Repository navigation
Publish releases through npm trusted publishing - #40
Merged
Merged
Conversation
The release for #39 built 0.13.0 but npm refused the publish with E404 on the PUT, its reply when a token can't publish the package. NPM_TOKEN was last set on 2026-06-10. Like policyengine-household-wizard (#4), publish with the workflow's OIDC identity instead of a stored token, on Node 24.21.0 with npm 11.19.0, and allow a manual run to retry a release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The review of #40 found that npm trusts the workflow from any branch and a manual run can pick one, so a manual run on a feature branch would publish it. Restrict the job to main. Add a concurrency group so two releases don't race, and rebase the release commit onto main before pushing it, so a version npm has always lands on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A run that waited behind another release would otherwise check out its own pushed commit and bump from the version before that release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The second review of #40 found that checking out main's tip could publish a later merge's code while npm's provenance names the triggering commit. Check out the triggering commit again, and release it only if it is still main's tip; otherwise start a fresh run on the tip, which carries its fragments. Move the concurrency group onto the job, so a skipped non-main run can't displace a queued main run, and say what the rebase before the push still can't cover. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
October 26, 2026 17:13
Contributor
Author
|
Merged at reviewed head 5fb12ee as 6e6630d.
|
This branch was successfully deployed
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.
Why
PolicyEngine/policyengine-ui-kit#39 merged as 7ad64d8, and its release run (40339204428) bumped the version to 0.13.0 and built the package, but
npm publishfailed:npm returns a 404 on a publish when the credentials can't publish the package. The repo's
NPM_TOKENsecret was last set on 2026-06-10, and npm still shows 0.12.1 as latest. Because the failure came before "Commit and push",mainis unchanged: the three changelog fragments from #39 are still there, and the next successful run will release them as 0.13.0.What
The same change PolicyEngine/policyengine-household-wizard#4 made, which has worked since its npm side was set up (its 0.2.0 went out on 2026-10-22 with a signed provenance statement):
id-token: write, so npm can accept the workflow's GitHub OIDC identity (npm trusted publishing). TheNODE_AUTH_TOKEN/NPM_TOKENuse is gone.workflow_dispatchlets someone retry a failed release without pushing a commit. On a manual runhead_commitis empty, so the job's skip-the-release-commit condition passes.main. npm trusts the workflow from any branch, and a manual run can pick one, so without this a manual run on a feature branch would publish it aslatest.releaseconcurrency group. The group is on the job, not the workflow, so a skipped non-mainrun never takes amainrun's place in the queue.main's tip when the run checks, before the build. npm records the run's commit as the package's source commit, so the published code must be that commit's. Ifmainhas moved on by then, the run releases nothing and starts a fresh run on the tip instead (gh workflow run, which needsactions: write). That covers a later merge and the release commit of a run this one waited for. The fresh run releases whatever fragments are still unreleased on the tip, and its provenance names the code it publishes. A merge that lands after the check doesn't change what this run publishes: it releases its own commit, and the merge's fragments go out in the next release.commit_and_push.shrebases the release commit ontomainbefore pushing it, so a merge that lands during a release doesn't stop the release commit from reachingmain. Two cases are left: a rebase conflict, or a merge landing between the pull and the push. Either stops the script with the version on npm but no release commit onmain. Later runs can then keep picking that same version and fail at publish, since npm refuses a version it already has, until someone writes the release commit by hand.Version bumping, changelog building, the build, the publish command and the release commit keep their order.
Needs Max: npm's side
This PR doesn't publish anything or touch npm. Before a release can succeed, someone with publish rights on
@policyengine/ui-kithas to add a trusted publisher on npmjs.com (package settings → Trusted publishing):PolicyEngine, repositorypolicyengine-ui-kit, workflowpush.yml, no environment;npm publishticked. This workflow publishes directly, and per npm's docs a configuration created after 2026-09-03 allows onlynpm stage publishuntil you tick it. household-wizard's release guide asks for the same.Then run the release by hand:
Until then, any run that reaches the publish step, including the one this PR's merge starts, will fail there the same way, leaving
mainunchanged. Once a release succeeds, theNPM_TOKENrepo secret can be deleted.Not in this PR, from the review: an
npm-publishenvironment limited tomain, named in npm's trusted-publisher form, would also stop a pushed branch with an edited workflow from publishing (true of the old token too); and splitting the build from the publish would keepid-token: writeaway frombun installand the build (household-wizard has the same single job).Verification
actionlint .github/workflows/push.ymlandshellcheck .github/commit_and_push.sh: clean.NPM_TOKENorNODE_AUTH_TOKENany more.🤖 Generated with Claude Code