Repository navigation
Audit that every merge on main went through the merge queue - #694
Merged
Merged
Conversation
#650 (6438cb2) and #680 (6b9820b) landed as build commits whose Merge gate run had failed, so "only the queue merges" has been a convention that nothing checks. audit-merges.mjs walks the last commits on main and prints `bypassed queue: #<pr> <sha> (merge_group: failure|absent)` when the landed commit carries no successful gate run of its own, `direct commit: <sha>` for a push that came from no pull request, and exits 1 when it found one. Read-only. The gate run is matched by workflow, not by "some merge_group run succeeded": on #680 the Test run of the very entry the gate refused is green, so the looser test would call that bypass a queue merge. Fixes #689 Docs-not-needed: adds a read-only .github/scripts check and its cases; no subsystem doc owns .github/.
Collaborator
Author
|
Verdict: PASS at 2372531 This does what #689 asked, and it does it on evidence rather than on a guess: the gate run is identified by workflow, not by "some Ran:
Not run:
Non-blocking:
T3: awaiting a maintainer approve at this tip; I am not enqueueing it. |
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.
Written-by: Dev
Adds
.github/scripts/audit-merges.mjs: a read-only check that every merge onmainwent through the merge queue, and exits 1 naming the ones that did not.Fixes #689
Tip SHA: 2372531
Reproduce
#650and#680are build commits whoseMerge gaterun had failed, andmainwas pushed to them anyway — the runs API, live:Nothing in the repository tells the two shapes apart: the only
merge_grouprecord of the landed commit is refused, and no check looks at what landed.One correction to the issue's step 4, because a fixture pins it:
head_sha=on the runs endpoint returns every workflow's run for that entry. On#680theTestrun of the same entry issuccess(39730969253), so "at least one run withconclusion === 'success'" would call that bypass a queue merge. The check therefore matches theMerge gateworkflow (path === .github/workflows/merge-gate.yml), and a greenTestrun proves nothing about the gate.What changed
.github/scripts/audit-merges.mjs(new, ~200 lines, no new dependency), its cases and four fixtures:auditCommit({sha, pulls, runs})— one commit in, one finding ornullout. No pull request →direct commit: <sha>. A successfulMerge gaterun whosehead_shais this commit → queue merge. Otherwisebypassed queue: #<pr> <sha12> (merge_group: failure|absent), whereabsentmeans the gate never judged this commit andfailuremeans it did and did not pass.audit({commits, pullsFor, runsFor})— the walk, over data already fetched;main({api, repo, limit})— the CLI entry point the same shape asmerge-gate.mjs(GH_REPO,GH_TOKEN,--limit, default 50), printing the lines and exiting 1 when there is a finding./commits?sha=main,/commits/{sha}/pulls,/actions/runs?event=merge_group&head_sha={sha}.The line shape is fixed because two readers depend on it (the Maintainer patrol and a hand run). A direct push is reported on its own line and is not counted as a bypass.
What I ran
At this tip, on the extracted tree:
TZ=UTC node --test .github/scripts/audit-merges.test.mjs→ 9/9TZ=UTC node --test ".github/scripts/*.test.mjs"→ 173/173Against the real repository, through this script's own
main()with itsapiinjected over the same REST pathsgh apiuses (ghis not installed on this box), at mainb5de55d0,--limit 40:#672and#674produce no line, which is the acceptance condition. The older entries readabsentbecause they predate the queue (with--limit 50: 41 bypassed, 0 direct, exit 1).Red without the source change
Three mutations of the guard, each reverting only
audit-merges.mjs:merge_grouprun exists on the commit" (the issue's literal step 4) → 5 of 9 red, including the#680fixture: the greenTestrun is read as the gate passing.conclusion === 'success'→ 4 of 9 red, same bypass fixture.head_shamatch is dropped → 1 red, the "a green gate run on a different commit says nothing about this one" guard.Restored → 9/9.
Not run
ghCLI is absent on this box, so the live run above used the injectedapirather than the realgh api; the paths are identical and the CI job that would call it hasghon the runner.ds-bot-patchescases pass here (173/173); in a tree withoutgitthey are the known four reds.Risk
T3 —
.github/**, per.github/agent/risk-rules.json; needs a PASS at this tip and a maintainer approve.Docs-not-needed: a read-only
.github/scriptscheck and its cases; no subsystem doc owns.github/.