github-workflows/skills/rebase-pr/SKILL.md
Local rebase-merge workflow for pull requests with signed commits
npx skillsauth add jacobpevans/claude-code-plugins rebase-prInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Merge a PR using local git rebase + signed commits + git push origin main.
gh pr merge --rebase cannot sign commits. Local rebase with commit.gpgsign=true
signs every rebased commit. Pushing main directly auto-closes the PR.
MANDATORY FIRST STEP: Spawn a Haiku subagent using the Agent tool with
mode: "bypassPermissions". Pass all content starting from Prerequisite: Validate Rulesets
through end-of-document as the agent prompt; include the current branch name and PR number.
Do not execute any steps yourself — the subagent runs the complete workflow autonomously with
all permissions auto-accepted.
If the Haiku subagent cannot be spawned, becomes unavailable, or encounters an unrecoverable error while running this workflow, clearly report the failure to the user and ask whether to (a) retry spawning the subagent or (b) proceed manually by following the remaining steps of this document together step-by-step.
Before anything else, check the all-branches ruleset. Replace <OWNER> and <REPO> before running:
gh api repos/<OWNER>/<REPO>/rulesets \
--jq '.[] | select(.conditions.ref_name.include[] == "~ALL") | .rules[].type'
If any of these appear → ABORT with the message shown:
| Rule type | Message |
|-----------|---------|
| non_fast_forward | "Remove from all-branches ruleset. Feature branches need force-push after rebase. Keep on main-only." |
| required_linear_history | "Remove from all-branches ruleset. Keep on main-only." |
| pull_request | "Remove from all-branches ruleset. Keep on main-only." |
| required_status_checks | "Remove from all-branches ruleset. Keep on main-only." |
| code_scanning | "Remove from all-branches ruleset. Keep on main-only." |
Only required_signatures belongs on all-branches.
Run the canonical PR-readiness gate from /gh-cli-patterns against
<PR_NUMBER>. Replace <OWNER>, <REPO>, <PR_NUMBER> per the placeholder convention in
that skill.
Abort if any fail:
| Field | Must be | Abort message |
|-------|---------|---------------|
| state | OPEN | "PR is not open — run /finalize-pr to fix" |
| mergeable | MERGEABLE | "PR has merge conflicts — run /finalize-pr to fix" |
| mergeStateStatus | CLEAN or HAS_HOOKS | "PR merge state is {value} — run /finalize-pr to fix" |
| isDraft | false | "PR is a draft — mark ready first, then run /finalize-pr" |
| reviewDecision | APPROVED or null | "PR needs approval — run /finalize-pr to fix" |
| statusCheckRollup.state | SUCCESS | "CI is not passing: {state} — run /finalize-pr to fix" |
| All reviewThreads.isResolved | true | "Unresolved review threads — run /finalize-pr to fix" |
| reviewThreads.pageInfo.hasNextPage | false | ">100 threads — paginate and re-verify" |
git fetch origin --force main
git pull origin main
For remote-only branches (Renovate, Dependabot, etc.):
# NEVER use FETCH_HEAD — always create from origin/{branch}
git fetch origin --force {branch}
git branch {branch} origin/{branch}
Create worktree and rebase:
git worktree add ../{worktree-path} {branch} # from main/
cd ../{worktree-path}
git rebase origin/main
git log --oneline origin/main..HEAD # verify commits are ahead
Replace <PR_NUMBER> before running:
git push --force-with-lease origin {branch}
gh pr checks <PR_NUMBER> --watch --interval 15
Do NOT proceed until all checks pass.
If force-with-lease fails on a bot branch (no upstream tracking):
git branch --set-upstream-to=origin/{branch} {branch}
git push --force-with-lease origin {branch}
cd ../main
git merge-base --is-ancestor origin/main {branch} # verify FF is possible; exit 0 = yes
git merge --ff-only {branch}
If merge-base --is-ancestor exits non-zero, main moved since rebase — go back to Step 2.
git push origin main
If rejected with "Code scanning waiting". Replace <PR_NUMBER> before running:
gh pr checks <PR_NUMBER> --watch --interval 15
git push origin main # retry after checks pass
Verify merged. Replace <PR_NUMBER> before running:
gh pr view <PR_NUMBER> --json state --jq '.state' # expect: MERGED
git worktree remove ../{worktree-path} # from main/
git branch -d {branch} # use -D only after confirming state=MERGED
git push origin --delete {branch}
git worktree prune
gh pr merge — GitHub cannot sign rebase commitsgit push --force origin main — only force-push feature branchesFETCH_HEAD — use origin/{branch}git branch -D without first confirming state=MERGED/finalize-prRebase conflicts:
# git rebase pauses and lists conflicted files
git status # see conflicted files
# edit files to resolve
git add {conflicted-files}
git rebase --continue
Push to main rejected (code scanning):
Wait for CI with gh pr checks <PR_NUMBER> --watch --interval 15, then retry push.
PR already merged: Skip Steps 1–6. Go directly to Step 7 cleanup.
merge-base --is-ancestor exits non-zero: Main moved while you were waiting for CI. Return to Step 2, re-sync main, re-fetch branch, re-rebase, force-push again, wait for CI, then retry merge.
Detection: git push fails, hook output shows "files were modified by this hook"
Action: Commit the auto-fixed files and retry the push:
git add -A
git commit -m "style: apply pre-push hook auto-fixes"
git push --force-with-lease origin {branch}
This commonly occurs with release-please CHANGELOG.md entries that don't conform to markdownlint rules.
documentation
Use when editing GitHub Actions workflow files (.github/workflows/*.yml) in JacobPEvans repos. Documents when to target self-hosted RunsOn runners vs GitHub-hosted runners, the v3 label catalog used across the org, the required github.run_id segment, and the GitHub App allowlist prereq.
testing
Check PR merge readiness, sync local repo, cleanup stale worktrees; optional cross-repo sweep and stale-branch prune modes
tools
Canonical reference for all gh CLI command shapes used by skills in this plugin. Defines the placeholder convention, allowed --json fields, GraphQL fallback rules, -f/-F/--raw-field flag semantics, the PR-readiness gate, code-scanning alert query, review-thread fetch/count/resolve mutations, and heredoc bodies. Prevents Unknown JSON field errors and divergent query shapes.
tools
Analyze current Claude Code session token usage via Splunk. Shows per-model, per-tool, and subagent token breakdown with cache efficiency metrics.