Repository navigation
ci: a green PR that nobody arms is indistinguishable from a red one - #2959
Merged
Merged
Conversation
…er lands Measured on this repo, 2026-09-01: SIX pull requests sat CLEAN with an EMPTY merge queue and auto-merge armed on none of them. Nothing was failing, nothing was blocked, and nothing was landing either — the trunk sat still while six finished changes waited on a human to press a button. A green PR that nobody arms is indistinguishable from a red one: both show up as "not merged", and neither tells you which it is. This adds the shared `Arm auto-merge` lane, byte-identical to the one landing across MeshWeaver.Plugins and the four satellites, so the behaviour is the same in every repo rather than a per-repo habit. It does NOT weaken a single gate. Auto-merge waits for exactly the required contexts branch protection already demands — here, `Consolidate test results` plus the merge queue's own ALLGREEN run. All it removes is the human round-trip between "green" and "merged". The one opt-out is deliberate and needs no configuration: mark a PR draft and it is not armed. Forks are skipped too, so an outside branch can never arm itself. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rbuergi
enabled auto-merge
September 1, 2026 11:05
rbuergi
disabled auto-merge
September 1, 2026 11:07
rbuergi
enabled auto-merge
September 1, 2026 11:07
Tested against this repo rather than inferred from docs (gh 2.95.0, 2026-09-01, PR #2959): gh pr merge --merge --auto → exit 0, armed; warns "The merge strategy for main is set by the merge queue" gh pr merge --auto → exit 0, armed So core accepts the invocation the shared file already used. But the two are not interchangeable everywhere: this repo's ruleset carries a merge_queue rule (merge_method SQUASH) and the five satellites carry none, a queue OWNS the merge strategy and some gh versions reject `--merge` alongside one outright, while a repo with no queue refuses to arm non-interactively unless a method IS named. The runner's gh version is not the one pinned here and it moves weekly. So the arm step now names the method and falls back to letting the queue decide, instead of the file forking per repo — divergent copies of a shared lane are a recorded failure mode in this family. It also reads the arm back afterwards. An exit code of 0 is the command's opinion; the read-back is the evidence, and it names the likely cause ("Allow auto-merge" disabled on the repo) when the arm silently did nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a repository workflow to automatically arm GitHub auto-merge for eligible pull requests, ensuring green PRs reliably enter the merge queue without a manual “arm” step.
Changes:
- Introduces a new
pull_request_targetworkflow that arms auto-merge on PR lifecycle events (opened/reopened/ready_for_review/synchronize). - Skips drafts and forks to preserve an explicit opt-out and avoid self-merging from untrusted sources.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+45
to
+52
| set -euo pipefail | ||
| # Already armed is the common case on `synchronize` and is NOT a failure. | ||
| if gh pr view "$PR" --repo "$REPO" --json autoMergeRequest --jq '.autoMergeRequest != null' | grep -qx true; then | ||
| echo "already armed — nothing to do"; exit 0 | ||
| fi | ||
| # A merged/closed PR races us on `synchronize`; treat it as done, not as an error. | ||
| state=$(gh pr view "$PR" --repo "$REPO" --json state --jq .state) | ||
| if [ "$state" != "OPEN" ]; then echo "PR is $state — nothing to arm"; exit 0; fi |
rbuergi
disabled auto-merge
September 1, 2026 11:11
rbuergi
enabled auto-merge
September 1, 2026 11:11
rbuergi
disabled auto-merge
September 1, 2026 11:11
rbuergi
enabled auto-merge
September 1, 2026 11:11
Contributor
…antly Found by actually firing the lane rather than reasoning about it (MeshWeaver.Crm#43, run 33502334335, the first live run of this workflow): arm requested (--merge): ok ##[warning]auto-merge still not set on #43 after a clean arm — is 'Allow auto-merge' enabled on Systemorph/MeshWeaver.Crm? Both lines are about a PR that had just MERGED successfully. Arming a PR with nothing left to wait for merges it on the spot, so there is no auto-merge request left to read back — and the read-back reported that as a failure, blaming a repo setting that was never off. A diagnostic that names the wrong cause is worse than none: this lane's entire safety net is that failing to arm is VISIBLE, and a warning that fires on the success path is one people learn to scroll past. So the read-back now checks whether the PR is simply no longer OPEN and says "landed" instead. The warning is kept for the case it was written for — a clean arm that genuinely left the PR open and unarmed, which is what `allow_auto_merge` being off looks like. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Contributor
Contributor
Contributor
Contributor
Contributor
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.
The situation this prevents
Measured on
Systemorph/MeshWeaver, 2026-09-01: six pull requests satCLEANwith an empty merge queue and auto-merge armed on none of them. Nothing failing, nothing blocked, and nothing landing — the trunk sat still while six finished changes waited on a human to press a button.A green PR that nobody arms is indistinguishable from a red one. Both read as "not merged", and neither tells you which it is.
What this adds
One workflow,
.github/workflows/auto-arm.yml, arming auto-merge on every non-draft, non-fork PR onopened,reopened,ready_for_reviewandsynchronize.Per "same on all repos", the file is byte-identical across
MeshWeaver,MeshWeaver.Plugins,.SocialMedia,.Reinsurance,.Manufacturing,.Educationand.Crm(sha2563f4a655e839e…). The repos are not identical — this repo runs a merge queue (merge_method: SQUASH) and the other six do not — so the arm step handles both shapes internally rather than the file forking per repo. Divergent copies of a shared lane are a recorded failure mode in this family.The two invocations were tested, not read off docs (gh 2.95.0, on core PR #2959):
gh pr merge --merge --autogh pr merge --autoBoth work today; the step tries the first and falls back to the second, because the runner's
ghis not the version pinned here and it moves weekly.This weakens no gate
Auto-merge waits for exactly the required contexts branch protection already demands. It changes when a PR merges, never what it must pass.
The opt-out needs no configuration
::warning::and exits 0 — not fatal, but never silent, since a silent failure would recreate the exact state this exists to fix.Both conditions are properties of the event, not configuration: no variable to forget to set (CI invariant #3).
Notes
allow_auto_mergeis confirmed enabled on this repo — and on all six others.actionlintis clean and adds no findings to this repo's existing baseline.🤖 Generated with Claude Code