Skip to content

ci: set up npm trusted publishing - #213

Merged
styfle merged 1 commit into
mainfrom
set-up-npm-trusted-publishing
Aug 7, 2026
Merged

ci: set up npm trusted publishing#213
styfle merged 1 commit into
mainfrom
set-up-npm-trusted-publishing

Conversation

@styfle

@styfle styfle commented Aug 7, 2026

Copy link
Copy Markdown
Member

Publishes @vercel/webpack-asset-relocator-loader to npm via trusted publishing (GitHub Actions OIDC) instead of the long-lived NPM_TOKEN_ELEVATED secret.

⚠️ Required manual step before merging

npm does not let you register a trusted publisher from CI — it has to be done in the npmjs.com UI, and until it exists the OIDC token exchange fails and @semantic-release/npm falls back to token auth (which this PR removes). So the next release after merge will fail unless this is done first.

On the package settings page, under Trusted Publisher, add a GitHub Actions publisher:

Field Value
Organization or user vercel
Repository webpack-asset-relocator-loader
Workflow filename ci.yml
Environment name (leave blank)
Allowed actions npm publish

These fields are case-sensitive and npm doesn't validate them at save time — mistakes only surface as ENEEDAUTH at publish time. Note the workflow filename is the file that runs the publish, which is ci.yml here, not a path.

Once a release has published successfully, the NPM_TOKEN_ELEVATED secret can be deleted and Publishing access can be tightened to Require two-factor authentication and disallow tokens (that setting only affects token auth, so OIDC keeps working).

Changes

package.json

  • Added publishConfig.access = "public" so the scoped package keeps publishing publicly.
  • Bumped semantic-release ^17.3.0^25.0.9. OIDC token exchange landed in @semantic-release/npm v13.1.0, which is only pulled in by semantic-release v25. v13 also bundles npm 11.x, satisfying the npm >= 11.5.1 requirement regardless of the runner's npm.

No change was needed to repository — npm normalizes the vercel/webpack-asset-relocator-loader shorthand to git+https://github.com/vercel/webpack-asset-relocator-loader.git, which is what the registry already has on record for v1.10.0 and what the OIDC repository check compares against.

.github/workflows/ci.yml

  • Split the release out of the test matrix into its own release job gated on needs: test and push-to-main. This keeps id-token: write scoped to the publish step rather than granting it to every matrix leg on every PR.
  • Added an explicit permissions block: contents: read at the workflow level, and on the release job contents: write (GitHub release + tag), issues: write / pull-requests: write (release comments), id-token: write (OIDC).
  • Removed NPM_TOKEN. @semantic-release/npm now calls getIDToken("npm:registry.npmjs.org") and exchanges it for a short-lived registry token; verify-auth.js returns early on success and never reads NPM_TOKEN.
  • Added fetch-depth: 0 to the release checkout, per the semantic-release GitHub Actions recipe.
  • Bumped the test matrix from Node 18 to Node 22. This one is forced rather than chosen: semantic-release v25 declares engines.node: ^22.14.0 || >= 24.10.0, and yarn v1 hard-errors (Found incompatible module) on an engine mismatch rather than warning — so leaving the matrix on Node 18 breaks yarn install on every leg. npm trusted publishing itself also requires Node >= 22.14.0. Node 18 went EOL in April 2025. If you'd rather keep Node 18 test coverage, the alternative is yarn install --ignore-engines in the test job — happy to switch.

Provenance attestations are generated automatically for public packages published from a public repo over OIDC, so no --provenance flag or publishConfig.provenance is needed.

Verification

  • yarn test — 85/85 passing on Node 22.
  • Confirmed the installed tree is semantic-release@25.0.9 / @semantic-release/npm@13.1.5 with npm 11.19.0 hoisted, and that the plugin's trusted-publishing/token-exchange.js reads the Actions OIDC token that id-token: write provides.
  • Workflow YAML parsed and asserted: two jobs, correct permissions, no remaining NPM_TOKEN reference.

The end-to-end publish can't be exercised from a PR — OIDC only works on push to main — so the first real validation is the next release.

🤖 Generated with Claude Code

Publish to npm via GitHub Actions OIDC instead of a long-lived
NPM_TOKEN secret.

- Bump semantic-release 17 -> 25, which pulls in @semantic-release/npm
  v13. OIDC token exchange landed in @semantic-release/npm v13.1.0, and
  v13 bundles npm 11.x (trusted publishing needs npm >= 11.5.1).
- Move the release out of the test matrix into its own job so that
  `id-token: write` is scoped to the publish step only, and grant the
  permissions semantic-release needs now that the workflow declares an
  explicit permissions block.
- Drop the NPM_TOKEN env var. With trusted publishing configured,
  @semantic-release/npm exchanges the Actions OIDC token for a
  short-lived registry token and never reads NPM_TOKEN.
- Add publishConfig.access=public so the scoped package keeps publishing
  publicly, and bump CI to Node 22 because semantic-release v25 requires
  ^22.14.0 || >=24.10.0 (yarn v1 hard-fails on engine mismatch).

Provenance attestations are generated automatically for public packages
published from a public repo via OIDC, so no --provenance flag is needed.

Co-Authored-By: Steven <229881+styfle@users.noreply.github.com>
@styfle
styfle requested a review from Timer as a code owner August 7, 2026 01:59
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​mapbox/​node-pre-gyp@​2.0.39910010090100
Updatednpm/​semantic-release@​17.3.0 ⏵ 25.0.997 +1100 +210097 +8100

View full report

@styfle
styfle merged commit 66e19e2 into main Aug 7, 2026
8 checks passed
@styfle
styfle deleted the set-up-npm-trusted-publishing branch August 7, 2026 02:06
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.10.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant