Repository navigation
release-merge: check_suite re-evaluation never fires, so an approval given before CI is green leaves the release PR stuck forever #318
Description
What's happening
workflow-release-merge.yml (#303/#305) is documented to work even when the maintainer approves the release PR before CI finishes: the approval fires pull_request_review: submitted, and if any check is still pending it exits cleanly and waits for a check_suite: completed event to re-evaluate. In practice, once approval genuinely precedes CI going green, that re-evaluation never happens — the PR sits approved and fully green with nothing left to merge it.
Evidence (CLDMV/slothlet PR #437)
- Approved at
2026-09-21T03:38:29Z.merge / 🚦 Release Mergeran immediately (pull_request_review, run35558209246), completed successfully at03:38:41, but did not merge —PR Coverage Badge(needscito finish first, in this repo's currently-released@v4) was still running. PR Coverage Badgefinished at03:57:04;✅ Required PR Checkwent green at03:57:16. The PR has been fully green and approved since then.- No further run of
release-merge.ymloccurred after03:38. Querying its workflow-run history forcheck_suite-triggered runs turns up none for this PR at all — every historicalcheck_suite-triggered run of this workflow reportshead_branch: master, nevernext, going back well before the approval. - The PR only unstuck after a fresh
pull_request_reviewwas submitted, which re-ran the evaluation from scratch and merged immediately (everything was already green).
This is likely the first real exercise of the check_suite re-fire path: every slothlet release before #437 merged because the approval came after CI was already green, so the initial pull_request_review evaluation succeeded on the spot and the re-evaluation path was never actually needed.
Root cause (unconfirmed — needs a repro with logging)
workflow-release-merge.yml's caller (release-merge.yml) listens on check_suite: types: [completed] with no further filtering, and action.mjs's resolveReleasePr() correctly handles a check_suite event by resolving head_branch (github.event.check_suite.head_branch) to the open release PR. The logic looks right — the gap appears to be upstream of the job even running: GitHub does not appear to be delivering a check_suite: completed event to this workflow for the release PR's own head branch (next/hotfixes) at all. Possible causes to check:
- The check suite for the release PR's head SHA may be getting merged/attributed differently than assumed (e.g. multiple check suites per SHA across different workflow-triggering events, and the "last" one completing doesn't fire the webhook the way expected).
- A repository or org-level check-suite
auto_trigger_checkspreference for the Actions app. check_suitewebhooks are known to have caveats when a SHA is associated with more than one ref — worth checking whether the release PR's head SHA is being treated as ambiguous.
Suggested fix
Whatever the exact platform cause, the fix needs to not depend on check_suite alone:
- Add a fallback poll. A
schedule(e.g. every 5–10 minutes) or a repeated re-arm from theciworkflow itself (e.g. haveci.yml's own completion, on the release PR's head, dispatchworkflow_dispatchonrelease-merge.yml) so an approval-before-green PR is guaranteed to converge even ifcheck_suitedoesn't fire. - Alternatively/additionally, have the CI workflow chain (
workflow-ci.ymlor the reusable it composes) explicitly call the release-merge workflow viaworkflow_call/workflow_dispatchas its last step when it detects it's running on a release PR head with a standing approval, rather than relying on GitHub's own check-suite webhook timing. - At minimum, document the gap and the manual recovery (
workflow_dispatchonrelease-merge.yml, or re-submitting any review) so a stuck PR isn't mysterious.
Impact
Affects every repo that has opted into release-merge.yml (slothlet at least; .github is being wired up now — see #316) whenever a maintainer approves a release PR before its CI (in particular the coverage leg, which can run long) finishes. The PR silently sits fully green and approved with nothing to merge it — easy to mistake for "just needs one more click" rather than a stuck automation.
Activity
fix(ci): replace the schedule poll with workflow_run — the actual fix…
Shinrai commentedon Sep 28, 2026
Fix shipped in v4.29.0 via #319 (a61d9e8): the re-evaluation trigger is now
workflow_run: completedon the caller's own CI workflow instead ofcheck_suite, which GitHub never delivers for Actions-created suites.workflow-release-merge.ymlreadsworkflow_run.head_branchfirst, and bothlocal-release-merge.ymland therelease-flow-v4/release-merge.ymltemplate carry the new trigger.Leaving this open at
status: implemented. Theworkflow_runruns do fire (slothlet has 100+ of them since), but every release PR since then — slothlet #440, #444, #457, #467 — was approved after CI was already green and merged straight from thepull_request_reviewrun. The approve-before-green path this issue is about hasn't run live yet. The next release approved while CI is still running will confirm it; close then.Note for adopters: the trigger lives in each repo's own
release-merge.yml, so a consumer only gets it by re-syncing that file from the template.@v4alone doesn't bring it.Shinrai commentedon Sep 28, 2026
The first live approve-before-green case, #322 (v4.29.1), got stuck, so the
workflow_runfix in #319 was incomplete.waiting on 1 unfinished check(s): 🔍 Analyze javascript-typescriptand exited.workflow_run.workflows(only🧪 Local CIis), so nothing re-fired.workflow_runrun replaced it in the concurrency group's pending slot. That part is harmless: every run re-reads the approval and the checks from the API.Follow-up fix on
fix/release-merge-rearm-all-checks(5fdce27): list every workflow that puts a check on a release-PR head, in bothlocal-release-merge.ymland the caller template. Also addbranches: [next, hotfixes]so feature-branch CI no longer triggers it.Every repo that adopted the template carries the same one-entry list and needs to re-sync its
release-merge.yml: slothlet, slothlet-vine, vitest-runner, jsonv, jsonv-eslint-plugin-jsonv, kasa-api, rti-videowall-server, tv-control, unifi-cli.cldmv-bot commentedon Sep 28, 2026
Closed in v4.29.2 — resolved by #323.
ci: re-arm release-merge on every check-producing workflow
Shinrai commentedon Sep 28, 2026
Re-synced every adopter's
release-merge.ymlfrom the v4.29.2 template, keeping each repo's own header. All nine had the template body unchanged, and the new list covers every workflow that puts a check on their release PRs.next: slothlet#490, slothlet-vine#45, vitest-runner#49, jsonv#61, jsonv-eslint-plugin-jsonv#40dev(dev-trunk repos): io-kasa-apie960d1e, rti-videowall-server51e390c, tv-control6d0d730, unifi-cli64752b5. These take effect oncedevis promoted tomaster.Each change takes effect in that repo once it reaches
master. That repo's first release PR after that is the live test.