pr-ship
PR Ship
End-to-end PR lifecycle shepherd: create PR → wait for CI → review → fix → merge. Single invocation, single PR.
Announce at start: "Using pr-ship skill to shepherd this PR from creation to merge."
Usage
/pr-ship [pr_number] [--no-auto-merge]
| Parameter | Default | Description |
|---|---|---|
pr_number |
none | Resume from an existing PR (skip creation) |
--no-auto-merge |
off | Require user confirmation before merge instead of auto-merge |
Session State
Track these values in conversation context throughout the session:
PR_NUMBER— current PR numberPHASE— current phase (create / ci-wait / review / fix / merge)RETRY_COUNT— CI failure + review fix retry counter (max 3, shared), initialized to 0AUTO_MERGE— true unless--no-auto-mergeis passedEMPTY_CI_COUNT— consecutive empty CI check counter (max 3), initialized to 0
Phase 0 — Create PR
Skip if pr_number is provided. When skipping, set PR_NUMBER from the argument and jump to Phase 1.
Parse arguments:
# Detect --no-auto-merge flag
AUTO_MERGE=true
if echo "$ARGUMENTS" | grep -q -- '--no-auto-merge'; then
AUTO_MERGE=false
fi
# Detect pr_number (first numeric argument)
PR_NUMBER=$(echo "$ARGUMENTS" | grep -oE '[0-9]+' | head -1)
If PR_NUMBER is set: set RETRY_COUNT = 0, EMPTY_CI_COUNT = 0, skip to Phase 1.
If PR_NUMBER is not set: invoke oss-pr to create the PR:
/oss-pr
After oss-pr completes, extract PR_NUMBER from the PR URL in its output. Set RETRY_COUNT = 0, EMPTY_CI_COUNT = 0.
Phase 1 — CI Wait
Check CI status:
gh pr view $PR_NUMBER --json statusCheckRollup \
--jq '.statusCheckRollup[] | {name: .name, status: .status, conclusion: .conclusion}'
Required jobs (same list as pr-review):
Code QualityUnit Tests (ubuntu-latest)Unit Tests (macos-14)Unit Tests (windows-2022)Coverage Testi18n-check
Informational exclusions: codecov/patch and codecov/project — always excluded from failure checks.
Decision Matrix
| CI Status | Action |
|---|---|
| All required jobs SUCCESS, no non-informational failures | → Phase 2 |
| Any required job QUEUED or IN_PROGRESS | ScheduleWakeup 270s, re-check |
statusCheckRollup empty (CI never triggered) |
Approve workflow (see below), ScheduleWakeup 270s |
| Any non-informational job FAILURE or CANCELLED | → CI Failure Handler |
Workflow Approval (CI not triggered)
HEAD_SHA=$(gh pr view $PR_NUMBER --json headRefOid --jq '.headRefOid')
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
RUN_IDS=$(gh api "repos/$REPO/actions/runs?head_sha=$HEAD_SHA&status=action_required" \
--jq '.workflow_runs[].id')
for RUN_ID in $RUN_IDS; do
gh run approve "$RUN_ID" --repo "$REPO"
done
Then EMPTY_CI_COUNT++ and ScheduleWakeup 270s to re-check. If EMPTY_CI_COUNT >= 3 (~13.5 minutes), abort:
CI 持续未触发(已等待约 13.5 分钟)。请检查仓库 CI 配置后重新调用
/pr-ship $PR_NUMBER。
CI Failure Handler
Step 1 — Check retry budget:
If RETRY_COUNT >= 3:
已达到最大重试次数 (3/3)。请手动检查 PR #$PR_NUMBER 后重新调用
/pr-ship $PR_NUMBER。
Exit.
Step 2 — Identify failures:
# Get failed job names
FAILED_JOBS=$(gh pr view $PR_NUMBER --json statusCheckRollup \
--jq '[.statusCheckRollup[] | select(.conclusion == "FAILURE" or .conclusion == "CANCELLED") | select(.name | test("^codecov/") | not) | .name] | join(", ")')
Report to user:
CI 失败:$FAILED_JOBS。正在尝试修复 ($RETRY_COUNT/3)...
Step 3 — Fetch failure details:
REPO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
# Find the failed run IDs
HEAD_SHA=$(gh pr view $PR_NUMBER --json headRefOid --jq '.headRefOid')
FAILED_RUN_IDS=$(gh api "repos/$REPO/actions/runs?head_sha=$HEAD_SHA&status=failure" \
--jq '.workflow_runs[].id')
# Get logs for each failed run
for RUN_ID in $FAILED_RUN_IDS; do
gh run view "$RUN_ID" --repo "$REPO" --log-failed 2>/dev/null | tail -100
done
Step 4 — Fix in worktree:
REPO_ROOT=$(git rev-parse --show-toplevel)
WORKTREE_DIR="/tmp/aionui-ship-${PR_NUMBER}"
HEAD_BRANCH=$(gh pr view $PR_NUMBER --json headRefName --jq '.headRefName')
# Clean up stale worktree
git worktree remove "$WORKTREE_DIR" --force 2>/dev/null || true
# Create worktree
git fetch origin "$HEAD_BRANCH"
git worktree add "$WORKTREE_DIR" "origin/$HEAD_BRANCH" --detach
# Symlink node_modules
ln -s "$REPO_ROOT/node_modules" "$WORKTREE_DIR/node_modules"
Fix only CI-reported errors (lint errors, type errors, test failures) in the worktree. No refactoring, no scope expansion.
After fixing, run local quality gate:
cd "$WORKTREE_DIR"
bun run lint:fix
bun run format
bunx tsc --noEmit
bun run test
Step 5 — Commit and push:
cd "$WORKTREE_DIR"
git add -u
git commit -m "fix(<scope>): resolve CI failures"
git push origin HEAD:$HEAD_BRANCH
No AI signature in commits.
Step 6 — Cleanup worktree:
cd "$REPO_ROOT"
git worktree remove "$WORKTREE_DIR" --force 2>/dev/null || true
Step 7 — Increment and loop:
RETRY_COUNT++. ScheduleWakeup 270s → re-enter Phase 1.
Phase 2 — Review
Invoke pr-review in interactive mode, passing the PR number explicitly:
/pr-review $PR_NUMBER
(No --automation flag — this is an interactive session.)
Decision based on review conclusion
| Review Conclusion | Action |
|---|---|
| ✅ APPROVED (including LOW-only) | → Phase 4 |
| ⚠️ CONDITIONAL | → Phase 3 |
| ❌ REJECTED | → Phase 3 (pr-fix triage decides if auto-fixable) |
Phase 3 — Fix
Check retry budget first:
If RETRY_COUNT >= 3:
已达到最大重试次数 (3/3)。请手动检查 PR #$PR_NUMBER 后重新调用
/pr-ship $PR_NUMBER。
Exit.
Invoke pr-fix in interactive mode, passing the PR number explicitly:
/pr-fix $PR_NUMBER
(No --automation flag.)
After pr-fix completes
Fix pushed successfully: RETRY_COUNT++. ScheduleWakeup 270s → back to Phase 1 (wait for CI on new commit).
Fix aborted (all issues dismissed, or user rejected CRITICAL dismissal):
pr-fix 未产生修复。是否继续看护此 PR?(yes/no)
- yes → back to Phase 1 (CI may already be passing)
- no → exit, output PR URL for manual handling
Phase 4 — Merge
AUTO_MERGE = true (default)
gh pr merge $PR_NUMBER --squash --auto
Output:
✅ PR #$PR_NUMBER 已设置 auto-merge,CI 通过后将自动合并。
AUTO_MERGE = false (--no-auto-merge)
Display summary:
=== PR #$PR_NUMBER 就绪 ===
标题: <title>
变更: +<additions> / -<deletions> (<file_count> files)
Review: <conclusion>
CI: 全部通过
输入 merge 确认合并,或 abort 放弃。
Fetch summary data:
gh pr view $PR_NUMBER --json title,additions,deletions,changedFiles \
--jq '{title: .title, additions: .additions, deletions: .deletions, files: .changedFiles}'
- User says merge →
gh pr merge $PR_NUMBER --squash→ output✅ PR #$PR_NUMBER 已合并。 - User says abort → exit, output PR URL
ScheduleWakeup Integration
This skill uses /loop dynamic mode for CI waiting. Each ScheduleWakeup call:
ScheduleWakeup(
delaySeconds: 270,
reason: "waiting for CI on PR #$PR_NUMBER (check N)",
prompt: "/pr-ship $PR_NUMBER"
)
Interval: 270s uniformly (under 5-min prompt cache TTL).
When to call ScheduleWakeup:
- CI is still running (QUEUED/IN_PROGRESS)
- Just approved a workflow run
- Just pushed a CI fix
- Just pushed a pr-fix commit
When NOT to call ScheduleWakeup:
- CI has completed (pass or fail with actionable errors)
- During review (Phase 2) or fix (Phase 3) execution
- After merge (Phase 4)
Mandatory Rules
- No AI signature — no
Co-Authored-By, noGenerated within any commit or comment - Retry limit = 3 — hard cap, shared between CI fixes and review fixes
- Fix scope discipline — CI fixes target only CI-reported errors; review fixes go through pr-fix
- No label pollution — pr-ship does not set any
bot:*labels - ScheduleWakeup only for CI wait — never during review or fix execution
- REPO detection at runtime —
gh repo view --json nameWithOwner --jq '.nameWithOwner' - Worktree path — always
/tmp/aionui-ship-<PR_NUMBER>(distinct from pr-automation's/tmp/aionui-pr-*and pr-verify's/tmp/aionui-verify-*) - Worktree cleanup — always remove worktree after CI fix, even on failure
Quick Reference
0. Parse args: pr_number? --no-auto-merge?
1. Phase 0: /oss-pr (skip if pr_number given)
2. Phase 1: CI wait loop
- check statusCheckRollup
- passing -> Phase 2
- running -> ScheduleWakeup 270s
- not triggered -> approve workflow + ScheduleWakeup 270s
- failed -> retry_count < 3? fix + push + ScheduleWakeup 270s : abort
3. Phase 2: /pr-review (interactive)
- APPROVED -> Phase 4
- CONDITIONAL/REJECTED -> Phase 3
4. Phase 3: /pr-fix (interactive)
- pushed -> retry_count++, back to Phase 1
- aborted -> ask user
5. Phase 4: merge
- default: gh pr merge --squash --auto
- --no-auto-merge: confirm then gh pr merge --squash
More from iofficeai/aionui
pptx
Presentation creation, editing, and analysis. When Claude needs to work with presentations (.pptx files) for: (1) Creating new presentations, (2) Modifying or editing content, (3) Working with layouts, (4) Adding comments or speaker notes, or any other presentation tasks
108docx
Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction. When Claude needs to work with professional documents (.docx files) for: (1) Creating new documents, (2) Modifying or editing content, (3) Working with tracked changes, (4) Adding comments, or any other document tasks
102xiaohongshu-recruiter
用于在小红书上发布高质量的 AI 相关岗位招聘帖子。包含自动生成极客风格的招聘封面图和详情图,并提供自动化发布脚本。当用户需要发布招聘信息、寻找 Agent 设计师或其他 AI 领域人才时使用。
68xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
67i18n
|
65openclaw-setup
OpenClaw usage expert: Helps you install, deploy, configure, and use OpenClaw personal AI assistant. Can diagnose issues, create bots, execute automated tasks, etc. Use when users need to install OpenClaw, configure Gateway, set up Channels, create Agents, troubleshoot issues, or perform OpenClaw-related operations.
63