Skip to content

Auto-update auto-merge PRs when main is pushed (#526) #1

Auto-update auto-merge PRs when main is pushed (#526)

Auto-update auto-merge PRs when main is pushed (#526) #1

name: Auto-update PRs
# When commits land on main, update every open PR targeting main that has
# auto-merge enabled, so the branch is current with main. This lets GitHub
# auto-merge actually fire instead of waiting for someone to click
# "Update branch".
#
# Uses the "Update pull request branch" API:
# PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch
# This honors the repo's merge-queue / merge method settings (merge or rebase).
on:
push:
branches: [main]
workflow_dispatch:
permissions:
contents: write
pull-requests: write
concurrency:
group: auto-update-prs-${{ github.ref }}
cancel-in-progress: false
jobs:
update:
runs-on: ubuntu-latest
steps:
- name: Update auto-merge-enabled PRs targeting main
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
set -euo pipefail
# List open PRs targeting main that have auto-merge enabled. Skip
# drafts and PRs whose head branch lives in a different repository
# (forks, sibling repos), since update-branch can't push to those
# with GITHUB_TOKEN. Match the full nameWithOwner so a same-org
# fork or sibling repo isn't mistaken for the canonical repo.
prs=$(gh pr list \
--base main \
--state open \
--limit 500 \
--json number,isDraft,headRepository,headRepositoryOwner,autoMergeRequest \
--jq ".[]
| select(.isDraft == false)
| select(.autoMergeRequest != null)
| select((.headRepositoryOwner.login + \"/\" + .headRepository.name) == \"${GH_REPO}\")
| .number")
if [ -z "$prs" ]; then
echo "No auto-merge-enabled PRs to update."
exit 0
fi
for pr in $prs; do
echo "::group::PR #$pr"
# 202 = update queued, 422 = already up to date or has conflicts.
# We tolerate 422 so one stuck PR doesn't fail the whole job, but
# any other non-success status (auth, rate limit, outage) fails
# loudly so regressions don't silently no-op the workflow.
set +e
output=$(gh api \
--method PUT \
-H "Accept: application/vnd.github+json" \
"/repos/${GH_REPO}/pulls/${pr}/update-branch" 2>&1)
exit_code=$?
set -e
if [ $exit_code -eq 0 ]; then
echo "Update queued for PR #$pr"
elif echo "$output" | grep -q "HTTP 422"; then
echo "Skipped PR #$pr (HTTP 422: already up to date, has conflicts, or not updatable)"
else
echo "::error::Unexpected failure updating PR #$pr"
echo "$output"
echo "::endgroup::"
exit 1
fi
echo "::endgroup::"
done