ci: publish to npm via OIDC trusted publishing - #161
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe release workflow now uses npm trusted publishing with OIDC, including Node 24 and npm upgrade steps, and package.json adds repository metadata. ChangesRelease Workflow and Package Metadata
Estimated code review effort: 2 (Simple) | ~10 minutes Sequence Diagram(s)sequenceDiagram
participant GitHub Actions
participant Node Setup
participant npm Registry
GitHub Actions->>Node Setup: actions/setup-node@v5 (Node 24)
Node Setup->>GitHub Actions: npm install -g npm@latest
GitHub Actions->>npm Registry: npm publish --provenance --access public
npm Registry-->>GitHub Actions: publish result
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
.github/workflows/release.yaml (1)
35-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valuePin npm to a tested npm release
npm install -g npm@latestmakes the release toolchain non-reproducible. Pin a known-good version instead (for examplenpm@11.5.1or newer) so trusted publishing keeps behaving consistently.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/workflows/release.yaml around lines 35 - 36, The release workflow currently installs npm using a floating latest tag, which makes the toolchain non-reproducible. Update the “Update npm” step in the release workflow to pin npm to a known-good tested version instead of npm@latest, keeping the existing npm --version check so the workflow still verifies the installed release.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release.yaml:
- Around line 60-62: The Release to NPM step in the release workflow will
publish on manual dispatch whenever dry_run is false, which can push a real
package version unexpectedly. Tighten the guard on the workflow job/step that
runs npm publish in the release.yaml workflow (the Release to NPM block), or add
explicit documentation and checks that the package.json version already exists
on npm before allowing workflow_dispatch to publish. Ensure the condition
clearly distinguishes OIDC-only runs from real release publishes.
---
Nitpick comments:
In @.github/workflows/release.yaml:
- Around line 35-36: The release workflow currently installs npm using a
floating latest tag, which makes the toolchain non-reproducible. Update the
“Update npm” step in the release workflow to pin npm to a known-good tested
version instead of npm@latest, keeping the existing npm --version check so the
workflow still verifies the installed release.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: c79d2c8a-4a7e-40fc-ba2a-f147d39706cc
📒 Files selected for processing (2)
.github/workflows/release.yamlpackage.json
| - name: Release to NPM | ||
| run: bun publish --access public | ||
| env: | ||
| NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
| if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && !inputs.dry_run) | ||
| run: npm publish --provenance --access public |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
sed -n '1,180p' .github/workflows/release.yamlRepository: ThallesP/nestjs-better-auth
Length of output: 2032
🏁 Script executed:
cat -n package.json | sed -n '1,80p'Repository: ThallesP/nestjs-better-auth
Length of output: 2920
🏁 Script executed:
rg -n "OIDC|dry_run|dry run|trusted publishing|publish --dry-run|without releasing|without releasing a new version" .Repository: ThallesP/nestjs-better-auth
Length of output: 165
Manual dispatch with dry_run: false still publishes to npm
If this path is only meant to exercise OIDC, gate it more tightly or document that package.json’s version must already exist on npm; otherwise a non-dry-run dispatch will publish that version for real.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release.yaml around lines 60 - 62, The Release to NPM step
in the release workflow will publish on manual dispatch whenever dry_run is
false, which can push a real package version unexpectedly. Tighten the guard on
the workflow job/step that runs npm publish in the release.yaml workflow (the
Release to NPM block), or add explicit documentation and checks that the
package.json version already exists on npm before allowing workflow_dispatch to
publish. Ensure the condition clearly distinguishes OIDC-only runs from real
release publishes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Migrates the release workflow from an
NPM_TOKENsecret to npm trusted publishing (OIDC).Why the previous attempts failed
The git history from January (
02787dc…3c22150) hit three known traps, each of which independently breaks OIDC publishing:bun publishdoesn't support trusted publishing — the OIDC token exchange is implemented in the npm CLI only (oven-sh/bun#22423, #24855). Bun still handles install/build/lint/test; only the publish step uses npm.setup-nodewithregistry-urlbreaks OIDC — it writes an.npmrcwith_authToken=${NODE_AUTH_TOKEN}, and the mere presence of that auth config makes npm skip OIDC and fail with a misleadingENEEDAUTH/E404(npm/cli#9088). That explains the wholeNODE_AUTH_TOKENunset/empty-string dance in the old commits — the fix is to not setregistry-urlat all and have no token env var anywhere.repository.urlcase mismatch — the old attempt usedgithub.com/thallesp/…but the OIDC token's repository claim isThallesP/nestjs-better-auth, and provenance validation compares them case-sensitively. This PR adds therepositoryfield with the exact casing (it was removed entirely in the revert).Also required: npm ≥ 11.5.1, so the workflow updates npm rather than trusting the runner's bundled version, and
id-token: writepermission.On npmjs.com → package @thallesp/nestjs-better-auth → Settings → Trusted Publisher, add a GitHub Actions publisher with these exact, case-sensitive values:
ThallesPnestjs-better-authrelease.yaml(with the.yamlextension, not.yml)After the first successful OIDC publish, the
NPM_TOKENrepo secret can be deleted, and optionally set the package to "Require two-factor authentication or automation" → disallow tokens.🤖 Generated with Claude Code
Summary by CodeRabbit
npm publishusing provenance and public access (replacing the previous Bun-based publish approach).