feat(auto-rebase): trigger Claude agentic rebase on merge conflict#280
feat(auto-rebase): trigger Claude agentic rebase on merge conflict#280don-petry wants to merge 7 commits into
Conversation
When auto-rebase-reusable.yml encounters a conflict it cannot resolve via the merge strategy, it already posts a sentinel comment (<!-- auto-rebase-conflict -->). This commit wires that sentinel to a new claude-rebase job that fires when github-actions[bot] posts that comment on a PR, giving Claude a chance to rebase the branch and resolve conflicts before escalating to a human. Changes: - auto-rebase-reusable.yml: update conflict comment to mention Claude will attempt an automatic rebase; switch manual instructions from merge to rebase (git rebase --continue / --force-with-lease) - claude-code-reusable.yml: add claude-rebase job triggered by the <!-- auto-rebase-conflict --> sentinel; Claude checks out the branch, rebases onto the base branch, resolves conflicts using best-effort judgment (prefer main's side for superseded pins, keep PR's side for novel changes), pushes, and posts a summary; aborts cleanly if application-code conflicts require human judgment Closes #279 Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
Note Gemini is unable to generate a review for this pull request due to the file types involved not being currently supported. |
📝 WalkthroughWalkthroughThis PR implements an agentic conflict resolution system for auto-rebasing pull requests. It adds a helper script with idempotent handlers for permission and merge-conflict errors, introduces a Claude-powered rebase job triggered by repository dispatch events, delivers comprehensive shell test infrastructure with gh CLI stubs, and wires everything together via workflow updates and a new CI harness. ChangesAgentic auto-rebase conflict resolution
Sequence Diagram(s)sequenceDiagram
participant PR as Pull Request
participant AutoRebase as auto-rebase-reusable
participant Script as scripts/auto-rebase.sh
participant GitHubAPI as GitHub API
participant ClaudeJob as claude-rebase job
participant Claude as Claude Code
PR->>AutoRebase: Run auto-rebase workflow
AutoRebase->>Script: Source and call handlers
Script->>GitHubAPI: git merge (merge strategy)
alt Merge conflict
GitHubAPI-->>Script: HTTP 422 error
Script->>GitHubAPI: GET PR comments (check sentinel)
alt Sentinel absent
Script->>GitHubAPI: repository_dispatch (claude-rebase)
GitHubAPI-->>ClaudeJob: Trigger on dispatch event
Script->>GitHubAPI: POST conflict comment (with sentinel)
ClaudeJob->>Claude: Invoke with rebase prompt
Claude->>GitHubAPI: git rebase, resolve conflicts
Claude->>GitHubAPI: git push --force-with-lease
Claude->>GitHubAPI: POST result comment
else Sentinel present
Script-->>Script: Skip (already dispatched)
end
else Merge succeeds
GitHubAPI-->>AutoRebase: Success
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ee5f5b6c7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This PR adds an agentic fallback for auto-rebase conflicts: when the merge-based branch update hits a conflict, the workflow posts a sentinel comment intended to trigger Claude to attempt a rebase and conflict resolution.
Changes:
- Updates the auto-rebase conflict comment to mention Claude’s automatic rebase attempt and rebase-based manual fallback.
- Adds a
claude-rebasejob to the reusable Claude workflow for sentinel-triggered conflict resolution. - Provides Claude with instructions for checkout, rebase, conflict handling, force-with-lease push, and summary posting.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
.github/workflows/auto-rebase-reusable.yml |
Updates conflict handling comments and sentinel-trigger messaging. |
.github/workflows/claude-code-reusable.yml |
Adds the new Claude rebase automation job and prompt. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ncy, git identity, tests Addresses all issues raised by Codex and Copilot on PR #280: P1 — GITHUB_TOKEN events don't trigger issue_comment workflows: Switch from comment-based trigger to repository_dispatch (one of only two event types GITHUB_TOKEN IS permitted to trigger workflow runs for). auto-rebase-reusable.yml fires `gh api .../dispatches` with event_type claude-rebase; claude.yml adds `repository_dispatch: types: [claude-rebase]`; claude-code-reusable.yml claude-rebase job triggers on repository_dispatch. P2 — Idempotency sentinel too broad (one-shot per PR): Replace `<!-- auto-rebase-conflict -->` with a SHA-keyed sentinel `<!-- auto-rebase-conflict:{base_sha} -->` where base_sha is the first 8 chars of the base branch HEAD. A new merge to the base branch changes the SHA, resetting the gate and giving Claude another attempt. P2 — Missing git identity before rebase --continue: Add `git config user.name/user.email` to the claude-rebase prompt before any rebase operations. Copilot — git rebase --continue called per-file instead of per-commit: Clarify in the prompt that all conflicted files for the current commit must be staged first, then `git rebase --continue` run once per commit. Testability: Extract conflict-handling logic from inline YAML to scripts/auto-rebase.sh. Add 12-test BATS suite covering both handle_permissions_block and handle_conflict (sentinel presence, SHA-keyed idempotency, dispatch payload fields, comment body content, fallback instructions). Add .github/workflows/auto-rebase-tests.yml to run ShellCheck + bats on every PR touching the auto-rebase files. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Review feedback addressed (commit 75afe83)All 5 review threads have been resolved:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 75afe833d1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@don-petry assigned me as reviewer — starting a fresh review now. Results will appear in a few minutes. |
|
@donpetry-bot please review |
|
@don-petry I'm on it — starting a fresh review now. Results will appear in a few minutes. |
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: MEDIUM
Reviewed commit: de97a136428c17833f4374de399f41dd297fbc02
Review mode: triage-approved (single reviewer)
Summary
Adds an agentic auto-rebase fallback: when the merge strategy hits a conflict, auto-rebase-reusable.yml fires a repository_dispatch event (event_type: claude-rebase) which triggers a new claude-rebase job in claude-code-reusable.yml. Claude checks out the branch, rebases onto the base branch, resolves conflicts with bounded judgment, and pushes with --force-with-lease.
The second commit (75afe83) addressed all prior AI-reviewer feedback (Codex P1/P2, Copilot) — see below. Triage's low-risk classification is correct; the implementation has appropriate safeguards.
Linked issue analysis
Closes #279 (feat(auto-rebase): assign conflicting PRs to Claude for agentic rebase). All acceptance criteria are addressed:
- ✅ Conflict comment now notes Claude will attempt the rebase
- ✅ New
claude-rebasejob dispatched viarepository_dispatch(the GITHUB_TOKEN-triggerable path) - ✅ Clear abort + summary comment path for unresolvable conflicts
- ✅ Idempotency preserved via SHA-keyed sentinel (
<!-- auto-rebase-conflict:{base_sha} -->)
Findings
Prior review feedback resolved (commit 75afe83):
- Codex P1 —
issue_commentevents fromGITHUB_TOKENdon't trigger workflows. Fixed by switching torepository_dispatch, which is one of only two event typesGITHUB_TOKENis permitted to trigger. - Codex P2 — Sentinel was one-shot per PR lifetime. Fixed by SHA-keying the sentinel to the base-branch HEAD; each new base merge resets the gate.
- Codex P2 — Missing git identity before
rebase --continue. Addedgit config user.name/user.emailto the Claude prompt. - Copilot —
git rebase --continueper-file instead of per-commit. Clarified in the prompt: stage all files for the commit, then--continueonce. - Test gap — Extracted conflict-handling logic to
scripts/auto-rebase.sh; added 12-test BATS suite + ShellCheck gate (.github/workflows/auto-rebase-tests.yml).
Security posture (the reason this stays MEDIUM, not HIGH):
- All third-party actions are pinned to commit SHA (
actions/checkout@de0fac2e…,anthropics/claude-code-action@476e359e…). claude-rebasejob uses a restricted--allowedToolsallowlist (Bash(git*:*),Bash(gh pr ...),Bash(gh api:*),Edit,Write) rather than unrestricted tool use.- Permissions on the new job are scoped (
contents: write,pull-requests: write,id-token: write,issues: write, plus read-onlyactions/checks). - Concurrency group
claude-rebase-${pr_number}withcancel-in-progress: trueprevents stacking. - 30-minute timeout caps blast radius.
- Push uses
--force-with-lease, not raw--force. - Rebase strategy explicitly aborts on complex application-code conflicts and falls back to a human-readable comment.
repository_dispatchpayload is constructed from internal PR metadata (PR number, head ref, base branch), not from untrusted user input.
Minor observations (non-blocking):
- The
--allowedToolspatternBash(git*:*)is broad — it matches any subcommand ofgitwith any arguments. Given the scoped checkout and--force-with-leasepush, the realistic blast radius is bounded to the PR branch, but tightening to specific git subcommands (git rebase:*,git push:*,git checkout:*,git add:*,git config:*,git fetch:*) would be a defense-in-depth win for a future PR. secrets.GH_PAT_WORKFLOWS || github.tokenfallback for checkout/push: when the PAT is absent, force-pushing to a PR branch that touches.github/workflows/will fail with the sameworkflowspermission error the original workflow already handles upstream. That's the right failure mode (loud, not silent), and the manual-rebase comment path is preserved.
CI status
All checks green:
- ✅ CodeQL — Analyze (actions)
- ✅ CodeQL (aggregate)
- ✅ CodeRabbit (status + approving review on this SHA)
- ✅ SonarQube Quality Gate (0 new issues, 0 hotspots)
- ✅ pr-review-mention / handle-mention
No unresolved review threads from human reviewers. Codex left automated suggestions on the prior SHA that have been addressed.
Reviewed automatically by the PR-review agent (single-reviewer mode: opus 4.7). Reply if you need a human review.
P1 — script not found when reusable is called from other repos: The checkout in auto-rebase-reusable.yml checked out the CALLER's repository, so scripts/auto-rebase.sh was only present when the .github repo called itself. Fix: always checkout petry-projects/.github (the canonical home of the scripts) regardless of which repo invokes the reusable. P2 — sentinel posted before dispatch, blocking retries on dispatch failure: Reorder handle_conflict to fire repository_dispatch first, post the SHA-keyed sentinel comment only after dispatch succeeds. If dispatch fails the comment is never written, so the next auto-rebase run for the same base SHA can retry cleanly. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
a8b49e9
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a8b49e94fa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| gh api "repos/$REPO/dispatches" \ | ||
| -X POST \ | ||
| -f event_type=claude-rebase \ | ||
| -F "client_payload[pr_number]=$pr_number" \ | ||
| -F "client_payload[head_ref]=$head_ref" \ | ||
| -F "client_payload[base_branch]=$base_branch" |
There was a problem hiding this comment.
Verify the Claude listener before marking dispatch handled
For downstream repos that pick up the updated auto-rebase-reusable.yml@v1 but have not yet copied the updated local claude.yml stub with on.repository_dispatch, this API call can succeed while no Claude workflow is actually listening on the repo’s default branch; GitHub documents repository_dispatch runs only when the workflow file exists on the default branch. Because the sentinel comment is posted immediately after this and future runs skip the same base SHA, those conflicted PRs are left with “Claude has been dispatched” but no rebase attempt. Add a compatibility check/fallback or avoid writing the sentinel until a run is confirmed.
Useful? React with 👍 / 👎.
| - name: Checkout petry-projects/.github (for scripts) | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | ||
| with: | ||
| repository: petry-projects/.github | ||
| fetch-depth: 1 |
There was a problem hiding this comment.
Pin the helper checkout to the reusable ref
When a downstream repo invokes auto-rebase-reusable.yml@v1, this checkout does not specify ref, so the helper script is loaded from petry-projects/.github’s default branch rather than the same version as the reusable. I checked actions/checkout’s README: for a different repository, omitted ref “uses the default branch.” That bypasses the standards guarantee that @v1 insulates adopters from changes on main, so any future incompatible edit to scripts/auto-rebase.sh can break all pinned callers immediately; checkout the same tag/SHA as the reusable or vendor the script within the versioned workflow.
Useful? React with 👍 / 👎.
donpetry-bot
left a comment
There was a problem hiding this comment.
Automated review — APPROVED ✓
Risk: MEDIUM
Reviewed commit: 55877e1f580426cfd3a3857c5ea444c407f50912
Review mode: triage-approved (single reviewer, confirmation pass)
Summary
Confirmation review on a triage-approved PR. The prior bot review approved de97a13; two commits since address feedback from a second Codex review and a merge brings in orthogonal compliance changes from PR #277. The fixes are surgical, the security posture is unchanged (and arguably tightened), and CodeRabbit explicitly approved this exact SHA. Approving.
Linked issue analysis
Closes #279 (feat(auto-rebase): assign conflicting PRs to Claude for agentic rebase). All acceptance criteria remain addressed; the new commits don't alter the user-visible contract — they just fix two correctness/operability bugs uncovered by Codex on the prior SHA.
Findings — what changed since the prior approval (de97a13)
1. auto-rebase-reusable.yml — checkout the canonical scripts repo (commit a8b49e9)
The checkout step previously used the default (caller's) repository, so scripts/auto-rebase.sh was only present when .github called itself. Fixed by setting repository: petry-projects/.github on actions/checkout. This is correct: the script's interactions with the caller's PR go through gh CLI against $REPO (= github.repository, the caller), so the caller's working tree isn't needed in this job.
2. scripts/auto-rebase.sh — dispatch before sentinel (commit a8b49e9)
handle_conflict() now fires repository_dispatch first and posts the SHA-keyed sentinel comment only after dispatch succeeds. Previously, a failed dispatch would still leave the sentinel in place, permanently blocking retries for the current base SHA. The new order trades that failure mode for the much rarer case of a successful dispatch followed by a failed comment post — which would result in (at most) one duplicate Claude run on the next auto-rebase, bounded by the existing claude-rebase-${pr_number} concurrency group with cancel-in-progress: true. Net win.
3. Merge from main (commit 55877e1)
Merges PR #277 (gitleaks secret-scan job using SHA-pinned binary install with checksum verification, dtolnay SHA pin, root .gitleaks.toml). Orthogonal to this PR's scope; no interaction with the auto-rebase logic.
Security posture (still MEDIUM, not HIGH):
- All third-party actions SHA-pinned (unchanged).
claude-rebasejob retains its restricted--allowedToolsallowlist (unchanged).- Scoped job permissions,
--force-with-leasepush, 30-min timeout, SHA-keyed sentinel idempotency, explicit abort-on-complex-conflict path — all unchanged. - The new explicit
repository: petry-projects/.githubcheckout pins the script source to a trusted location, which is a small defense-in-depth improvement over relying on caller-controlled checkout content.
Carry-forward observation (non-blocking, same as prior review):
The Bash(git*:*) allowlist pattern is still broad. Tightening to specific git subcommands would be a future-PR defense-in-depth win, but the blast radius is bounded by the scoped checkout and force-with-lease, so this stays non-blocking.
CI status
All checks green on 55877e1:
- ✅ CodeQL — Analyze (actions)
- ✅ CodeQL (aggregate)
- ✅ CodeRabbit (status + APPROVED review on this SHA)
- ✅ SonarQube Quality Gate (0 new issues, 0 hotspots)
No unresolved human-reviewer threads. Codex's automated suggestions on prior SHAs have been addressed in a8b49e9.
Reviewed automatically by the PR-review agent (single-reviewer mode: opus 4.7). Reply if you need a human review.
|
|
@donpetry-bot please review and approve — all CI checks are passing |
|
@don-petry I'm on it — starting a fresh review now. Results will appear in a few minutes. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a1db44f317
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| gh api "repos/$REPO/dispatches" \ | ||
| -X POST \ |
There was a problem hiding this comment.
Continue after a failed Claude dispatch
If the repository_dispatch request fails for one conflicted PR due to a transient API/token problem, this unguarded gh api runs under the sourced script's set -e, so the entire auto-rebase step exits instead of moving on to the remaining PRs. That regresses the workflow's per-PR graceful handling: a single dispatch failure can leave later behind branches unprocessed until another push or manual run.
Useful? React with 👍 / 👎.
| if: >- | ||
| github.event_name == 'repository_dispatch' && | ||
| github.event.action == 'claude-rebase' |
There was a problem hiding this comment.
Validate dispatch payload before running privileged rebase
This privileged job now trusts any repository_dispatch payload with action claude-rebase, but it never re-checks that the referenced PR is the same-repo, non-Dependabot PR that auto-rebase is supposed to handle. If another automation or a maintainer token dispatches this event with a fork PR number, the job still gets write permissions and inherited secrets and then instructs Claude to gh pr checkout and rebase that PR; add the same head-repo/bot gate used by the auto-rebase producer before invoking Claude.
Useful? React with 👍 / 👎.
|
Auto-rebase failed — merge conflict — this branch has conflicts with Claude will attempt to resolve this automatically. If it cannot, a follow-up comment will explain what needs manual attention. To resolve manually instead: |
|
Auto-rebase failed — merge conflict — this branch has conflicts with Claude will attempt to resolve this automatically. If it cannot, a follow-up comment will explain what needs manual attention. To resolve manually instead: |
Auto-rebase: Manual Resolution RequiredThe agentic rebase could not be completed automatically. Here's what was found: Conflicting filesThe PR branch diverges from
Why automatic resolution was skippedThese are application-logic conflicts, not simple action-pin version bumps. The PR and Manual resolution stepsgit fetch origin
git rebase origin/main
# Resolve conflicts in each file listed above.
# For each file: keep the PR's newer logic (repository_dispatch trigger,
# scripts/auto-rebase.sh sourcing) and incorporate any relevant changes
# from main's 761dd4a commit.
git add .github/workflows/auto-rebase-reusable.yml
git add .github/workflows/claude-code-reusable.yml
git add .github/workflows/claude.yml
git add standards/ci-standards.md
git add standards/github-settings.md
git add standards/workflows/claude.yml
git rebase --continue
git push --force-with-leaseTip: The PR branch version of |
The claude.yml trigger change (adding repository_dispatch: [claude-rebase]) causes the expected OIDC validation failure on any PR that modifies claude.yml — the Anthropic token endpoint requires the file to be byte-for-byte identical to the default branch. The claude-code-reusable.yml job (claude-rebase) receives the event correctly as long as the CALLING repo's claude.yml declares the trigger. That update to each repo's thin stub is a follow-up compliance sweep, not a requirement for the reusable to work from .github itself. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
836f546
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/auto-rebase-tests.yml:
- Around line 32-33: The concurrency group currently uses the commit SHA (group:
auto-rebase-tests-${{ github.ref }}-${{ github.sha }}), which makes each run
unique and prevents cancel-in-progress from working; update the group key to be
stable per branch/PR by removing `${{ github.sha }}` and using a ref/PR-scoped
value instead (for example use `${{ github.ref }}` or for pull requests `${{
github.event.pull_request.number }}`/`${{ github.head_ref }}`) so that
cancel-in-progress: true will actually cancel previous runs for the same
branch/PR.
In `@test/workflows/auto-rebase/helpers/setup.bash`:
- Around line 25-26: The gh-call stub ar_install_gh_stub currently logs args
space-separated though the comment says argv should be tab-separated; update the
stub so it writes arguments to $AR_GH_LOG separated by tabs (use a tab delimiter
when joining "$@") and make the same change for the other gh-call stubs in this
file (the ones around the earlier 42-43 and later 67-68 blocks) so all argv
logging uses tab separation to preserve argument boundaries.
- Line 84: The ar_gh_call_count helper uses grep -c "$pattern" which treats
pattern as a regex; change it to fixed-string matching so special chars in
$pattern don't get interpreted. Update the invocation that sets count (the line
using count=$(grep -c "$pattern" "${AR_GH_LOG:-/dev/null}" 2>/dev/null) ||
count=0) to use grep --fixed-strings (or -F) and -- to end options, keeping the
same redirection and fallback so it still assigns count and handles missing
AR_GH_LOG correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 43ed7723-f550-4b58-b1b1-d5314adeed23
📒 Files selected for processing (6)
.github/workflows/auto-rebase-reusable.yml.github/workflows/auto-rebase-tests.yml.github/workflows/claude-code-reusable.ymlscripts/auto-rebase.shtest/workflows/auto-rebase/auto-rebase.batstest/workflows/auto-rebase/helpers/setup.bash
| group: auto-rebase-tests-${{ github.ref }}-${{ github.sha }} | ||
| cancel-in-progress: true |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | ⚡ Quick win
Make concurrency key branch/PR-scoped (not SHA-scoped).
Using ${{ github.sha }} in the group makes each run unique, so cancel-in-progress: true won’t cancel older runs after new commits. Use a stable key per ref/PR instead.
Proposed fix
concurrency:
- group: auto-rebase-tests-${{ github.ref }}-${{ github.sha }}
+ group: auto-rebase-tests-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| group: auto-rebase-tests-${{ github.ref }}-${{ github.sha }} | |
| cancel-in-progress: true | |
| concurrency: | |
| group: auto-rebase-tests-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/auto-rebase-tests.yml around lines 32 - 33, The
concurrency group currently uses the commit SHA (group: auto-rebase-tests-${{
github.ref }}-${{ github.sha }}), which makes each run unique and prevents
cancel-in-progress from working; update the group key to be stable per branch/PR
by removing `${{ github.sha }}` and using a ref/PR-scoped value instead (for
example use `${{ github.ref }}` or for pull requests `${{
github.event.pull_request.number }}`/`${{ github.head_ref }}`) so that
cancel-in-progress: true will actually cancel previous runs for the same
branch/PR.
| # The stub logs each invocation to $AR_GH_LOG (one line per call, argv tab-separated). | ||
| ar_install_gh_stub() { |
There was a problem hiding this comment.
Align gh-call log format with the documented contract.
The comment says argv is tab-separated, but the stub writes space-separated args. This can blur argument boundaries and weaken assertions for arguments containing spaces.
Proposed fix
-# The stub logs each invocation to $AR_GH_LOG (one line per call, argv tab-separated).
+# The stub logs each invocation to $AR_GH_LOG (one line per call, argv tab-separated).
-printf '%s ' "\$@" >> "${AR_TMP}/gh.log"
+printf '%s\t' "\$@" >> "${AR_TMP}/gh.log"
printf '\n' >> "${AR_TMP}/gh.log"
-printf '%s ' "\$@" >> "${AR_TMP}/gh.log"
+printf '%s\t' "\$@" >> "${AR_TMP}/gh.log"
printf '\n' >> "${AR_TMP}/gh.log"Also applies to: 42-43, 67-68
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/workflows/auto-rebase/helpers/setup.bash` around lines 25 - 26, The
gh-call stub ar_install_gh_stub currently logs args space-separated though the
comment says argv should be tab-separated; update the stub so it writes
arguments to $AR_GH_LOG separated by tabs (use a tab delimiter when joining
"$@") and make the same change for the other gh-call stubs in this file (the
ones around the earlier 42-43 and later 67-68 blocks) so all argv logging uses
tab separation to preserve argument boundaries.
| local pattern="$1" | ||
| local count | ||
| # grep -c prints 0 even on no match; exit code 1 means no match (not error). | ||
| count=$(grep -c "$pattern" "${AR_GH_LOG:-/dev/null}" 2>/dev/null) || count=0 |
There was a problem hiding this comment.
Use fixed-string matching for call assertions.
ar_gh_call_count says “substring match,” but grep -c "$pattern" treats the pattern as regex. Patterns containing []()|* can miscount or fail unexpectedly.
Proposed fix
- count=$(grep -c "$pattern" "${AR_GH_LOG:-/dev/null}" 2>/dev/null) || count=0
+ count=$(grep -F -c -- "$pattern" "${AR_GH_LOG:-/dev/null}" 2>/dev/null) || count=0📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| count=$(grep -c "$pattern" "${AR_GH_LOG:-/dev/null}" 2>/dev/null) || count=0 | |
| count=$(grep -F -c -- "$pattern" "${AR_GH_LOG:-/dev/null}" 2>/dev/null) || count=0 |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@test/workflows/auto-rebase/helpers/setup.bash` at line 84, The
ar_gh_call_count helper uses grep -c "$pattern" which treats pattern as a regex;
change it to fixed-string matching so special chars in $pattern don't get
interpreted. Update the invocation that sets count (the line using count=$(grep
-c "$pattern" "${AR_GH_LOG:-/dev/null}" 2>/dev/null) || count=0) to use grep
--fixed-strings (or -F) and -- to end options, keeping the same redirection and
fallback so it still assigns count and handles missing AR_GH_LOG correctly.
|
Closing — the core feature (agentic Claude rebase fallback) was delivered via #281, which merged a more complete implementation (PAT-based sentinel, SHA-keyed delete-and-repost idempotency, semver version comparison in the prompt). PR #280's unique contribution was the test suite ( Follow-up: open a new PR that extracts #281's inline conflict-handling logic into |
Pull request was closed



Summary
auto-rebase-reusable.yml: when the merge strategy fails with a conflict, the existing sentinel comment (<!-- auto-rebase-conflict -->) now tells the author that Claude will attempt an automatic rebase. Manual fallback instructions are updated fromgit mergetogit rebase --continue / --force-with-lease.claude-code-reusable.yml: newclaude-rebasejob triggered byissue_commentevents wheregithub-actions[bot]posts a comment containing<!-- auto-rebase-conflict -->on a PR. Claude checks out the branch, rebases onto the base branch, resolves conflicts with best-effort judgment, pushes, and posts a result summary. Aborts cleanly if conflicts require human judgment.How the trigger works
The sentinel is idempotent — auto-rebase won't re-post it on subsequent runs, so Claude only gets one automatic attempt per conflict. If Claude's rebase also fails it posts a clear summary and a human takes over.
Conflict resolution strategy Claude uses
.gitignore, configTest plan
claude-rebasejob fires on that commentCloses #279
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes
New Features
Tests