Repository navigation
Publish releases with npm trusted publishing - #48
Merged
Merged
Conversation
A new workflow publishes the package to npm when a version tag like 1.2.3 is pushed. npm trusts the workflow through OIDC, so no npm token is stored and no 2FA prompt is needed. The workflow runs the lint and the tests first, and stops if the tag does not match package.json or is not on the default branch. Run by hand, it only checks the trusted publisher setup with npm publish --dry-run and an OIDC token exchange. The trusted publisher on npmjs.com must point to this repository, the workflow file release.yml and the environment npm-publish. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Findings of the Codex Astra review of the release workflow: - Install, lint and tests run in a verify job without the id-token permission. Only the publish job and the check job may request an OIDC token. - The publish job checks the tag and its branch before any repository code runs, and installs with --ignore-scripts. - The manual check runs only on the default branch and executes no repository scripts. It no longer runs npm publish --dry-run, which fails for a version that already exists. - Each tag has its own concurrency group, so a pending release is not replaced by another run. - The README says that the trusted publisher must allow npm publish and expires after 2 days without a publish. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
.github/workflows/release.yml: a version tag such as1.2.3publishes the package to npm with npm trusted publishing (OIDC). No npm token is stored and no 2FA prompt is needed.How it works
verify(no OIDC permission): install, lint, tests,npm pack --dry-run, and for tags a check that the tag matchespackage.jsonand is on the default branch.publish(tags only, environmentnpm-publish,id-token: write): checks the tag again before any repository code runs, installs with--ignore-scripts, then runsnpm publish. Provenance is automatic.check-trusted-publisher(manual run on the default branch only): asks npm for a publish token the same waynpm publishdoes and reports the result. It publishes nothing and runs no repository scripts.npm setup (once per package, right before a release)
On npmjs.com, add a trusted publisher: this repository, workflow
release.yml, environmentnpm-publish, and under "Allowed actions" selectnpm publish. A new trusted publisher expires if it does not publish within 2 days.Review
A Codex review (gpt-6-astra) found four problems: OIDC access during repository scripts, a manual check that failed for existing versions, the missing
npm publishpermission in the setup notes, and the concurrency of pending releases. The second commit fixes them. The re-review found no new problems. actionlint passes.npm ci --ignore-scriptsplusnpm packproduces the same tarball as the published version.🤖 Generated with Claude Code