feat(reusable): disable auto-merge when a new commit is pushed (#10)
Reusable workflow that consumers call from their pr-guards.yml on pull_request:synchronize. When a new commit is pushed to an open PR that has auto-merge enabled, this disables auto-merge and posts a comment so the operator must explicitly re-engage after verifying. Background: on 2026-04-27, PR #2174 in molecule-core auto-merged with only the first commit because the second commit was pushed AFTER the merge queue had locked the PR's SHA. The second commit ended up orphaned on a merged-and-deleted branch (the wider "automatically delete head branches" repo setting now blocks the push entirely; this workflow catches the race window where the PR is queued but not yet merged). Defense in depth — if both fixes are active: 1. Repo setting "delete branch on merge" prevents pushes to a merged branch (post-merge orphan case). 2. This workflow catches in-queue races (push lands while the queue is processing) by force-disabling auto-merge so the operator must re-engage explicitly. Together they cover the full lifecycle of "auto-merge enabled → new commits arrive" without relying on operator discipline. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0335ec169c
commit
d5caaac219
53
.github/workflows/disable-auto-merge-on-push.yml
vendored
Normal file
53
.github/workflows/disable-auto-merge-on-push.yml
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
name: Disable auto-merge on push
|
||||
|
||||
# Reusable guard against the "I enabled auto-merge then pushed more
|
||||
# commits" race. Background: on 2026-04-27, PR #2174 in molecule-core
|
||||
# auto-merged with only the first commit because the second commit
|
||||
# was pushed AFTER the merge queue had already locked the PR's SHA.
|
||||
# The second commit ended up orphaned on a merged-and-deleted branch.
|
||||
#
|
||||
# Mechanism: on every `pull_request: synchronize` event (= new commit
|
||||
# pushed to an open PR), check if auto-merge is enabled. If yes,
|
||||
# disable it and post a comment. This forces the operator to
|
||||
# re-engage `gh pr merge --auto` after the new push, with the
|
||||
# re-engagement acting as the verification step.
|
||||
#
|
||||
# Call from each repo's .github/workflows/ via a thin wrapper:
|
||||
#
|
||||
# name: pr-guards
|
||||
# on:
|
||||
# pull_request:
|
||||
# types: [synchronize]
|
||||
# permissions:
|
||||
# pull-requests: write
|
||||
# jobs:
|
||||
# disable-auto-merge-on-push:
|
||||
# uses: Molecule-AI/molecule-ci/.github/workflows/disable-auto-merge-on-push.yml@main
|
||||
#
|
||||
# False-positive behavior: if a CI bot pushes (e.g. dependency-update
|
||||
# rebase, secret rotation), this also disables auto-merge for that
|
||||
# PR. That's acceptable — the operator who originally enabled
|
||||
# auto-merge gets notified and re-engages, which is exactly the
|
||||
# verify-after-machine-edits behavior we want.
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
guard:
|
||||
name: Disable auto-merge on push
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.auto_merge != null
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Disable auto-merge
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
PR: ${{ github.event.pull_request.number }}
|
||||
REPO: ${{ github.repository }}
|
||||
NEW_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: |
|
||||
set -eu
|
||||
gh pr merge "$PR" --disable-auto -R "$REPO" || true
|
||||
gh pr comment "$PR" -R "$REPO" --body "🔒 Auto-merge disabled — new commit (\`${NEW_SHA:0:7}\`) pushed after auto-merge was enabled. The merge queue locks SHAs at entry, so subsequent pushes can race. Verify the new commit and re-enable with \`gh pr merge --auto\`."
|
||||
Loading…
Reference in New Issue
Block a user