From 5c364e2cddc4aad51978d01bf7812a3abd1c3a6f Mon Sep 17 00:00:00 2001 From: Ivan Tsai <9553914+oscar60310@users.noreply.github.com> Date: Thu, 8 Sep 2022 16:19:54 +0800 Subject: [PATCH 1/6] build: rewrite version before publishing --- tools/scripts/publish.mjs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/tools/scripts/publish.mjs b/tools/scripts/publish.mjs index 55365f83..c95942ea 100644 --- a/tools/scripts/publish.mjs +++ b/tools/scripts/publish.mjs @@ -1,14 +1,23 @@ import { execSync } from 'child_process'; +import { getReleaseTag, getVersionByArguments } from './version.mjs'; +import path from 'path'; +import fs from 'fs'; + +// CWD: ./dist/packages/xxx +const packageJSONPath = path.resolve(process.cwd(), 'package.json'); if (process.env.READY_FOR_PUBLISH !== 'true') { console.log(`Set env READY_FOR_PUBLISH=true before running publish commands.`) process.exit(1); } -// Executing publish script: node path/to/publish.mjs {tag} -// Default "tag" to "alpha" so we won't publish the "latest" tag by accident. -let [, , tag] = process.argv; -if (!tag || tag === 'undefined') tag = 'alpha'; +const tag = getReleaseTag(); + +// Update the version property in package.json +const version = getVersionByArguments(); +const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, 'utf-8')); +packageJSON.version = version; +fs.writeFileSync(packageJSONPath, JSON.stringify(packageJSON, null, 2), 'utf-8'); // Execute "npm publish" to publish -execSync(`npm publish --tag ${tag}`); +execSync(`npm publish --tag ${tag}`); From 83c8663032824ae1fb43ee710f9486cf5931074b Mon Sep 17 00:00:00 2001 From: Ivan Tsai <9553914+oscar60310@users.noreply.github.com> Date: Thu, 8 Sep 2022 16:20:16 +0800 Subject: [PATCH 2/6] ci: add nightly build workflow --- .circleci/config.yml | 86 ++++++++++++++++++++++++++++++++++++--- packages/cli/Dockerfile | 3 +- tools/scripts/publish.mjs | 2 + 3 files changed, 85 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2e631ee3..8afb7eeb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,6 +8,11 @@ executors: # https://github.com/facebook/jest/issues/11956 - image: cimg/node:16.10.0 +parameters: + workflow_name: + type: string + default: 'none' + # Set some environment variables like the base SHA of PRs ...etc. set_env: &set_env name: Setup Environment Variables @@ -26,11 +31,21 @@ set_env: &set_env echo 'export AFFECTED_ARGS="--head=HEAD --base=${CIRCLE_PR_BASE_SHA}"' >> $BASH_ENV elif [ "$CIRCLE_BRANCH" == "develop" ]; then - # Merge into develop branch, use main branch as the base. - - echo "Using main branch as the base" - echo 'export AFFECTED_ARGS="--head=HEAD --base=origin/main"' >> $BASH_ENV - + # Use the last build commit if there is nightly-build tag + + last_commit="$(git rev-list -n 1 tags/nightly-build || echo '')" + + # Check whether the commit is on the target branch + if [ "$last_commit" != "" ] && [ "$(git merge-base $last_commit $CIRCLE_BRANCH)" == "$last_commit" ]; then + # use last build sha as the base. + echo "Using $last_commit as the base (last build)" + echo "export AFFECTED_ARGS=\"--head=HEAD --base=$last_commit\"" >> $BASH_ENV + else + # use main branch as the base. + echo "Using main branch as the base" + echo 'export AFFECTED_ARGS="--head=HEAD --base=origin/main"' >> $BASH_ENV + fi + else echo "Testing/Linting on all packages" @@ -136,9 +151,48 @@ jobs: echo "No coverage report found." fi + nightly-build: + executor: node-executor + steps: + - checkout + - run: + <<: *set_env + - restore_cache: + <<: *yarn_cache + # Setup remote docker to build image + # https://circleci.com/docs/building-docker-images + - setup_remote_docker + - run: + name: NPM publish + # running with yarn nx causes npm config issues + command: ./node_modules/.bin/nx affected --target=publish ${AFFECTED_ARGS} --tag dev + environment: + READY_FOR_PUBLISH: 'true' + - run: + name: Docker login + command: echo "${GITHUB_PAT}" | docker login ghcr.io -u ${GITHUB_USER} --password-stdin + - run: + name: Docker publish + command: yarn nx affected --target=publish:docker ${AFFECTED_ARGS} --tag dev + environment: + READY_FOR_PUBLISH: 'true' + # After a success build, move the tag nightly-build to HEAD + - run: + name: Move nightly-build tag + command: | + # delete remote tag + git push origin :refs/tags/nightly-build + # tag current HEAD + git tag -f nightly-build + # push tag + git push origin $CIRCLE_BRANCH --tags + workflows: version: 2 pr-check: + when: + not: + equal: [scheduled_pipeline, << pipeline.trigger_source >>] jobs: - install - lint: @@ -147,3 +201,25 @@ workflows: - test: requires: - install + nightly-build: + when: + or: + - and: + - equal: [scheduled_pipeline, << pipeline.trigger_source >>] + - equal: ['nightly build', << pipeline.schedule.name >>] + - and: + - equal: [api, << pipeline.trigger_source >>] + - equal: ['nightly build', << pipeline.parameters.workflow_name >>] + jobs: + - install + - lint: + requires: + - install + - test: + requires: + - install + - nightly-build: + requires: + - install + - lint + - test diff --git a/packages/cli/Dockerfile b/packages/cli/Dockerfile index 6874258d..9fbf35d2 100644 --- a/packages/cli/Dockerfile +++ b/packages/cli/Dockerfile @@ -2,7 +2,8 @@ FROM node:16-alpine # Annotation required by Github to link with our repository LABEL org.opencontainers.image.source https://github.com/canner/vulcan-sql -COPY ../../dist/packages/cli/ /usr/cli +# We'll execute docker build from project root. Using absolute path to avoid "forbidden path outside the build contex" error +COPY /dist/packages/cli/ /usr/cli WORKDIR /usr/cli ENV NODE_ENV=production RUN npm i diff --git a/tools/scripts/publish.mjs b/tools/scripts/publish.mjs index c95942ea..8eb3020c 100644 --- a/tools/scripts/publish.mjs +++ b/tools/scripts/publish.mjs @@ -19,5 +19,7 @@ const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, 'utf-8')); packageJSON.version = version; fs.writeFileSync(packageJSONPath, JSON.stringify(packageJSON, null, 2), 'utf-8'); +// Set npm credential +fs.writeFileSync('.npmrc', '//registry.npmjs.org/:_authToken=${NPM_TOKEN}', 'utf-8'); // Execute "npm publish" to publish execSync(`npm publish --tag ${tag}`); From e3dbe821f879db020189968b5eaac4cffbf8b33f Mon Sep 17 00:00:00 2001 From: Ivan Tsai <9553914+oscar60310@users.noreply.github.com> Date: Tue, 13 Sep 2022 10:20:54 +0800 Subject: [PATCH 3/6] build: bump to 0.2.0 for all package, fix version bumping scripts --- packages/build/package.json | 4 ++-- packages/cli/package.json | 2 +- packages/core/package.json | 2 +- packages/extension-dbt/package.json | 4 ++-- packages/extension-debug-tools/package.json | 23 +++++++++++++++++++-- packages/serve/package.json | 4 ++-- packages/test-utility/package.json | 5 +++-- tools/scripts/version.mjs | 8 +++---- 8 files changed, 36 insertions(+), 16 deletions(-) diff --git a/packages/build/package.json b/packages/build/package.json index c3943deb..cd91a9bb 100644 --- a/packages/build/package.json +++ b/packages/build/package.json @@ -1,7 +1,7 @@ { "name": "@vulcan-sql/build", "description": "VulcanSQL package for building projects", - "version": "0.1.0-alpha.1", + "version": "0.2.0", "type": "commonjs", "publishConfig": { "access": "public" @@ -22,6 +22,6 @@ }, "license": "MIT", "peerDependencies": { - "@vulcan-sql/core": "0.1.0-alpha.1" + "@vulcan-sql/core": "~0.2.0-0" } } diff --git a/packages/cli/package.json b/packages/cli/package.json index 09f82ece..f687600e 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@vulcan-sql/cli", "description": "CLI tools for VulcanSQL", - "version": "0.1.0-alpha.1", + "version": "0.2.0", "type": "commonjs", "bin": { "vulcan": "./src/index.js" diff --git a/packages/core/package.json b/packages/core/package.json index 61027470..0ea707f4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@vulcan-sql/core", "description": "Core package of VulcanSQL", - "version": "0.1.0-alpha.1", + "version": "0.2.0", "type": "commonjs", "publishConfig": { "access": "public" diff --git a/packages/extension-dbt/package.json b/packages/extension-dbt/package.json index 980c4a98..f5834447 100644 --- a/packages/extension-dbt/package.json +++ b/packages/extension-dbt/package.json @@ -1,7 +1,7 @@ { "name": "@vulcan-sql/extension-dbt", "description": "Using dbt models form VulcanSQL projects", - "version": "0.1.0-alpha.1", + "version": "0.2.0", "type": "commonjs", "publishConfig": { "access": "public" @@ -23,6 +23,6 @@ }, "license": "MIT", "peerDependencies": { - "@vulcan-sql/core": "0.x" + "@vulcan-sql/core": "~0.2.0-0" } } diff --git a/packages/extension-debug-tools/package.json b/packages/extension-debug-tools/package.json index f97377b0..3631964f 100644 --- a/packages/extension-debug-tools/package.json +++ b/packages/extension-debug-tools/package.json @@ -1,9 +1,28 @@ { "name": "@vulcan-sql/extension-debug-tools", - "version": "0.1.0-alpha.1", + "description": "A collection of Vulcan extension debug tools", + "version": "0.2.0", "type": "commonjs", + "publishConfig": { + "access": "public" + }, + "keywords": [ + "vulcan", + "vulcan-sql", + "data", + "sql", + "database", + "data-warehouse", + "data-lake", + "api-builder" + ], + "repository": { + "type": "git", + "url": "https://github.com/Canner/vulcan.git" + }, + "license": "MIT", "peerDependencies": { - "@vulcan-sql/core": "*" + "@vulcan-sql/core": "~0.2.0-0" }, "devDependencies": { "@vulcan-sql/test-utility": "0.1.0-alpha.1" diff --git a/packages/serve/package.json b/packages/serve/package.json index 39a8613b..7db5816a 100644 --- a/packages/serve/package.json +++ b/packages/serve/package.json @@ -1,7 +1,7 @@ { "name": "@vulcan-sql/serve", "description": "VulcanSQL package for serving projects", - "version": "0.1.0-alpha.1", + "version": "0.2.0", "type": "commonjs", "publishConfig": { "access": "public" @@ -22,6 +22,6 @@ }, "license": "MIT", "peerDependencies": { - "@vulcan-sql/core": "0.1.0-alpha.1" + "@vulcan-sql/core": "~0.2.0-0" } } diff --git a/packages/test-utility/package.json b/packages/test-utility/package.json index 93f985e1..4e6030c0 100644 --- a/packages/test-utility/package.json +++ b/packages/test-utility/package.json @@ -1,6 +1,7 @@ { "name": "@vulcan-sql/test-utility", - "version": "0.1.0-alpha.1", + "description": "Vulcan package for extension testing", + "version": "0.2.0", "type": "commonjs", "publishConfig": { "access": "public" @@ -22,6 +23,6 @@ }, "license": "MIT", "peerDependencies": { - "@vulcan-sql/core": "0.1.0-alpha.1" + "@vulcan-sql/core": "~0.2.0-0" } } diff --git a/tools/scripts/version.mjs b/tools/scripts/version.mjs index 55005062..866847f2 100644 --- a/tools/scripts/version.mjs +++ b/tools/scripts/version.mjs @@ -10,17 +10,17 @@ dayjs.extend(timezone); export function getNightlyVersion() { const packageJson = fs.readFileSync(path.resolve(process.cwd(), 'package.json'), 'utf-8'); - const { version } = JSON.parse(packageJson); + const { major, minor, patch } = semver.parse(JSON.parse(packageJson).version); // 0.1.0-dev.20220907.0 - return semver.inc(version, 'prerelease', `dev.${dayjs().tz('Asia/Taipei').format('YYYYMMDD')}`) + return `${major}.${minor}.${patch}-dev.${dayjs().tz('Asia/Taipei').format('YYYYMMDD')}.0` } export function getBetaVersion() { const packageJson = fs.readFileSync(path.resolve(process.cwd(), 'package.json'), 'utf-8'); - const { version } = JSON.parse(packageJson); + const { major, minor, patch } = semver.parse(JSON.parse(packageJson).version); // 0.1.0-beta.0 - return semver.inc(version, 'prerelease', `beta`) + return `${major}.${minor}.${patch}-beta.0` } export function getLatestVersion() { From c23d441258c678ce65cb34fd81540b496c333b68 Mon Sep 17 00:00:00 2001 From: Ivan Tsai <9553914+oscar60310@users.noreply.github.com> Date: Tue, 13 Sep 2022 11:38:04 +0800 Subject: [PATCH 4/6] fix(cli): specify version for cli testing --- packages/cli/src/cli.ts | 1 + packages/cli/src/commands/serve.ts | 4 +-- packages/cli/src/schemas/init/vulcan.yaml | 2 ++ packages/cli/test/cli.spec.ts | 34 ++++++++++++++++++----- packages/cli/test/init.spec.ts | 5 +++- 5 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/cli/src/cli.ts b/packages/cli/src/cli.ts index b449c2fb..83ac1631 100644 --- a/packages/cli/src/cli.ts +++ b/packages/cli/src/cli.ts @@ -17,6 +17,7 @@ program .argument('[path]', 'folder path to initialize Vulcan project') .description('create a new Vulcan project') .option('-p --project-name ', 'specify project name') + .option('-v --version ', 'specify Vulcan version') .action(async (path: string | undefined, options) => { await handleInit(path, options || {}); }); diff --git a/packages/cli/src/commands/serve.ts b/packages/cli/src/commands/serve.ts index b372b89b..3aad2481 100644 --- a/packages/cli/src/commands/serve.ts +++ b/packages/cli/src/commands/serve.ts @@ -23,8 +23,8 @@ export const serveVulcan = async (options: ServeCommandOptions) => { // Start server logger.info(`Starting server...`); const server = new VulcanServer(config); - await server.start(options.port); - logger.info(`Server is listening at port ${options.port}.`); + await server.start(); + logger.info(`Server is listening at port ${config.port || 3000}.`); addShutdownJob(async () => { logger.info(`Stopping server...`); await server.close(); diff --git a/packages/cli/src/schemas/init/vulcan.yaml b/packages/cli/src/schemas/init/vulcan.yaml index 4ed27194..f393ec28 100644 --- a/packages/cli/src/schemas/init/vulcan.yaml +++ b/packages/cli/src/schemas/init/vulcan.yaml @@ -21,3 +21,5 @@ document-generator: folderPath: . types: - RESTFUL +enforce-https: + enabled: false diff --git a/packages/cli/test/cli.spec.ts b/packages/cli/test/cli.spec.ts index 14e62edf..d6ab905d 100644 --- a/packages/cli/test/cli.spec.ts +++ b/packages/cli/test/cli.spec.ts @@ -4,16 +4,36 @@ import * as jsYAML from 'js-yaml'; import * as path from 'path'; import { runShutdownJobs } from '../src/utils'; import * as supertest from 'supertest'; +import faker from '@faker-js/faker'; const projectName = 'test-vulcan-project'; +const testingVersion = '0.1.2-dev.20220913.0'; +const testingServerPort = faker.datatype.number({ min: 20000, max: 30000 }); const workspaceRoot = path.resolve(__dirname, '..', '..', '..'); const projectRoot = path.resolve(workspaceRoot, projectName); beforeAll(async () => { await fs.rm(projectRoot, { recursive: true, force: true }); - await program.parseAsync(['node', 'vulcan', 'init', '-p', projectName]); + await program.parseAsync([ + 'node', + 'vulcan', + 'init', + '-p', + projectName, + '-v', + testingVersion, + ]); process.chdir(projectRoot); + const projectConfig = jsYAML.load( + await fs.readFile(path.resolve(projectRoot, 'vulcan.yaml'), 'utf-8') + ) as Record; + projectConfig['port'] = testingServerPort; + fs.writeFile( + path.resolve(projectRoot, 'vulcan.yaml'), + jsYAML.dump(projectConfig), + 'utf-8' + ); }, 30000); afterAll(async () => { @@ -45,9 +65,9 @@ it('Build command should make result.json', async () => { it('Serve command should start Vulcan server', async () => { // Action await program.parseAsync(['node', 'vulcan', 'build']); - await program.parseAsync(['node', 'vulcan', 'serve', '-p', '12345']); - const agent = supertest('http://localhost:12345'); - const result = await agent.get('/'); + await program.parseAsync(['node', 'vulcan', 'serve']); + const agent = supertest(`http://localhost:${testingServerPort}`); + const result = await agent.get('/doc'); // Assert expect(result.statusCode).toBe(200); await runShutdownJobs(); @@ -55,9 +75,9 @@ it('Serve command should start Vulcan server', async () => { it('Start command should build the project and start Vulcan server', async () => { // Action - await program.parseAsync(['node', 'vulcan', 'start', '-p', '12345']); - const agent = supertest('http://localhost:12345'); - const result = await agent.get('/'); + await program.parseAsync(['node', 'vulcan', 'start']); + const agent = supertest(`http://localhost:${testingServerPort}`); + const result = await agent.get('/doc'); // Assert expect(result.statusCode).toBe(200); await runShutdownJobs(); diff --git a/packages/cli/test/init.spec.ts b/packages/cli/test/init.spec.ts index ed368408..c46f51bd 100644 --- a/packages/cli/test/init.spec.ts +++ b/packages/cli/test/init.spec.ts @@ -4,7 +4,8 @@ import * as jsYAML from 'js-yaml'; import * as path from 'path'; import { runShutdownJobs } from '../src/utils'; -const projectName = 'test-vulcan-project'; +const projectName = 'test-vulcan-project-init'; +const testingVersion = '0.1.2-dev.20220913.0'; const workspaceRoot = path.resolve(__dirname, '..', '..', '..'); const projectRoot = path.resolve(workspaceRoot, `${projectName}-with-path`); @@ -29,6 +30,8 @@ it('Init command with folder path should create default config in target folder' 'init', '-p', projectName, + '-v', + testingVersion, projectRoot, ]); // Action From 7df2d4591d5cb9ae3481f4ad7cd96726c66e6ca5 Mon Sep 17 00:00:00 2001 From: Ivan Tsai <9553914+oscar60310@users.noreply.github.com> Date: Tue, 13 Sep 2022 14:18:04 +0800 Subject: [PATCH 5/6] ci: set deployment key with write access for deploy jobs --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8afb7eeb..37be84d1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -154,6 +154,10 @@ jobs: nightly-build: executor: node-executor steps: + # Using the deployment key with write access + - add_ssh_keys: + fingerprints: + - 'd8:c0:e1:c8:8b:8d:dd:f8:50:cd:d9:34:1c:21:3d:85' - checkout - run: <<: *set_env From 00600eb147d3547419ebe86e14dedae52cd9e2b8 Mon Sep 17 00:00:00 2001 From: Ivan Tsai <9553914+oscar60310@users.noreply.github.com> Date: Tue, 13 Sep 2022 17:58:57 +0800 Subject: [PATCH 6/6] feat: receive args.version from nx --- packages/build/project.json | 2 +- packages/cli/project.json | 2 +- packages/core/project.json | 2 +- packages/extension-dbt/project.json | 2 +- packages/extension-debug-tools/project.json | 2 +- packages/serve/project.json | 2 +- packages/test-utility/project.json | 2 +- tools/scripts/publish.mjs | 1 + 8 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/build/project.json b/packages/build/project.json index dbc39b24..ed28adf9 100644 --- a/packages/build/project.json +++ b/packages/build/project.json @@ -49,7 +49,7 @@ "publish": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "node ../../../tools/scripts/publish.mjs {args.tag}", + "command": "node ../../../tools/scripts/publish.mjs {args.tag} {args.version}", "cwd": "dist/packages/build" }, "dependsOn": [ diff --git a/packages/cli/project.json b/packages/cli/project.json index 9ab15658..18191954 100644 --- a/packages/cli/project.json +++ b/packages/cli/project.json @@ -43,7 +43,7 @@ "publish": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "node ../../../tools/scripts/publish.mjs {args.tag}", + "command": "node ../../../tools/scripts/publish.mjs {args.tag} {args.version}", "cwd": "dist/packages/cli" }, "dependsOn": [ diff --git a/packages/core/project.json b/packages/core/project.json index e2f1ce38..b644f2ac 100644 --- a/packages/core/project.json +++ b/packages/core/project.json @@ -43,7 +43,7 @@ "publish": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "node ../../../tools/scripts/publish.mjs {args.tag}", + "command": "node ../../../tools/scripts/publish.mjs {args.tag} {args.version}", "cwd": "dist/packages/core" }, "dependsOn": [ diff --git a/packages/extension-dbt/project.json b/packages/extension-dbt/project.json index a00b540f..e8652b4e 100644 --- a/packages/extension-dbt/project.json +++ b/packages/extension-dbt/project.json @@ -49,7 +49,7 @@ "publish": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "node ../../../tools/scripts/publish.mjs {args.tag}", + "command": "node ../../../tools/scripts/publish.mjs {args.tag} {args.version}", "cwd": "dist/packages/extension-dbt" }, "dependsOn": [ diff --git a/packages/extension-debug-tools/project.json b/packages/extension-debug-tools/project.json index eb3f4b20..4b4a8db7 100644 --- a/packages/extension-debug-tools/project.json +++ b/packages/extension-debug-tools/project.json @@ -34,7 +34,7 @@ "publish": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "node ../../../tools/scripts/publish.mjs {args.tag}", + "command": "node ../../../tools/scripts/publish.mjs {args.tag} {args.version}", "cwd": "dist/packages/extension-debug-tools" }, "dependsOn": [ diff --git a/packages/serve/project.json b/packages/serve/project.json index 532dcaa9..0948bd27 100644 --- a/packages/serve/project.json +++ b/packages/serve/project.json @@ -59,7 +59,7 @@ "publish": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "node ../../../tools/scripts/publish.mjs {args.tag}", + "command": "node ../../../tools/scripts/publish.mjs {args.tag} {args.version}", "cwd": "dist/packages/serve" }, "dependsOn": [ diff --git a/packages/test-utility/project.json b/packages/test-utility/project.json index e572b8bf..6956bcc7 100644 --- a/packages/test-utility/project.json +++ b/packages/test-utility/project.json @@ -49,7 +49,7 @@ "publish": { "executor": "@nrwl/workspace:run-commands", "options": { - "command": "node ../../../tools/scripts/publish.mjs {args.tag}", + "command": "node ../../../tools/scripts/publish.mjs {args.tag} {args.version}", "cwd": "dist/packages/test-utility" }, "dependsOn": [ diff --git a/tools/scripts/publish.mjs b/tools/scripts/publish.mjs index 8eb3020c..a2d25b30 100644 --- a/tools/scripts/publish.mjs +++ b/tools/scripts/publish.mjs @@ -3,6 +3,7 @@ import { getReleaseTag, getVersionByArguments } from './version.mjs'; import path from 'path'; import fs from 'fs'; +// node publish.mjs // CWD: ./dist/packages/xxx const packageJSONPath = path.resolve(process.cwd(), 'package.json');