Skip to content

ci: a green PR that nobody arms is indistinguishable from a red one - #2959

Merged
rbuergi merged 3 commits into
mainfrom
ci/auto-arm-automerge
Sep 1, 2026
Merged

rbuergi merged 3 commits into
mainfrom
ci/auto-arm-automerge

Conversation

@rbuergi

@rbuergi rbuergi commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

The situation this prevents

Measured on Systemorph/MeshWeaver, 2026-09-01: six pull requests sat CLEAN with 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 on opened, reopened, ready_for_review and synchronize.

Per "same on all repos", the file is byte-identical across MeshWeaver, MeshWeaver.Plugins, .SocialMedia, .Reinsurance, .Manufacturing, .Education and .Crm (sha256 3f4a655e839e…). 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):

command result on the merge-queue repo
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

Both work today; the step tries the first and falls back to the second, because the runner's gh is 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

  • Draft is the opt-out — mark a PR draft and it is not armed.
  • Forks are skipped, so an outside branch can never arm itself.
  • Failing to arm emits a ::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_merge is confirmed enabled on this repo — and on all six others.
  • The file calls no reusable workflow and no action — there is no SHA pin to bump.
  • actionlint is clean and adds no findings to this repo's existing baseline.

🤖 Generated with Claude Code

…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>
Copilot AI lite review requested due to automatic review settings September 1, 2026 11:05
@rbuergi
rbuergi enabled auto-merge September 1, 2026 11:05
@rbuergi
rbuergi disabled auto-merge September 1, 2026 11:07
@rbuergi
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_target workflow 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
rbuergi disabled auto-merge September 1, 2026 11:11
@rbuergi
rbuergi enabled auto-merge September 1, 2026 11:11
@rbuergi
rbuergi disabled auto-merge September 1, 2026 11:11
@rbuergi
rbuergi enabled auto-merge September 1, 2026 11:11
@github-actions

github-actions Bot commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

793 tests  ±0   789 ✅ ±0   3m 23s ⏱️ +16s
  7 suites ±0     4 💤 ±0 
  7 files   ±0     0 ❌ ±0 

Results for commit 0120a6e. ± Comparison against base commit adb10c1.

♻️ This comment has been updated with latest results.

…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>
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 138 tests  ±0   1 138 ✅ ±0   3m 41s ⏱️ -10s
    7 suites ±0       0 💤 ±0 
    7 files   ±0       0 ❌ ±0 

Results for commit 0120a6e. ± Comparison against base commit adb10c1.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 169 tests  ±0   1 169 ✅ ±0   4m 40s ⏱️ +3s
    7 suites ±0       0 💤 ±0 
    7 files   ±0       0 ❌ ±0 

Results for commit 0120a6e. ± Comparison against base commit adb10c1.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    8 files  ±0      8 suites  ±0   4m 9s ⏱️ +3s
1 505 tests ±0  1 504 ✅ ±0  1 💤 ±0  0 ❌ ±0 
2 215 runs  ±0  2 214 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit 0120a6e. ± Comparison against base commit adb10c1.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

1 155 tests  ±0   1 155 ✅ ±0   8m 46s ⏱️ + 1m 20s
    7 suites ±0       0 💤 ±0 
    7 files   ±0       0 ❌ ±0 

Results for commit 0120a6e. ± Comparison against base commit adb10c1.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

3 077 tests  ±0   2 885 ✅ ±0   6m 49s ⏱️ +7s
    8 suites ±0     192 💤 ±0 
    8 files   ±0       0 ❌ ±0 

Results for commit 0120a6e. ± Comparison against base commit adb10c1.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Test Results

   44 files  ±0     44 suites  ±0   31m 30s ⏱️ + 1m 38s
8 837 tests ±0  8 640 ✅ ±0  197 💤 ±0  0 ❌ ±0 
9 547 runs  ±0  9 350 ✅ ±0  197 💤 ±0  0 ❌ ±0 

Results for commit 0120a6e. ± Comparison against base commit adb10c1.

@rbuergi
rbuergi added this pull request to the merge queue Sep 1, 2026
Merged via the queue into main with commit c95da3c Sep 1, 2026
25 checks passed
@rbuergi
rbuergi deleted the ci/auto-arm-automerge branch September 13, 2026 10:30
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.

2 participants