Skip to content

ci(napi): gate the release PR on a real native build - #89

Merged
jamesyong-42 merged 1 commit into
mainfrom
ci/gate-release-pr-on-native-build
Jul 30, 2026
Merged

ci(napi): gate the release PR on a real native build#89
jamesyong-42 merged 1 commit into
mainfrom
ci/gate-release-pr-on-native-build

Conversation

@jamesyong-42

@jamesyong-42 jamesyong-42 commented Jul 30, 2026

Copy link
Copy Markdown
Member

Follow-up to #86. That fixed the bug that broke 0.5.22; this addresses why a broken release was unrecoverable and had to be rolled forward to 0.5.23.

Prevention — the part that matters

release-please cuts the tag the moment its PR merges, so today the first proof that the native build works arrives after the version is spent. This runs the 6-target matrix and its load checks on the release PR, while the version can still be not-released.

It would have caught this exact regression: #85 broke the loader at 17:09 on Jul 28, and release-please refreshed its PR branch at 17:10. A gate there fails on MODULE_NOT_FOUND, #80 never merges, and 0.5.22 is never cut.

Scoped per-job on github.head_ref, because branches: under pull_request filters the base branch, not the head. Every other PR already builds the addon natively on all three hosts through ci.yml's pnpm buildnapi build --platform --release; what this adds for a release PR is the cross-compiled targets and the require() checks. test and publish need no matching guard — they needs: the build job, and a skipped dependency skips its dependents.

No publish path opens up. publish stays gated on the publish input, which no pull_request event can set.

The cost is building twice per release — once as the gate, once for real after merge. Reusing the PR's artifacts would make the provenance attest a run that merely repacked binaries it never built, so the double build is the honest price.

Recovery — source_ref

A workflow_dispatch always reads its own definition from the ref it targets, and this workflow had no way to separate the two. So a workflow bug that reaches a tag cannot be fixed for that tag by any later commit on main — which is precisely why 0.5.22 could not be retried.

gh workflow run napi-build.yml --ref main -f publish=true -f source_ref=<tag> now runs main's workflow against the tag's source.

All three checkouts honour it. The publish job's matters most: it never builds, and takes the version straight from package.json, so a mismatch there would ship one ref's binaries under another ref's version number.

This recovers the native package only. release.yml's publish job — which ships the SDK and CLI — is on: push gated on release_created, and release-please will not re-create a released version; re-running the old run fails too, since its native-build watch waits on a run id that is already a completed failure. With no NPM_TOKEN (publishing is token-less OIDC), there is no manual path either. RELEASING.md now documents this, and that rolling forward stays the answer.

Verification

A CI-only change can't be tested locally, and this PR's own branch name deliberately won't match the guard — so I opened a throwaway PR from a release-please---prefixed branch (#88, closed) to exercise the new path for real:

  • NAPI Build triggered on the pull_request event
  • the head_ref guard admitted it — all 6/6 build jobs instantiated rather than skipping
  • all 6/6 checkouts resolved refs/pull/N/merge successfully, which is the genuinely new code path here (this workflow had never run on a PR event, and I changed every checkout to an explicit ref:)

Cancelled once those three were confirmed rather than burning 6 runners for 7 minutes — the compilation itself was proven by the 0.5.23 release run earlier today.

actionlint is clean on both changed workflows. The one SC2086 note it reports pre-exists on main (the deliberately-unquoted $TAG_ARG, which must word-split to nothing).

Not verified: that the gate blocks a genuinely broken build — that needs a real breakage, and the #85 timeline above is the argument instead.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

0.5.22 was cut, failed, and could not be repaired — the tag existed but
nothing reached npm. Two changes so that is less likely and less final.

Prevention: run the 6-target matrix and its load checks on release-please's
PR, before the merge that cuts the tag. #85 broke the loader at 17:09 and
release-please refreshed its PR branch at 17:10, so this gate would have
caught that exact regression with a CI run instead of a burned version.
Guarded per-job on github.head_ref (`branches:` filters the base, not the
head); every other PR already builds the addon natively on all three hosts
via ci.yml's `pnpm build`, so what this adds is the cross-compiled targets.
`publish` stays gated on the `publish` input, which no PR event can set.

Recovery: a `source_ref` input, because a workflow_dispatch always reads its
own definition from the ref it targets — so a workflow bug that reaches a tag
cannot be fixed for that tag from main. `--ref main -f source_ref=<tag>` runs
main's workflow against the tag's source. All three checkouts honour it; the
publish job's especially, since it never builds and takes the version from
package.json, so a mismatch would ship one ref's binaries under another's
version.

This only recovers the native package. RELEASING.md documents why the SDK and
CLI halves cannot be republished for an existing tag, and that rolling forward
remains the answer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jamesyong-42

Copy link
Copy Markdown
Member Author

Exclusion half of the guard confirmed on this PR itself: NAPI Build run 30567501007skipped in 1s (branch ci/gate-release-pr-on-native-build doesn't match the release-please-- prefix), against 6/6 jobs instantiating on the #88 smoke branch. Both directions of the guard are now exercised for real; only the block-a-broken-build case remains argued rather than demonstrated.

@jamesyong-42
jamesyong-42 merged commit 4fae56e into main Jul 30, 2026
11 of 24 checks passed
@jamesyong-42
jamesyong-42 deleted the ci/gate-release-pr-on-native-build branch July 30, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant