From 537ca43457bd62f0686b40ff03b5403237dc3a40 Mon Sep 17 00:00:00 2001 From: Ulises Gascon Date: Fri, 11 Sep 2026 17:15:05 +0200 Subject: [PATCH 1/3] ci: add npm staged publication with dist-tag support Port: https://github.com/expressjs/body-parser/blob/aa9889bc35ede269cbb8cc271e485cde0847776c/.github/workflows/npm-publish.yml --- .github/workflows/npm-publish.yml | 78 +++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/npm-publish.yml diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 00000000000..b3b30e638b4 --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,78 @@ +name: Publish package to npm + +on: + release: + # "created" does not fire when a draft release is published, "published" does + types: [published] + +concurrency: + group: "${{ github.workflow }} ✨ ${{ github.ref }}" + cancel-in-progress: false + +permissions: + contents: read + +jobs: + publish: + name: Publish to npm + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup Node.js + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: "lts/*" + registry-url: "https://registry.npmjs.org" + + # npm stage publish requires npm >= 11.15.0 + - name: Upgrade npm + run: npm install -g npm@latest + + # Derive the npm dist-tag from the package version rather than from the + # release target branch, which is just whatever the "Target" dropdown held + # when the release was created and has been wrong in the past. Publishing + # a maintenance line must never overwrite "latest": + # prerelease (e.g. 3.0.0-beta.1) -> next + # major >= current npm "latest" major -> latest + # major < current npm "latest" major -> latest-.x + # No data from the release event is used, so nothing untrusted reaches + # the script. + - name: Resolve npm dist-tag from package version + id: dist-tag + run: | + node <<'EOF' + const fs = require('fs') + const { execFileSync } = require('child_process') + + const SEMVER = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/ + const { name, version } = JSON.parse(fs.readFileSync('package.json', 'utf8')) + const parsed = SEMVER.exec(version) + if (!parsed) throw new Error(`Invalid version in package.json: ${version}`) + + const latest = execFileSync('npm', ['view', name, 'version'], { encoding: 'utf8' }).trim() + const latestParsed = SEMVER.exec(latest) + if (!latestParsed) throw new Error(`Unexpected "latest" version on npm: ${latest}`) + + const major = Number(parsed[1]) + const prerelease = parsed[4] + const latestMajor = Number(latestParsed[1]) + + let tag + if (prerelease) tag = 'next' + else if (major >= latestMajor) tag = 'latest' + else tag = `latest-${major}.x` + + console.log(`${name}@${version} (npm latest: ${latest}) -> dist-tag "${tag}"`) + fs.appendFileSync(process.env.GITHUB_OUTPUT, `tag=${tag}\n`) + EOF + + - name: Stage publish to npm + env: + NPM_DIST_TAG: ${{ steps.dist-tag.outputs.tag }} + run: npm stage publish --tag "$NPM_DIST_TAG" \ No newline at end of file From 0a23565e6689faff26db1bb1e22791eba06b4933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Fri, 11 Sep 2026 19:32:28 +0200 Subject: [PATCH 2/3] Apply suggestion from @krzysdz Co-authored-by: krzysdz <12915102+krzysdz@users.noreply.github.com> --- .github/workflows/npm-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index b3b30e638b4..b0b158be8ca 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -66,7 +66,7 @@ jobs: let tag if (prerelease) tag = 'next' else if (major >= latestMajor) tag = 'latest' - else tag = `latest-${major}.x` + else tag = `latest-${major}` console.log(`${name}@${version} (npm latest: ${latest}) -> dist-tag "${tag}"`) fs.appendFileSync(process.env.GITHUB_OUTPUT, `tag=${tag}\n`) From b889d9de261b6685205c64bb2fc6f64f721231c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulises=20Gasc=C3=B3n?= Date: Fri, 11 Sep 2026 19:32:38 +0200 Subject: [PATCH 3/3] Apply suggestion from @krzysdz Co-authored-by: krzysdz <12915102+krzysdz@users.noreply.github.com> --- .github/workflows/npm-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index b0b158be8ca..f0408ac94fb 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -40,7 +40,7 @@ jobs: # a maintenance line must never overwrite "latest": # prerelease (e.g. 3.0.0-beta.1) -> next # major >= current npm "latest" major -> latest - # major < current npm "latest" major -> latest-.x + # major < current npm "latest" major -> latest- # No data from the release event is used, so nothing untrusted reaches # the script. - name: Resolve npm dist-tag from package version