feat: consolidate auto-merge into single reliable workflow#775
Conversation
…ests - Rewrite auto-merge.yml: consolidate enable/disable (pull_request) and new merge-on-gate-pass (check_run: All Gates Passed) + bot-approve jobs - Stub auto-merge-on-ci.yml (deprecated workflow_run/AGI smoke trigger) - Create .github/actions/check-auto-merge-eligibility/action.yml composite action with draft/fork/label/conflict/review eligibility checks - Add merge_queue rule to main-default-automation.ruleset.json - Update .github/workflows/README.md with auto-merge policy and new secrets - Update .github/DEFAULT_GITHUB_AUTOMATION.md with label setup instructions - Add tests/test_auto_merge_workflow.py (35 tests, all passing)
- Fix concurrency group: use explicit != '' guard for PR number to avoid falsy coalesce when pull_request.number is 0 - Fix fork guard: explicit null check for prData.head.repo (deleted forks) - Fix mergeable check: only merge when mergeable===true (not just !false); distinguish null (pending) from false (conflict/behind) in log/comment - Fix review ordering: sort reviews by submitted_at before building latestByReviewer map to ensure chronological precedence - Fix eligibility action error output: sanitize gh CLI stderr (strip ANSI codes, truncate to 120 chars) before writing to GITHUB_OUTPUT - Fix test file: remove duplicate section header above _get_triggers helper
- Revert concurrency group to simple || (PR number is numeric, != '' is wrong)
- Use context.payload.repository.full_name for fork guard (avoids string concat)
- Replace cut -c1-120 with bash substring ${var:0:120} in eligibility action
(character-aware, avoids splitting multi-byte UTF-8 on some systems)
- Consolidate test assert message for All Gates Passed onto one line
There was a problem hiding this comment.
Sorry @Copilot, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
There was a problem hiding this comment.
Sorry @Bryan-Roe, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
@Bryan-Roe Thanks for sending me some feedback. Unfortunately, I hit an error while trying to use the custom Copilot setup steps configured for this repository. The error I am seeing is: Once you or someone with the necessary access fixes the problem, please let me know in a comment and I'll try again. Thanks! |
🔐 CodeQL — Open Alerts on this PR
Copilot Autofix suggestions (if enabled) appear as inline review comments on the affected lines. |
There was a problem hiding this comment.
Pull request overview
This PR consolidates the repository's overlapping auto-merge automation into a single auto-merge.yml workflow to fix a reliability gap: the old CI-triggered path watched workflow_run: ["AGI smoke"], whose pull_requests field is routinely empty for human-created PRs. The new design triggers merges off the canonical check_run for Merge Gate / All Gates Passed (whose PR association is reliably populated), adds explicit eligibility gating, and introduces an optional gated bot-approval path. It also deprecates the old workflow to a manual no-op, adds a merge_queue ruleset rule, a reusable eligibility composite action, docs, and structural tests.
Changes:
- Rewrote
auto-merge.ymlinto four jobs (enable,disable,merge-on-gate-pass,bot-approve) with fork/draft guards and a bot-approval allowlist gated behindAUTO_MERGE_BOT_APPROVE/AUTO_MERGE_APPROVE_TOKEN. - Stubbed
auto-merge-on-ci.ymlto aworkflow_dispatch-only no-op; added amerge_queuerule to the branch ruleset; added acheck-auto-merge-eligibilitycomposite action. - Added 35 structural unit tests and updated
README.md/DEFAULT_GITHUB_AUTOMATION.md.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
.github/workflows/auto-merge.yml |
Consolidated 4-job auto-merge workflow (label arm/disarm, gate-pass merge, bot-approve). |
.github/workflows/auto-merge-on-ci.yml |
Reduced to a manual-only deprecated stub. |
.github/actions/check-auto-merge-eligibility/action.yml |
New composite eligibility action — but not referenced by any workflow (dead/duplicated logic). |
.github/rulesets/main-default-automation.ruleset.json |
Adds a merge_queue rule; introduces // comments that break the strict-JSON validator/import. |
.github/DEFAULT_GITHUB_AUTOMATION.md |
Documents auto-merge and dependabot auto-merge policy and label setup. |
.github/workflows/README.md |
Adds auto-merge policy table, allowlist, and secret/variable rows. |
tests/test_auto_merge_workflow.py |
New structural tests; two stub tests read triggers incorrectly and pass vacuously. |
| name: Check Auto-Merge Eligibility | ||
| description: > | ||
| Validates all eligibility criteria for automatic PR merging and outputs | ||
| whether the PR is eligible together with a human-readable reason. | ||
| Checks: not draft, targets main, not a fork, has auto-merge/autofix label, | ||
| not blocked/conflicted, no CHANGES_REQUESTED reviews, has an APPROVED review. |
| // Merge queue: prevents the thundering-herd problem when many | ||
| // auto-merge labeled PRs all become mergeable simultaneously. | ||
| // Requires enabling the merge queue in repository Settings → General | ||
| // → Pull Requests → "Allow merge queue" (UI-only setting). |
|
|
||
| def test_auto_merge_on_ci_no_longer_watches_agi_smoke() -> None: | ||
| wf = _load_auto_merge_on_ci() | ||
| triggers = wf.get("on", {}) |
| def test_auto_merge_on_ci_stub_has_no_automatic_trigger() -> None: | ||
| """The stub must not fire automatically to avoid consuming CI minutes.""" | ||
| wf = _load_auto_merge_on_ci() | ||
| triggers = wf.get("on", {}) |
The existing auto-merge setup had three overlapping workflows with a critical reliability gap:
auto-merge-on-ci.ymltriggered onworkflow_run: ["AGI smoke"]—workflow_run.pull_requestsis routinely empty for human-created PRs, and the wrong CI signal was being watched instead of the canonicalMerge Gate / All Gates Passedgate.Changes
auto-merge.yml— consolidated workflow (4 jobs)enable/disable: unchanged label-arm/disarm behavior; adds fork+draft guard and an informational PR comment on armmerge-on-gate-pass(new): triggers oncheck_run: completedfilteringcheck_run.name == 'All Gates Passed'—check_run.pull_requestsis reliably populated. Full eligibility gate per PR: label present, not draft, not fork,mergeable === true(distinguishesnull=pending fromfalse=conflict), reviews sorted bysubmitted_atbefore building latest-per-reviewer map, noCHANGES_REQUESTED, hasAPPROVEDbot-approve(new): gated byvars.AUTO_MERGE_BOT_APPROVE == 'true'; approves PRs authored byBOT_APPROVE_ALLOWLISTactors usingAUTO_MERGE_APPROVE_TOKENPAT (separate identity required —GITHUB_TOKENcannot self-approve)auto-merge-on-ci.yml— stubbedReplaced with
workflow_dispatch-only no-op. Removes the brokenworkflow_run: ["AGI smoke"]automatic trigger..github/actions/check-auto-merge-eligibility/action.yml— new composite actionEncodes all eligibility rules as a reusable
gh-CLI action; outputseligible: true/falseandreason.main-default-automation.ruleset.jsonAdded
merge_queuerule (requires UI opt-in: Settings → General → Pull Requests → "Allow merge queue").Docs + tests
DEFAULT_GITHUB_AUTOMATION.mdupdated with policy table, bot-actor allowlist, andgh label createsetup commandstests/test_auto_merge_workflow.py: 35 unit tests covering trigger config, per-jobif:conditions, eligibility action contract, and stub verificationRequired manual setup