From aab59ce6332de562fb39486df8b31134b2b60842 Mon Sep 17 00:00:00 2001 From: Sasha <118575614+weboko@users.noreply.github.com> Date: Wed, 29 Mar 2023 10:36:37 +0200 Subject: [PATCH] chore: introduce custom publish script and move to a new secret for publishing (#1279) --- .github/workflows/ci.yml | 8 ++-- ci/publish.js | 101 +++++++++++++++++++++++++++++++++++++++ package.json | 3 +- 3 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 ci/publish.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc101b11b2..5d465477bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -231,9 +231,7 @@ jobs: - run: npm run build if: ${{ steps.release.outputs.releases_created }} - - name: Authenticate with registry - if: ${{ steps.release.outputs.releases_created }} - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ./.npmrc - - - run: npm publish --workspaces --tag latest --access public + - run: npm run publish if: ${{ steps.release.outputs.releases_created }} + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_JS_WAKU_PUBLISH }} diff --git a/ci/publish.js b/ci/publish.js new file mode 100644 index 0000000000..ea15790085 --- /dev/null +++ b/ci/publish.js @@ -0,0 +1,101 @@ +import fs from "fs"; +import path from "path"; +import cp from "child_process"; +import { promisify } from "util"; +import { fileURLToPath } from "url"; + +const PACKAGE_JSON = "package.json"; +// hack to get __dirname +const DIR = path.dirname(fileURLToPath(import.meta.url)); + +const exec = promisify(cp.exec); +const readFile = promisify(fs.readFile); + +run() + .then(() => { + console.info("Successfully published packages."); + }) + .catch((err) => { + console.error("Failed at publishing packages with ", err.message); + }); + +async function run() { + const rootPackage = await readJSON(path.resolve(DIR, "../", PACKAGE_JSON)); + const workspacePaths = rootPackage.workspaces; + + const workspaces = await Promise.all( + workspacePaths.map(async (workspacePath) => { + const workspaceInfo = await readWorkspace(workspacePath); + const allowPublishing = await shouldBePublished(workspaceInfo); + + if (allowPublishing) { + return workspaceInfo; + } + + return; + }) + ); + + await Promise.all( + workspaces + .filter((v) => !!v) + .map(async (info) => { + try { + await exec( + `npm publish --workspace ${info.workspace} --tag latest --access public` + ); + console.info( + `Successfully published ${info.name} with version ${info.version}.` + ); + } catch (err) { + console.error( + `Cannot publish ${info.workspace} with version ${info.version}. Error: ${err.message}` + ); + } + }) + ); +} + +async function readJSON(path) { + const rawJSON = await readFile(path, "utf-8"); + return JSON.parse(rawJSON); +} + +async function readWorkspace(packagePath) { + const json = await readJSON( + path.resolve(DIR, "../", packagePath, PACKAGE_JSON) + ); + + return { + name: json.name, + private: !!json.private, + version: json.version, + workspace: packagePath, + }; +} + +async function shouldBePublished(info) { + if (info.private) { + console.info(`Skipping ${info.path} because it is private.`); + return false; + } + + try { + const npmTag = `${info.name}@${info.version}`; + const { stdout } = await exec(`npm view ${npmTag} version`); + + if (stdout.trim() !== info.version.trim()) { + return true; + } + + console.info(`Workspace ${info.path} is already published.`); + } catch (err) { + if (err.message.includes("code E404")) { + return true; + } + + console.error( + `Cannot check published version of ${info.path}. Received error: ${err.message}` + ); + } +} diff --git a/package.json b/package.json index c896b9c5f5..26b5c95396 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "deploy": "node ci/deploy.js", "doc": "run-s doc:*", "doc:html": "typedoc --options typedoc.cjs", - "doc:cname": "echo 'js.waku.org' > docs/CNAME" + "doc:cname": "echo 'js.waku.org' > docs/CNAME", + "publish": "node ./ci/publish.js" }, "devDependencies": { "@size-limit/preset-big-lib": "^8.2.4",