fix(release): nightly gate must pin the entry-point workflow, not event_name - #1358
Merged
Conversation
…nt_name c41db8e ("scope manifest signing identities") added a trigger-shape rule to the "Resolve immutable release policy" job that no run can ever satisfy: if [[ "${GITHUB_EVENT_NAME}" != "workflow_call" ]]; then echo "::error::nightly releases require workflow_call" Under workflow_call the `github` context — and therefore GITHUB_EVENT_NAME — belongs to the CALLER, so a nightly reports `schedule` (cron) or `workflow_dispatch` (forced re-cut), never the literal "workflow_call". This repo already established that caller/callee context split empirically in 8cba6dd (#832), where github.workflow_ref was found to be the entry-point workflow (nightly.yml) rather than the signing workflow. The gate has therefore failed closed on every nightly that actually reached the release job since the hardening landed: run 30077877380 (2026-07-24) and run 30254411300 (2026-07-27). The 07-25 and 07-26 runs were green only because the change gate skipped the release job entirely (main HEAD was already nightly-tagged), and the 07-23 run predates the hardening. The caller is correct and is left untouched — nightly.yml does invoke release.yml via `uses:` from refs/heads/main. The gate is what regressed, so the gate is restored to a satisfiable form that is strictly narrower than the original intent: GITHUB_WORKFLOW_REF (the entry-point ref) must equal the canonical nightly.yml at refs/heads/main. That names the repository, the entry-point workflow, and the branch, where "was a reusable call" named none of them. It fails closed when the variable is unset. The event-shape assertion is kept in satisfiable form (schedule or workflow_dispatch, the two triggers nightly.yml declares), and the refs/heads/main check plus the refs/heads/main signer identity are unchanged. The stable/preview branch is untouched. Adds a static contract test that fails against the pre-fix workflow. Not provable offline: only a real nightly run can confirm GITHUB_WORKFLOW_REF is populated as expected on the runner. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CI's ruff reformats this file; the lane's local ruff did not (lockfile skew — the repo venv is unreadable so the lane fell back to system ruff). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
thinmintdev
enabled auto-merge (squash)
July 27, 2026 14:54
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.
Nightly releases have been failing since 2026-07-24 (run 30077877380, again 30254411300) with:
Root cause
c41db8e5("scope manifest signing identities") added a trigger-shape rule to the Resolve immutable release policy job that no run can satisfy:Under
workflow_callthegithubcontext belongs to the caller, soGITHUB_EVENT_NAMEisschedule(cron) orworkflow_dispatch(forced re-cut) — never the literalworkflow_call. This repo already established that caller/callee split empirically in8cba6dd5(#832).The caller (
nightly.yml) was correct all along and is untouched.Note the 07-25 and 07-26 runs were not genuinely green: both ~13s with the release job skipped, because main HEAD was already nightly-tagged.
Fix
The gate regressed, so the gate is restored — in a form strictly narrower than the original intent.
GITHUB_WORKFLOW_REFmust match the canonicalnightly.yml@refs/heads/main, which names the repository, entry-point workflow, and branch, where "was a reusable call" named none of them. Fails closed when unset. The event-shape assertion is kept in satisfiable form. Stable/preview path untouched.Verification
tests/release/ tests/updater/ tests/installer/→ 367 passed, 1 skipped (skip: shellcheck absent)release.yml, green afterNot provable offline
That the runner populates
GITHUB_WORKFLOW_REFas<owner>/<repo>/.github/workflows/nightly.yml@refs/heads/maininside a called reusable workflow. Evidence is indirect but strong (#832). Fails closed if wrong. Validate after merge withgh workflow run nightly.yml --ref main -f force=true.Nothing downstream of this gate has executed since 2026-07-23, so a later-stage failure could still be hiding behind it.
🤖 Generated with Claude Code