ci(publish): migrate to OIDC trusted publishing#162
Conversation
WalkthroughThe publish workflow gains an early authentication checkpoint. Before attempting package publication, a new step verifies that the NPM_TOKEN secret can authenticate to npm by running ChangesNPM Authentication Verification
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Replaces the long-lived NPM_TOKEN secret with GitHub OIDC + npm trusted
publishing rules (configured on npmjs.com for @openhop/server,
@openhop/web, openhop). Each run now mints a short-lived OIDC token
from GitHub and npm exchanges it with the registry — nothing to rotate,
nothing to expire, and the registry verifies the publish came from this
exact repo + workflow.
This unblocks the 0.3.3 publish failure (cryptic
`404 Not Found - PUT @openhop%2fserver` — npm's mask for a
permissionless scoped publish) and removes the auth-rot failure mode
permanently.
Changes:
- Upgrade npm to >=11.5.1 before `npm ci`. Node 22 LTS bundles
npm 10.x, which predates OIDC publishing in the CLI.
- Add an OIDC-readiness preflight that fails fast if either
`permissions: id-token: write` got dropped from the workflow
(ACTIONS_ID_TOKEN_REQUEST_URL would be unset) or npm somehow isn't
new enough. Surfaces the real cause instead of an opaque registry
rejection halfway through publish.
- Drop `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}` from all three
publish steps. npm auto-detects the GitHub OIDC context.
- Add --provenance to each publish so the resulting tarballs carry
a signed build attestation — the "verified" badge on npmjs.com and
a SLSA-style supply-chain signal that pairs naturally with trusted
publishing.
After this lands the NPM_TOKEN repo secret is dead weight and can be
deleted from Settings → Secrets and variables → Actions.
78269ee to
851bf60
Compare
|
@coderabbitai full review Force-pushed: squashed the original |
🧩 Analysis chain🏁 Script executed: Length of output: 18267
🔴 Bug: version check only validates
|
CodeRabbit caught three issues in the OIDC migration:
1. The npm version preflight only compared the major (`>= 11`),
so npm 11.0.0 - 11.5.0 would have passed despite lacking OIDC
publishing support. Replace with a semver-correct
`sort -V -C` gate that succeeds iff $npm_version >= 11.5.1.
Verified across 10.9.0 / 11.0.0 / 11.5.0 / 11.5.1 / 11.5.2 /
11.6.0 / 12.0.0.
2. `npm install -g npm@latest` is non-deterministic — a future
buggy major could break publishes silently. Pin the floor +
cap the major: `npm@^11.5.1` (>=11.5.1 <12.0.0).
3. `--provenance` is redundant on trusted-publishing runs with
npm >= 11.5.1 (provenance is auto-attached). Drop the flag
and update the inline comment to spell out why no flag is
needed.
No behavioural change on the happy path beyond removing the redundant
`--provenance` argument; the publish outputs still carry signed
provenance attestations via trusted publishing's automatic flow.
|
Thanks @coderabbitai — addressed in 95f5e7b:
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 16060
The workflow is clean — no long-lived token, correct OIDC permissions, a semver floor that actually enforces 11.5.1, a deterministic (。◕‿◕。)🐇 [approve] |
Why
The
0.3.3publish (run 25984620955) failed because the long-livedNPM_TOKENrepo secret no longer has publish rights on the@openhopscope. npm masks scoped-package permission failures as404 Not Found - PUT https://registry.npmjs.org/@openhop%2fserver, which is what surfaced.npm now caps publish tokens at 90 days, so even with a fresh rotation we'd be back here every quarter. Trusted Publishing fixes this class of failure permanently: no stored token, each run mints a short-lived OIDC token from GitHub, npm verifies it against per-package "Trusted Publisher" rules.
What this PR does
^11.5.1(Node 22 LTS ships 10.x, which predates OIDC publishing in the CLI; pin is bounded so a future major can't break us silently).permissions: id-token: writegot dropped from the workflow or npm somehow isn't new enough. Uses asort -V -Csemver-correct gate (≥ 11.5.1, not just major ≥ 11).NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}from all three publish steps. npm auto-detects the GitHub OIDC context.--provenanceflag is needed.Out-of-band setup (already done)
For each of
@openhop/server,@openhop/web,openhopon npmjs.com → Settings → Trusted Publisher → GitHub Actions:naorsabagopenhoppublish.ymlTest plan
Verify OIDC trusted publishing is wired upprintsOIDC ready, npm <version>, and the three publishes go through with provenance attestations visible on each package's npmjs.com page.NPM_TOKENsecret from repo Settings → Secrets and variables → Actions.🤖 Generated with Claude Code