Skip to content

feat: consolidate auto-merge into single reliable workflow#775

Merged
Bryan-Roe merged 4 commits into
mainfrom
copilot/explore-codebase-merge-prs
Jul 6, 2026
Merged

feat: consolidate auto-merge into single reliable workflow#775
Bryan-Roe merged 4 commits into
mainfrom
copilot/explore-codebase-merge-prs

Conversation

Copilot AI commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

The existing auto-merge setup had three overlapping workflows with a critical reliability gap: auto-merge-on-ci.yml triggered on workflow_run: ["AGI smoke"]workflow_run.pull_requests is routinely empty for human-created PRs, and the wrong CI signal was being watched instead of the canonical Merge Gate / All Gates Passed gate.

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 arm
  • merge-on-gate-pass (new): triggers on check_run: completed filtering check_run.name == 'All Gates Passed'check_run.pull_requests is reliably populated. Full eligibility gate per PR: label present, not draft, not fork, mergeable === true (distinguishes null=pending from false=conflict), reviews sorted by submitted_at before building latest-per-reviewer map, no CHANGES_REQUESTED, has APPROVED
  • bot-approve (new): gated by vars.AUTO_MERGE_BOT_APPROVE == 'true'; approves PRs authored by BOT_APPROVE_ALLOWLIST actors using AUTO_MERGE_APPROVE_TOKEN PAT (separate identity required — GITHUB_TOKEN cannot self-approve)

auto-merge-on-ci.yml — stubbed

Replaced with workflow_dispatch-only no-op. Removes the broken workflow_run: ["AGI smoke"] automatic trigger.

.github/actions/check-auto-merge-eligibility/action.yml — new composite action

Encodes all eligibility rules as a reusable gh-CLI action; outputs eligible: true/false and reason.

main-default-automation.ruleset.json

Added merge_queue rule (requires UI opt-in: Settings → General → Pull Requests → "Allow merge queue").

Docs + tests

  • README and DEFAULT_GITHUB_AUTOMATION.md updated with policy table, bot-actor allowlist, and gh label create setup commands
  • tests/test_auto_merge_workflow.py: 35 unit tests covering trigger config, per-job if: conditions, eligibility action contract, and stub verification

Required manual setup

gh label create auto-merge --color 0075ca --description "Squash-merge when all CI gates pass"
gh label create autofix    --color e4e669 --description "Auto-merge for automated fix PRs"
# Add secret: AUTO_MERGE_APPROVE_TOKEN (PAT with pull-requests:write, separate identity)
# Add variable: AUTO_MERGE_BOT_APPROVE=true

Copilot AI added 3 commits July 6, 2026 23:49
…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
Copilot AI requested review from Copilot and removed request for Copilot July 6, 2026 23:53

@sourcery-ai sourcery-ai Bot 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.

Sorry @Copilot, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Copilot AI changed the title feat: consolidate auto-merge workflows and add eligibility composite action feat: consolidate auto-merge into single reliable workflow Jul 6, 2026
Copilot AI requested a review from Bryan-Roe July 6, 2026 23:54
@Bryan-Roe Bryan-Roe marked this pull request as ready for review July 6, 2026 23:55
Copilot AI review requested due to automatic review settings July 6, 2026 23:55

@sourcery-ai sourcery-ai Bot 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.

Sorry @Bryan-Roe, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copilot AI commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@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:

no `copilot-setup-steps` job found in your `copilot-setup-steps.yml` workflow file. Please ensure you have a single job named `copilot-setup-steps`. For more details, see https://gh.io/copilot/actions-setup-steps

Once you or someone with the necessary access fixes the problem, please let me know in a comment and I'll try again. Thanks!

@Bryan-Roe Bryan-Roe merged commit 9cebc9d into main Jul 6, 2026
69 of 84 checks passed
@Bryan-Roe Bryan-Roe deleted the copilot/explore-codebase-merge-prs branch July 6, 2026 23:55
@github-actions github-actions Bot added documentation Improvements or additions to documentation github-actions tests labels Jul 6, 2026
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🔐 CodeQL — Open Alerts on this PR

Severity Count
medium 67
high 92
note 727
warning 83
error 108
critical 1

Copilot Autofix suggestions (if enabled) appear as inline review comments on the affected lines.
See the full list in the Security tab.

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

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.yml into four jobs (enable, disable, merge-on-gate-pass, bot-approve) with fork/draft guards and a bot-approval allowlist gated behind AUTO_MERGE_BOT_APPROVE/AUTO_MERGE_APPROVE_TOKEN.
  • Stubbed auto-merge-on-ci.yml to a workflow_dispatch-only no-op; added a merge_queue rule to the branch ruleset; added a check-auto-merge-eligibility composite 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.

Comment on lines +1 to +6
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.
Comment on lines +37 to +40
// 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", {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation github-actions tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants