Repository navigation
Merge queue: land every pull request as a merge commit; allow only merge commits - #8
Merged
Merged
Conversation
…rge commits An upstream merge must keep its upstream parent. With the queue squashing, it had to bypass the queue with an admin merge, and twice it went through the queue instead and lost its parent (cocoindex-plus#549, #557; #561). #7 then made ci-mode refuse a labelled pull request, but that still left a special path to remember. Now there is one path. The queue merges with merge commits (rulesets/repo/merge-queue.json), and apply_rulesets.py also sets the merge settings of every queue repository from rulesets/repo-settings.json: merge commits only, titled with the pull request's title. A pull request keeps its history, so an upstream merge goes through the queue like any change, and no merge method can squash it. Admins bypass only for incidents, with --merge. - ci-mode: back to the version before #7; the label guard has nothing left to guard. - CI.md: the queue section, Merge commits (first-parent reading, revert with -m 1), the incident bypass, Enforcement, and what was verified in cocoindex-plus on 2026-10-24. Already applied to cocoindex-plus with apply_rulesets.py; --check is clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
georgeh0
added a commit
that referenced
this pull request
Oct 24, 2026
…#9) #8 switched the queue to merge commits and disallowed squash, which changed how every pull request lands. That was not approved: regular pull requests squash. This restores the queue's SQUASH method and cocoindex-plus's merge settings as they were before #8 (squash and merge commits allowed, no rebase, merge commits titled by GitHub's default message), and keeps them as code in rulesets/repo-settings.json so apply_rulesets.py restores them. CI.md goes back to the squash queue with the admin merge for a pull request that must keep its merge commit. A guard that keeps such a pull request out of the queue follows separately. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
georgeh0
added a commit
that referenced
this pull request
Oct 24, 2026
…of history The queue squashes, and a squash keeps only a merge's first parent, so an upstream merge must land as a merge commit around the queue (CI.md, Merge commits). Three cocoindex-plus merge PRs went through the queue anyway and lost their upstream parents (#541, #549, #557; cocoindex-plus#561). On a merge_group event, ci-mode now fetches the queued pull request's history and its base, commits only (`--filter=tree:0`, about 3 MB and 2 s for cocoindex-plus), and fails when the pull request contains a merge whose first parent is on the base and whose second parent is not. It needs no label and no new permission (`contents: read`). It fails before any test job, so the queue removes the pull request cheaply. Merging the base into a branch, or a pull-style merge of a branch with itself, passes. A failed lookup fails the merge group. Checked on real cocoindex-plus pull requests with the bases they had: #530, #541, #549, #557, #565 (OSS merges) and #550 (stacked on #549's unlanded merge) fail; #550 on a base with #549's merge commit, #556, #563 and #566 pass; synthetic pull-style, base-merged and unlanded-branch shapes behave as described. apply_rulesets.py also enables merge methods before it applies the rulesets and disables them after: a merge-queue rule may only name a method the repository allows, so #8's order failed going back to SQUASH (HTTP 422). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
georgeh0
added a commit
that referenced
this pull request
Oct 24, 2026
…of history (#10) The queue squashes, and a squash keeps only a merge's first parent, so an upstream merge must land as a merge commit around the queue (CI.md, Merge commits). Three cocoindex-plus merge PRs went through the queue anyway and lost their upstream parents (#541, #549, #557; cocoindex-plus#561). On a merge_group event, ci-mode now fetches the queued pull request's history and its base, commits only (`--filter=tree:0`, about 3 MB and 2 s for cocoindex-plus), and fails when the pull request contains a merge whose first parent is on the base and whose second parent is not. It needs no label and no new permission (`contents: read`). It fails before any test job, so the queue removes the pull request cheaply. Merging the base into a branch, or a pull-style merge of a branch with itself, passes. A failed lookup fails the merge group. Checked on real cocoindex-plus pull requests with the bases they had: #530, #541, #549, #557, #565 (OSS merges) and #550 (stacked on #549's unlanded merge) fail; #550 on a base with #549's merge commit, #556, #563 and #566 pass; synthetic pull-style, base-merged and unlanded-branch shapes behave as described. apply_rulesets.py also enables merge methods before it applies the rulesets and disables them after: a merge-queue rule may only name a method the repository allows, so #8's order failed going back to SQUASH (HTTP 422). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
One formal path for every pull request, with no special case for upstream merges (cocoindex-io/cocoindex-plus#561).
rulesets/repo/merge-queue.json:merge_method: MERGE). A pull request keeps its own history, so an upstream merge keeps its upstream parent and goes through the queue like any change, tested by the queue's full run.apply_rulesets.pynow also sets the merge settings fromrulesets/repo-settings.json: squash and rebase off, merge commits titled with the PR's title, the PR's body as the message. No GitHub path can squash a pull request, not even an admin's.--merge.ci-modegoes back to its version before ci-mode: fail the merge group of a pull request labelled merge-commit #7: with nothing able to squash, themerge-commitlabel guard has nothing left to guard.mainwithgit log --first-parent, revert with-m 1), the incident bypass, § Enforcement, and the behavior verified in cocoindex-plus today.Trade-off: a feature PR's branch commits now sit behind the second parent of its merge commit. First-parent history still has one commit per PR, titled
<title> (#N)as before.Already applied to cocoindex-plus with
apply_rulesets.py;--checkis clean. After merging, movev1(ci-modechanged).Test plan
pytest scripts(20 passed), ruff, conformance on the starter workflow.apply_rulesets.py --checkreported exactly the planned drift (merge_method,allow_squash_merge, the merge commit title and message), then applied it, then reported none.0a20e997(parents206df9b9,27d78f4b).bcc8b61efromoss/mainis an ancestor ofmain, and the subject is the PR title with(#565). #566 landed the same way. An admingh pr merge --squash --adminand--rebase --adminon scratch PR #567 were refused ("Squash merges are not allowed on this repository").🤖 Generated with Claude Code