diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ff44473..53988726 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,12 @@ jobs: - name: Build run: npm run build + + - name: Install s + run: npm install -g @serverless-devs/s + + - name: s config + run: s config add --AccessKeyID 123 --AccessKeySecret 123 --AccountID 123 --SecurityToken 123 -a default - name: export env if: matrix.os != 'windows-latest' diff --git a/.github/workflows/publish-pkg.yml b/.github/workflows/publish-pkg.yml index f20bd963..8a642085 100644 --- a/.github/workflows/publish-pkg.yml +++ b/.github/workflows/publish-pkg.yml @@ -60,5 +60,6 @@ jobs: npm run pub else echo "No changes in ${{ matrix.package }}/package.json" + fi env: NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} diff --git a/packages/credential/package.json b/packages/credential/package.json index 7d903257..3c4370fb 100644 --- a/packages/credential/package.json +++ b/packages/credential/package.json @@ -1,6 +1,6 @@ { "name": "@serverless-devs/credential", - "version": "0.0.4", + "version": "0.0.5", "description": "credential for serverless-devs", "main": "lib/index.js", "scripts": { diff --git a/packages/credential/src/utils/index.ts b/packages/credential/src/utils/index.ts index 79ce839c..8f72ab1c 100644 --- a/packages/credential/src/utils/index.ts +++ b/packages/credential/src/utils/index.ts @@ -77,6 +77,7 @@ export async function writeData(content: Record>) fs.writeFileSync(getYamlPath(), yaml.dump(content)); } catch (ex: any) { Logger.logger.debug(`write data error: ${ex.message}`); - throw new Error('Configuration failed'); + if (ex.message.includes('EACCES')) throw new Error(`Configuration failed. Please check the permission.`);; + throw new Error('Configuration failed.'); } } diff --git a/packages/engine/__tests__/environment.test.ts b/packages/engine/__tests__/environment.test.ts index b6a30813..3dd207d8 100644 --- a/packages/engine/__tests__/environment.test.ts +++ b/packages/engine/__tests__/environment.test.ts @@ -85,7 +85,7 @@ describe('not specify --env', () => { }); test('env name was not found', async () => { fs.ensureFileSync(ENVIRONMENT_FILE_PATH); - fs.writeJSONSync(ENVIRONMENT_FILE_PATH, [{ 'project': 'demo', 'default': 'testing11' }], { spaces: 2 }) + fs.writeJSONSync(ENVIRONMENT_FILE_PATH, [{ 'project': 'web-framework-app', 'default': 'testing11' }], { spaces: 2 }) const template = 's.yaml' const engine = new Engine({ template, @@ -98,7 +98,7 @@ describe('not specify --env', () => { }); test('basic', async () => { fs.ensureFileSync(ENVIRONMENT_FILE_PATH); - fs.writeJSONSync(ENVIRONMENT_FILE_PATH, [{ 'project': 'demo', 'default': 'testing' }], { spaces: 2 }) + fs.writeJSONSync(ENVIRONMENT_FILE_PATH, [{ 'project': 'web-framework-app', 'default': 'testing' }], { spaces: 2 }) const template = 's.yaml' const engine = new Engine({ template, diff --git a/packages/engine/__tests__/mock/environment/env.yaml b/packages/engine/__tests__/mock/environment/env.yaml index 60b61d72..daefd00c 100644 --- a/packages/engine/__tests__/mock/environment/env.yaml +++ b/packages/engine/__tests__/mock/environment/env.yaml @@ -1,4 +1,3 @@ -project: demo # required,string类型。环境属于一个project,一个env.yaml描述project所有环境 environments: # required,数组类型。定义所有环境 - name: testing # required,string类型。环境名 access: default # required,string类型。声明环境使用的云账号 diff --git a/packages/engine/package.json b/packages/engine/package.json index 255030af..6edcf5b2 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@serverless-devs/engine", - "version": "0.1.0-beta.2", + "version": "0.1.0", "description": "a engine lib for serverless-devs", "main": "lib/index.js", "scripts": { diff --git a/packages/load-application/package.json b/packages/load-application/package.json index 2d0fc15a..7ca894bd 100644 --- a/packages/load-application/package.json +++ b/packages/load-application/package.json @@ -1,6 +1,6 @@ { "name": "@serverless-devs/load-application", - "version": "0.0.12-beta.1", + "version": "0.0.12", "description": "load application for serverless-devs", "main": "lib/index.js", "scripts": { @@ -18,7 +18,7 @@ }, "dependencies": { "@serverless-cd/debug": "^4.3.4", - "@serverless-devs/art-template": "^4.13.7", + "@serverless-devs/art-template": "^4.13.15", "@serverless-devs/credential": "workspace:^", "@serverless-devs/downloads": "workspace:^", "@serverless-devs/utils": "workspace:^", diff --git a/packages/load-component/package.json b/packages/load-component/package.json index ab8ad09b..ab00b5a7 100644 --- a/packages/load-component/package.json +++ b/packages/load-component/package.json @@ -1,6 +1,6 @@ { "name": "@serverless-devs/load-component", - "version": "0.0.6", + "version": "0.0.7-beta.1", "description": "request for serverless-devs", "main": "lib/index.js", "scripts": { diff --git a/packages/load-component/src/index.ts b/packages/load-component/src/index.ts index 5c94d07b..cef33dbe 100644 --- a/packages/load-component/src/index.ts +++ b/packages/load-component/src/index.ts @@ -20,6 +20,10 @@ export class Component { } async update() { const [componentName, componentVersion] = getProvider(this.name); + if(componentVersion === 'CUSTOM') { + this.params.logger(`Skip outside component's update. You could use 's clean --component ' before deploy to update your custom component cache manually.`); + return; + } debug(`componentName: ${componentName}, componentVersion: ${componentVersion}`); const componentCachePath = getComponentCachePath(componentName, componentVersion); debug(`componentCachePath: ${componentCachePath}`); @@ -42,18 +46,18 @@ export class Component { private async getDevComponent() { const [componentName, componentVersion] = getProvider(this.name); debug(`componentName: ${componentName}, componentVersion: ${componentVersion}`); - const componentCachePath = getComponentCachePath(componentName, componentVersion); + const componentCachePath = getComponentCachePath(componentName, componentVersion === 'CUSTOM' ? '' : componentVersion); debug(`componentCachePath: ${componentCachePath}`); const lockPath = getLockFile(componentCachePath); if (fs.existsSync(lockPath)) { return await buildComponentInstance(componentCachePath, this.params); } - const { zipballUrl, version } = await getZipballUrl(componentName, componentVersion); + const { zipballUrl = componentName, version = componentVersion } = await getZipballUrl(componentName, componentVersion); debug(`zipballUrl: ${zipballUrl}`); await download(zipballUrl, { logger: get(this.params, 'engineLogger', get(this.params, 'logger')), dest: componentCachePath, - filename: `${componentName}${componentVersion ? `@${componentVersion}` : ''}`, + filename: componentVersion === 'CUSTOM' ? componentName.split('/').pop()?.split('.')[0] : `${componentName}${componentVersion ? `@${componentVersion}` : ''}`, extract: true, headers: registry.getSignHeaders(), }); diff --git a/packages/load-component/src/utils/index.ts b/packages/load-component/src/utils/index.ts index a8f78b79..342cf188 100644 --- a/packages/load-component/src/utils/index.ts +++ b/packages/load-component/src/utils/index.ts @@ -63,6 +63,9 @@ export const buildComponentInstance = async (componentPath: string, params?: any }; export function getProvider(name: string) { + if (isValidUrl(name)) { + return [name, 'CUSTOM']; + } assert(!includes(name, '/'), `The component name ${name} cannot contain /`); const [componentName, componentVersion] = split(name, '@'); const { core_load_serverless_devs_component } = process.env; @@ -84,6 +87,9 @@ export function getProvider(name: string) { } export const getZipballUrl = async (componentName: string, componentVersion?: string) => { + if(componentVersion === 'CUSTOM') { + return {}; + } const url = componentVersion ? getUrlWithVersion(componentName, componentVersion) : getUrlWithLatest(componentName); debug(`url: ${url}`); try { @@ -102,5 +108,15 @@ export const getZipballUrl = async (componentName: string, componentVersion?: st }; export const getComponentCachePath = (componentName: string, componentVersion?: string) => { + componentName = isValidUrl(componentName) ? componentName.split('/').pop()?.split('.')[0] || '' : componentName; return path.join(getRootHome(), 'components', 'devsapp.cn', 'v3', componentVersion ? `${componentName}@${componentVersion}` : componentName); }; + +export function isValidUrl(s: string) { + try { + new URL(s); + return true; + } catch (err) { + return false; + } +} diff --git a/packages/parse-spec/package.json b/packages/parse-spec/package.json index 5b53de9e..c4909243 100644 --- a/packages/parse-spec/package.json +++ b/packages/parse-spec/package.json @@ -1,6 +1,6 @@ { "name": "@serverless-devs/parse-spec", - "version": "0.0.23", + "version": "0.0.24", "description": "a parse yaml spec lib for serverless-devs", "main": "lib/index.js", "scripts": { @@ -22,7 +22,7 @@ }, "dependencies": { "@serverless-cd/debug": "^4.3.4", - "@serverless-devs/art-template": "^4.13.14", + "@serverless-devs/art-template": "^4.13.15", "@serverless-devs/credential": "workspace:^", "@serverless-devs/utils": "workspace:^", "chalk": "^4.1.2", diff --git a/packages/parse-spec/src/index.ts b/packages/parse-spec/src/index.ts index 52b41581..02e3aaab 100644 --- a/packages/parse-spec/src/index.ts +++ b/packages/parse-spec/src/index.ts @@ -217,6 +217,13 @@ class ParseSpec { this.parseArgv(); if (!this.yaml.use3x) return this.v1(); const { steps, content, originSteps } = await new ParseContent(this.yaml.content, this.getParsedContentOptions(this.yaml.path)).start(); + const services = get(this.yaml.content, 'services', {}); + if (isEmpty(steps) && !isEmpty(services)) { + this.options.logger.tips('Check https://docs.serverless-devs.com/serverless-devs/yaml for more details. Use the \'s cli fc3 s2tos3\' command for automatic YAML transformation.'); + throw new DevsError(`Keyword 'services' has been replaced by 'resources' in 3.0.0 YAML.`, { + trackerType: ETrackerType.parseException, + }); + } // steps 存放每个FC组件/函数的 yaml 配置 ([content.resource] => steps) // content 为 yaml 已解析的整体完整信息 // originSteps 为 steps 的未解析版 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0bcec330..1880b7e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -193,8 +193,8 @@ importers: specifier: ^4.3.4 version: 4.3.4 '@serverless-devs/art-template': - specifier: ^4.13.7 - version: 4.13.7 + specifier: ^4.13.15 + version: 4.13.15 '@serverless-devs/credential': specifier: workspace:^ version: link:../credential @@ -310,8 +310,8 @@ importers: specifier: ^4.3.4 version: 4.3.4 '@serverless-devs/art-template': - specifier: ^4.13.14 - version: 4.13.14 + specifier: ^4.13.15 + version: 4.13.15 '@serverless-devs/credential': specifier: workspace:^ version: link:../credential @@ -1116,8 +1116,8 @@ packages: - supports-color dev: false - /@serverless-devs/art-template@4.13.14: - resolution: {integrity: sha512-eVn9YaWgWMBBp2wiRrXzpJepflH/LSTSbAKgHaqd3klRSccnrFs81TGQBCS9kac9xx3gRubeH4vw3olNDX+Qxw==} + /@serverless-devs/art-template@4.13.15: + resolution: {integrity: sha512-vgu6L7wzEc8Ju39kPkNAS77UK7aU9q412Hvh8mfVpJ/j7X46jKRe8DR+7NCmJ8rYGwKbhNb0UwmsRfpdmBHS6w==} engines: {node: '>= 1.0.0'} dependencies: '@serverless-devs/utils': 0.0.14 @@ -1128,26 +1128,12 @@ packages: html-minifier: 3.5.21 is-keyword-js: 1.0.3 js-tokens: 3.0.2 + js-yaml: 4.1.0 lodash: 4.17.21 merge-source-map: 1.1.0 source-map: 0.5.7 dev: false - /@serverless-devs/art-template@4.13.7: - resolution: {integrity: sha512-Qvhwi9240m3JLUFPqQgilSWF51gBSIO8anyyDb8I5h1mnNMnYZ7xk8i4y0f9NZ2AuNDT6yaG4/TeMrnWYGr2Vw==} - engines: {node: '>= 1.0.0'} - dependencies: - acorn: 5.7.4 - escodegen: 1.14.3 - estraverse: 4.3.0 - html-minifier: 3.5.21 - is-keyword-js: 1.0.3 - js-tokens: 3.0.2 - lodash.get: 4.4.2 - merge-source-map: 1.1.0 - source-map: 0.5.7 - dev: false - /@serverless-devs/credentials@2.2.6: resolution: {integrity: sha512-LanVxoMtAGpl9K38vhc4Eeb/vXQI2XQX67CWmQIfdKI1l0FWMlInUUtMe01SpzbR2bxiX0v/Tze4vGDyrYgMEQ==} dependencies: @@ -3219,10 +3205,6 @@ packages: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} dev: false - /lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - dev: false - /lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} dev: false