Skip to content

Commit 5b45da5

Browse files
nmetulevCopilot
andauthored
Auto-update auto-merge PRs when main is pushed (#526)
## Problem When multiple PRs are queued behind each other, GitHub's auto-merge waits for each PR's branch to be up-to-date with main before merging. Today that requires someone to click `Update branch` on every PR after each merge, which is tedious and the checks take a long time. ## Fix Add `.github/workflows/auto-update-prs.yml` which triggers on every push to `main` and: 1. Lists all open, non-draft PRs targeting main that have **auto-merge enabled** (and aren't from forks - `GITHUB_TOKEN` can't push to fork branches). 2. Calls the GitHub `PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch` API on each one - the same thing the green `Update branch` button does. It honors the repo's configured merge method (merge or rebase). Result: PRs with auto-merge enabled stay current with main automatically, and the auto-merge queue can flow without manual intervention. ## Notes - Uses the built-in `GITHUB_TOKEN`; no PAT or secrets needed. - 422 responses (already up-to-date / conflicts) are tolerated so one stuck PR doesn't fail the run. - `concurrency` is configured with `cancel-in-progress: false` so rapid pushes to main don't cancel an in-flight update batch. - Only auto-merge-enabled PRs are touched, so this won't spam CI on draft / WIP branches. --------- Co-authored-by: Nikola Metulev <711864+nmetulev@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 44a1179 commit 5b45da5

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Auto-update PRs
2+
3+
# When commits land on main, update every open PR targeting main that has
4+
# auto-merge enabled, so the branch is current with main. This lets GitHub
5+
# auto-merge actually fire instead of waiting for someone to click
6+
# "Update branch".
7+
#
8+
# Uses the "Update pull request branch" API:
9+
# PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch
10+
# This honors the repo's merge-queue / merge method settings (merge or rebase).
11+
12+
on:
13+
push:
14+
branches: [main]
15+
workflow_dispatch:
16+
17+
permissions:
18+
contents: write
19+
pull-requests: write
20+
21+
concurrency:
22+
group: auto-update-prs-${{ github.ref }}
23+
cancel-in-progress: false
24+
25+
jobs:
26+
update:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- name: Update auto-merge-enabled PRs targeting main
30+
env:
31+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
GH_REPO: ${{ github.repository }}
33+
run: |
34+
set -euo pipefail
35+
36+
# List open PRs targeting main that have auto-merge enabled. Skip
37+
# drafts and PRs whose head branch lives in a different repository
38+
# (forks, sibling repos), since update-branch can't push to those
39+
# with GITHUB_TOKEN. Match the full nameWithOwner so a same-org
40+
# fork or sibling repo isn't mistaken for the canonical repo.
41+
prs=$(gh pr list \
42+
--base main \
43+
--state open \
44+
--limit 500 \
45+
--json number,isDraft,headRepository,headRepositoryOwner,autoMergeRequest \
46+
--jq ".[]
47+
| select(.isDraft == false)
48+
| select(.autoMergeRequest != null)
49+
| select((.headRepositoryOwner.login + \"/\" + .headRepository.name) == \"${GH_REPO}\")
50+
| .number")
51+
52+
if [ -z "$prs" ]; then
53+
echo "No auto-merge-enabled PRs to update."
54+
exit 0
55+
fi
56+
57+
for pr in $prs; do
58+
echo "::group::PR #$pr"
59+
# 202 = update queued, 422 = already up to date or has conflicts.
60+
# We tolerate 422 so one stuck PR doesn't fail the whole job, but
61+
# any other non-success status (auth, rate limit, outage) fails
62+
# loudly so regressions don't silently no-op the workflow.
63+
set +e
64+
output=$(gh api \
65+
--method PUT \
66+
-H "Accept: application/vnd.github+json" \
67+
"/repos/${GH_REPO}/pulls/${pr}/update-branch" 2>&1)
68+
exit_code=$?
69+
set -e
70+
71+
if [ $exit_code -eq 0 ]; then
72+
echo "Update queued for PR #$pr"
73+
elif echo "$output" | grep -q "HTTP 422"; then
74+
echo "Skipped PR #$pr (HTTP 422: already up to date, has conflicts, or not updatable)"
75+
else
76+
echo "::error::Unexpected failure updating PR #$pr"
77+
echo "$output"
78+
echo "::endgroup::"
79+
exit 1
80+
fi
81+
echo "::endgroup::"
82+
done

0 commit comments

Comments
 (0)