Skip to content

ci(release): accept the release PR's CI when its push event is lost - #327

Merged
sunerpy merged 1 commit into
mainfrom
ci/release-ci-run-override
Oct 22, 2026
Merged

sunerpy merged 1 commit into
mainfrom
ci/release-ci-run-override

Conversation

@sunerpy

@sunerpy sunerpy commented Oct 21, 2026

Copy link
Copy Markdown
Owner

Summary

GitHub never delivered the push event for the v0.55.0 release commit 5f96a74 (merge of #325 at 2026-10-21T14:05:40Z). The commit has no workflow run and no check suite, and the repository activity log has no pr_merge entry for it. Every earlier merge has one. Release Please runs only on push, and verify-ci accepts only a CI push run on the exact release commit. That run can no longer appear, because ci.yml has no dispatch trigger, so the release is stuck before Release Please. This PR adds a guarded way out that keeps the exact-SHA gate in charge whenever it can decide.

  • workflow_dispatch input ci_run_id (optional). On a manual rebuild, verify-ci runs a new step, pr_ci, that accepts the named run only while the release commit has no CI push run. The run must:

    • be a completed pull_request run of .github/workflows/ci.yml in this repository, with CI Success passed in its latest attempt;
    • have as its head the head of the one merged PR into main whose merge commit is the release commit;
    • have a head that contains the release commit's single parent (so the PR run tested the head's own tree);
    • share the release commit's tree.

    verify-ci gains pull-requests: read for commits/<sha>/pulls, and the exact-SHA wait step is skipped only when this step accepted.

  • Publish-time check. When verify-ci took that path, publish-release checks again before the draft becomes public: a CI push run that has appeared since, from a replayed event for example, must pass first. It waits up to 7.5 minutes inside the job's timeout and otherwise fails, asking for a re-run. A run created in the few seconds between this check and gh release edit --draft=false cannot be stopped; the owner accepted that window.

  • Push path unchanged.

  • Structure gate. scripts/check-ci-gate.sh now applies the exact-SHA rule to the push-run wait step itself and pins its condition. The new pr_ci step also contains select(.name == "CI Success"), so the old whole-job string match would no longer have caught a weakened wait step. The gate also pins the dispatch-only condition of every step that reads ci_run_id, the new permission, the pr_ci_accepted output, and the publish-time check.

After merge

Each step needs the owner's go-ahead.

  1. This merge's push lets Release Please create tag v0.55.0 and the draft at 5f96a74. That run's verify-ci then fails as expected: there is no push CI for 5f96a74. The draft stays unpublished, and the run can be cancelled once the draft exists.
  2. Dispatch Release on main with tag_name=v0.55.0 and ci_run_id=39605156993. That is chore: release 0.55.0 #325's CI on head 67a9a9d, attempt 2, all green, on tree 029198bb…, the same tree as 5f96a74.

Testing

  • scripts/tests/release-ci-override.test.sh (new) extracts both steps from release.yml and runs them against a stub gh. 31 cases: 23 for pr_ci (accept, defer to an existing push run, and every rejection) and 8 for the publish-time check (no run, later pass, later fail, running then pass or fail, never completes, API failures). Disabling each of the 20 guards one at a time makes its matching case fail.
  • scripts/tests/ci-gate.test.sh: 16 cases. J is re-anchored on the wait step; L–P are new.
  • actionlint (with shellcheck of run: blocks), shellcheck, oxfmt, docs-check.py, guardrail.sh and every script test pass. The pre-push hook's make pre-ci passed on the pinned 1.98.0 toolchain: make check, the viewer gate (svelte-check, vitest 574/574, rebuilt bundle byte-identical) and the archive smoke (codegraph 0.55.0).

GitHub never delivered the push event for v0.55.0's release commit
5f96a74: the commit has no workflow run, and the repository activity log
has no merge entry for it. Release Please runs only on push, and verify-ci
accepts only a CI push run on the exact release commit, which can no
longer appear because ci.yml has no dispatch trigger. The release could
not finish.

A manual Release dispatch can now name the release PR's own CI run in a
new ci_run_id input. verify-ci uses it only while the release commit has
no CI push run, and only if the run is a completed pull_request run of
ci.yml in this repository whose CI Success passed, its head is the head of
the one merged pull request into main whose merge commit is the release
commit, that head contains the release commit's single parent, and both
commits share a tree. The new step needs pull-requests: read for
commits/<sha>/pulls.

When verify-ci took that path, publish-release checks again before it
makes the release public: a CI push run that has appeared since, from a
replayed event for example, must pass first. The push path is unchanged.

check-ci-gate.sh now applies the exact-SHA rule to the push-run wait step
itself and pins that step's condition, the dispatch-only condition of
every step that reads ci_run_id, the new permission, and the
publish-time check. release-ci-override.test.sh runs both new steps
against a stub gh.
@codecov

codecov Bot commented Oct 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Impacted file tree graph

@@           Coverage Diff           @@
##             main     #327   +/-   ##
=======================================
  Coverage   95.60%   95.60%           
=======================================
  Files         280      280           
  Lines      166327   166327           
=======================================
+ Hits       159013   159015    +2     
+ Misses       7314     7312    -2     

see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sunerpy
sunerpy merged commit b02b563 into main Oct 22, 2026
11 checks passed
@sunerpy
sunerpy deleted the ci/release-ci-run-override branch October 22, 2026 00:11
sunerpy added a commit that referenced this pull request Oct 22, 2026
…329)

Record the v0.55.0 release: #322 merged as 0796c8a, release PR #325 as
5f96a74, the push event GitHub never delivered for that merge, #327's
dispatch path, Release run 39698634632, and the black-box acceptance of
the downloaded binaries against v0.54.0, with the 24-cell benchmark and
the older upgrade issue in default daemon mode.

Close the v1.6.1 -> v1.6.2 sync: the tracked release moves to v1.6.2 with
the owner's exceptions (COBOL, G16 and G17, OD-19, and the W7-W9 rows
planned for the follow-up pull request). The audit's LANDED rows now name
#322, and docs-check.py expects the new tracked release.
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