The "refuse releases not on the default branch" check used a depth-1
checkout plus a depth-1 `git fetch`, so the tag commit and the default
branch tip shared no history locally — `git merge-base --is-ancestor`
could only pass when the tag was exactly the branch tip, failing closed
on any legitimate release once the branch advanced. Use `fetch-depth: 0`
and drop the re-shallowing manual fetch; this also removes the
public-repo-only dependency on an anonymous `git fetch` (works on
private repos too, since checkout fetches before stripping credentials).
Add a top-level `concurrency:` group so overlapping releases serialize
instead of racing for a dist-tag in the staging queue;
`cancel-in-progress: false` to queue rather than kill an in-flight
`npm stage publish`.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Why?
passport-intercomis published to npm by hand today, which depends on along-lived npm token. This moves publishing onto short-lived, per-run OIDC
credentials and adds a human approval step before any release goes live —
removing the need for a stored npm token entirely.
How?
Adds a release-triggered GitHub Actions workflow that:
NPM_TOKENsecret.npm stage publish), so every release isqueued and a maintainer must approve it with 2FA before it goes live.
nextdist-tag and stable versions tolatest.package.json(tolerant of a leadingv)and refuses releases not reachable from the default branch.
.nvmrc(needed for the npm CLI version thatsupports staged publishing).
Before the first release can publish, a stage-only Trusted Publisher for this
package must be registered on npm (configured against this repo + workflow).
Generated with Claude Code