Skip to content

feat(automerge): add Claude-author auto-merge reusable workflow#20

Merged
topcoder1 merged 1 commit into
mainfrom
feat/claude-author-automerge
May 2, 2026
Merged

feat(automerge): add Claude-author auto-merge reusable workflow#20
topcoder1 merged 1 commit into
mainfrom
feat/claude-author-automerge

Conversation

@topcoder1

Copy link
Copy Markdown
Owner

Summary

Adds .github/workflows/claude-author-automerge.yml reusable workflow that auto-enables gh pr merge --auto --squash on PRs detected as Claude-authored — unless the diff touches risk-tier paths.

Detection signals (any of)

  • Branch matches claude/*
  • Any commit in PR has Co-Authored-By: Claude trailer
  • PR carries auto-merge label

Risk-tier path filter (encodes global CLAUDE.md policy)

Auto-merge is skipped when changed files match any of:

  • auth / login / session / oauth / sso
  • secrets / .env* / keychain* / credentials*
  • migrations/ / *.sql
  • billing / payment* / pricing* / invoice*
  • Dockerfile, .github/workflows/**, infra/, terraform/, pulumi/, deploy*.{sh,yml,yaml}

On match: posts a sticky comment + skips. Manual click-merge still works.

Branch protection still applies

This only flips the auto-merge toggle. Required checks (Claude Review) must still pass before GitHub merges. The risk-tier filter is an extra circuit breaker on top.

Companion

Pairs with new install-automerge-policy.sh in topcoder1/dotclaude for fleet rollout.

Auto-merge rationale: workflow file in this repo (.github/workflows/**) — installer modifies CI config, deserves manual review; not auto-merging.

Codex pre-review: skipped (workflow-only change, ~190 lines, no business logic — Claude Review covers this category sufficiently).

Test plan

  • Land this PR
  • Run install-automerge-policy.sh topcoder1/attaxion_dev (the install PR itself touches .github/workflows/** so it WILL be in the risk-tier list — expected behavior; manual-merge that one)
  • After install lands, open a trivial test PR on a claude/* branch with no risk paths — verify auto-merge fires
  • Open a test PR touching infra/ — verify the workflow posts the sticky comment and does NOT enable auto-merge

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.7 (1M context) [email protected]

Auto-enables 'gh pr merge --auto --squash' on PRs detected as
Claude-authored (branch claude/*, Co-Authored-By: Claude trailer, or
'auto-merge' label) unless the diff touches risk-tier paths from the
global CLAUDE.md policy:

  - auth / login / session / oauth / sso
  - secrets / .env / keychain / credentials
  - migrations / *.sql
  - billing / payment / pricing / invoice
  - production infra (Dockerfile, .github/workflows, infra/, terraform/,
    pulumi/, deploy scripts)

Risk matches post a sticky comment and skip auto-merge — manual
click-merge still works. Branch protection (required Claude Review
check) still applies; this only flips the auto-merge toggle.

Pairs with new install-automerge-policy.sh in dotclaude.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
fi

- name: Enable auto-merge
if: steps.detect.outputs.claude_authored == '1' && steps.risk.outputs.risky != '1'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: risk-step failure silently enables auto-merge

When if: is specified with a custom expression, GitHub Actions drops the implicit success() guard. If the risk step fails for any reason (network error, API rate limit, gh auth failure), steps.risk.outputs.risky is never written. '' != '1' evaluates to true, so this step fires — enabling auto-merge on a PR whose risk tier was never validated.

Suggested change
if: steps.detect.outputs.claude_authored == '1' && steps.risk.outputs.risky != '1'
if: success() && steps.detect.outputs.claude_authored == '1' && steps.risk.outputs.risky != '1'

Same fix needed on line 156 for the "Comment + skip" step's condition.

Comment on lines +164 to +165
existing=$(gh api "/repos/${{ github.repository }}/issues/$PR/comments" \
--jq ".[] | select(.body | contains(\"$marker\")) | .id" | head -1)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition: TOCTOU between read and write

If this workflow fires twice concurrently (e.g., opened + labeled events in quick succession), both runs fetch the comment list, both find no existing marker comment, and both POST a new one — producing two identical sticky comments. This is minor (cosmetic noise, not a security issue), but worth noting if the calling workflow triggers on multiple event types.

@claude

claude Bot commented May 2, 2026

Copy link
Copy Markdown

Flagged 2 issues inline — see comments. One real security bug (risk-step failure silently enables auto-merge due to missing success() guard); one minor race condition in comment deduplication.

@topcoder1
topcoder1 merged commit cde21b0 into main May 2, 2026
4 checks passed
@topcoder1
topcoder1 deleted the feat/claude-author-automerge branch May 2, 2026 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant