Skip to content

claude-author-automerge: GitHub server-side branch-update uses GITHUB_TOKEN, can't be PAT-replaced from workflow #59

@topcoder1

Description

@topcoder1

Background

Lesson banked in dotclaude/CLAUDE.md (2026-05-12 burn on techrecon#147) framed this as:

claude-author-automerge.yml's update-branch step rebased the install PR (merged main into the feature branch via github-actions[bot]), advancing HEAD SHA from 360d460 to 2b942bd. ... claude-author-automerge would need a PAT for the branch-update push.

On closer inspection, there is no update-branch step in claude-author-automerge.yml. The merge commit attributed to github-actions[bot] is generated by GitHub's server-side auto-merge service, which kicks in automatically when a PR with gh pr merge --auto enabled has stale base. That service:

  • Uses GITHUB_TOKEN (no caller override possible)
  • Subjects all spawned pushes to GitHub's recursion-prevention rule (no pull_request workflows fire on the new SHA)
  • Result: PR sits BLOCKED with empty check rollup forever

What does NOT fix this

  • Adding secrets.automerge_pat to the Enable auto-merge step — doesn't help, the bad rebase happens server-side AFTER auto-merge is enabled, not in our workflow
  • Pre-rebasing with PAT before enabling auto-merge — only solves the "PR opened against stale base" case; doesn't help if base advances AFTER our workflow finishes

Three architectural fix options

Option A — Proactive rebase on push:main

Add on: push: branches: [main] trigger to claude-author-automerge.yml. For every open Claude-authored PR with a stale base, force-update with PAT. Keeps branches fresh proactively. Drawback: bursty load when many PRs are open + main moves rapidly.

Option B — Reactive self-heal on stuck PRs

New workflow claude-pr-self-heal.yml triggered on check_suite: completed. When it detects mergeStateStatus=BLOCKED + empty rollup + last commit by github-actions[bot], push an empty user-attributed commit using PAT. This is the canonical manual workaround, just automated. Drawback: reactive — PR sits stuck for one check_suite cycle before self-healing.

Option C — Replace gh pr merge --auto with merge-when-ready

Don't use GitHub's auto-merge service. Add a workflow that listens to check_run: completed / check_suite: completed events, polls all required-check states, and calls gh pr merge --squash directly (with PAT) when everything is green. Eliminates GitHub's auto-merge service from the critical path entirely. Drawback: larger architectural shift; ~100+ lines of new workflow; more failure modes to test.

Current workaround

Push an empty user-attributed commit to the stuck branch:

git clone --depth 5 --branch <branch> https://github.com/<repo>.git
cd <repo>
git commit --allow-empty -m "ci: retrigger"
git push

Documented in lesson #235 in dotclaude/CLAUDE.md.

Recommendation

Option B is the smallest viable fix and matches what we already do manually. Open this issue and accept the latency cost (one check_suite cycle before self-heal). Options A and C are bigger lifts that can come later if Option B proves inadequate.

Not blocking — manual workaround works fine for low-frequency occurrence. The lesson on dotclaude/CLAUDE.md gives the diagnosis pattern (BLOCKED + empty rollup + github-actions[bot] last commit). Filing this issue so the architecture decision is captured for whoever picks this up next.

🤖 Auto-filed during test-ratchet Wave 2 close-out

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions