From 7a5bb00e095a9a481a68c41bf131fee0807b7554 Mon Sep 17 00:00:00 2001 From: Tauan BF <11513929+tauanbinato@users.noreply.github.com> Date: Mon, 28 Sep 2026 20:42:54 -0300 Subject: [PATCH] Stage the npm launcher for approval instead of publishing it npm's trusted publisher settings advise against letting a workflow run npm publish: allowed only npm stage publish, a release's version waits on npmjs.com until the maintainer approves it with their second factor, so the release job, or anyone who takes over its token, cannot put a version live alone. Staging needs npm 11.15.0 or later, so the job installs npm 11.20.0 rather than take the one Node brings, checks it, and runs npm stage publish with provenance. A notice in the run says the version is waiting for approval. A rerun still skips a version npm has published; one staged and not yet approved stops it, as npm refuses to stage a version twice. --- .github/workflows/release.yml | 22 ++++++++++++++-------- CHANGELOG.md | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fcf7bb4..f1a9c91 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,8 +4,8 @@ name: Release # the tag's message body becomes the notes of a GitHub release that carries the # binaries, their checksums and build provenance; then the Homebrew formula in # Tech-Byte-Frontier/homebrew-tap installs it, and the npm launcher -# @tech-byte-frontier/jevgate of the same version runs it. Every step can be -# rerun safely. +# @tech-byte-frontier/jevgate of the same version is staged on npm, where it +# goes live once the maintainer approves it. Every step can be rerun safely. on: push: tags: ["v*"] @@ -132,7 +132,8 @@ jobs: needs: publish runs-on: ubuntu-latest # npm trusts only this workflow in this environment (trusted publishing), and - # adds the package's provenance itself. + # only to stage a version: it goes live when the maintainer approves it on + # npmjs.com with their second factor, so this job alone cannot publish. environment: npm permissions: contents: read @@ -144,17 +145,20 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - # Trusted publishing needs npm 11.5.1 or later, which Node 24 releases - # bring. No package cache: nothing restored runs next to the publish token. + # No package cache: nothing restored runs next to the publish token. - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 registry-url: https://registry.npmjs.org package-manager-cache: false - - name: Publish the npm launcher + # Staged publishing needs npm 11.15.0 or later: install a known one rather + # than take the one Node brings. + - name: Install npm + run: npm install --global npm@11.20.0 + - name: Stage the npm launcher run: | npm_version=$(npm --version) - [ "$(printf '%s\n' 11.5.1 "$npm_version" | sort -V | head -n 1)" = 11.5.1 ] || { echo "::error::npm $npm_version is older than 11.5.1, which trusted publishing needs"; exit 1; } + [ "$(printf '%s\n' 11.15.0 "$npm_version" | sort -V | head -n 1)" = 11.15.0 ] || { echo "::error::npm $npm_version is older than 11.15.0, which staged publishing needs"; exit 1; } name=$(jq -r .name npm/package.json) version=$(jq -r .version npm/package.json) [ "$TAG" = "v$version" ] || { echo "::error::Tag $TAG does not match npm/package.json version $version"; exit 1; } @@ -163,5 +167,7 @@ jobs: exit 0 fi # The package ships the release's checksums, which tie it to these binaries. + # A version already staged and not yet approved stops a rerun here. gh release download "$TAG" --pattern SHA256SUMS --dir npm - npm publish ./npm --access public + npm stage publish ./npm --access public --provenance + echo "::notice::$name $version is staged: approve it on npmjs.com (the package's Staged Packages) to publish it" diff --git a/CHANGELOG.md b/CHANGELOG.md index af20d1c..18aab0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ Notable changes to JevGate. Versions follow [Semantic Versioning](https://semver ## [Unreleased] -- Releases publish the npm package, `@tech-byte-frontier/jevgate`, from the release workflow through npm's trusted publishing: no token, and npm shows the package's provenance. 0.30.0's was published by hand. +- Releases stage the npm package, `@tech-byte-frontier/jevgate`, from the release workflow through npm's trusted publishing, with no token and with provenance; each version goes live when the maintainer approves it on npmjs.com. 0.30.0's was published by hand. ## [0.30.0] - 2026-09-28