From de042bdd5b11fe27e28de0f468f6a80c7a444ef8 Mon Sep 17 00:00:00 2001 From: Shivakumar Date: Sat, 18 Jul 2026 10:08:06 +0530 Subject: [PATCH 1/3] ci: auto-enable merge-when-ready on every PR open No human or agent needs to remember gh pr merge --auto anymore -- this flips every non-draft PR into GitHub's native auto-merge state the moment it's opened. Branch protection's required status checks still gate the actual merge; GitHub re-syncs a BEHIND branch itself. Configurable without a code change: gh variable set AUTO_MERGE_ENABLED --body false to disable repo-wide. --- .github/workflows/auto-merge.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/auto-merge.yml diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml new file mode 100644 index 00000000..be35acb5 --- /dev/null +++ b/.github/workflows/auto-merge.yml @@ -0,0 +1,29 @@ +name: auto-merge + +on: + pull_request: + types: + - opened + - reopened + - ready_for_review + +jobs: + enable-auto-merge: + name: Enable auto-merge + # Toggle repo-wide without touching this file: + # gh variable set AUTO_MERGE_ENABLED --body false (disable) + # gh variable set AUTO_MERGE_ENABLED --body true (re-enable, or just delete the variable — unset defaults to enabled) + if: vars.AUTO_MERGE_ENABLED != 'false' && github.event.pull_request.draft == false + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + # Doesn't merge anything itself — just flips the PR into GitHub's + # native auto-merge state. Branch protection's required status checks + # (build/clippy/fmt/etc., all "strict") still gate the actual merge, + # and GitHub re-syncs a BEHIND branch on its own before merging, so + # this replaces the manual "remember to pass --auto" step entirely. + - name: gh pr merge --auto + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: gh pr merge --auto --squash --delete-branch "${{ github.event.pull_request.number }}" --repo "${{ github.repository }}" From 1c777f5c6c826dfb87ba75671476dd7ab774e873 Mon Sep 17 00:00:00 2001 From: Shivakumar Date: Sat, 18 Jul 2026 10:09:27 +0530 Subject: [PATCH 2/3] fix(ci): auto-merge workflow needs a PAT, not the default GITHUB_TOKEN enablePullRequestAutoMerge rejects the Actions-issued token with 'Resource not accessible by integration' regardless of declared permissions. Needs a real PAT in the AUTOMERGE_TOKEN secret. --- .github/workflows/auto-merge.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index be35acb5..0aee7f32 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -23,7 +23,14 @@ jobs: # (build/clippy/fmt/etc., all "strict") still gate the actual merge, # and GitHub re-syncs a BEHIND branch on its own before merging, so # this replaces the manual "remember to pass --auto" step entirely. + # + # Needs a real PAT, not the default token: GitHub's Actions-issued + # GITHUB_TOKEN is rejected by the enablePullRequestAutoMerge mutation + # ("Resource not accessible by integration") regardless of declared + # permissions — confirmed 2026-07-18. Create a fine-grained PAT scoped + # to this repo with Pull requests: read/write, then: + # gh secret set AUTOMERGE_TOKEN --body - name: gh pr merge --auto env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.AUTOMERGE_TOKEN }} run: gh pr merge --auto --squash --delete-branch "${{ github.event.pull_request.number }}" --repo "${{ github.repository }}" From b7d00dc68ac0f449c58bfc764f0568d78bb99427 Mon Sep 17 00:00:00 2001 From: Shivakumar Date: Sat, 18 Jul 2026 10:11:12 +0530 Subject: [PATCH 3/3] fix(ci): exclude fork PRs from auto-merge auto-enable External contributions never get auto-merge auto-enabled here regardless of CI status -- head.repo.full_name != repository is an explicit gate, not an accident of GitHub blocking secrets from fork-triggered pull_request runs. --- .github/workflows/auto-merge.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/auto-merge.yml b/.github/workflows/auto-merge.yml index 0aee7f32..db92628d 100644 --- a/.github/workflows/auto-merge.yml +++ b/.github/workflows/auto-merge.yml @@ -13,7 +13,18 @@ jobs: # Toggle repo-wide without touching this file: # gh variable set AUTO_MERGE_ENABLED --body false (disable) # gh variable set AUTO_MERGE_ENABLED --body true (re-enable, or just delete the variable — unset defaults to enabled) - if: vars.AUTO_MERGE_ENABLED != 'false' && github.event.pull_request.draft == false + # + # head.repo.full_name == repository excludes forks explicitly — CI + # passing is not the same as a human having reviewed what an external + # PR's code actually does, so third-party contributions never get + # auto-merge auto-enabled here regardless of check status. (GitHub also + # blocks secrets from fork-triggered pull_request runs by default, so + # AUTOMERGE_TOKEN wouldn't be reachable from a fork either way — this + # check makes that explicit instead of relying on it silently.) + if: >- + vars.AUTO_MERGE_ENABLED != 'false' && + github.event.pull_request.draft == false && + github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-latest permissions: pull-requests: write