Skip to main content
ClaudeWave
Skill28.2k estrellas del repoactualizado today

pr-ship

pr-ship is a continuous integration skill that automates the entire pull request lifecycle from creation through merge. It creates a new PR using oss-pr, monitors CI status checks, requests code review, applies fixes based on feedback, and merges the PR when ready. Use this skill to shepherd a single PR from start to finish with minimal manual intervention, optionally requiring user confirmation before the final merge step.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/iOfficeAI/AionUi /tmp/pr-ship && cp -r /tmp/pr-ship/.claude/skills/pr-ship ~/.claude/skills/pr-ship
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

SKILL.md

# 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 number
- `PHASE` — current phase (create / ci-wait / review / fix / merge)
- `RETRY_COUNT` — CI failure + review fix retry counter (max 3, shared), initialized to 0
- `AUTO_MERGE` — true unless `--no-auto-merge` is passed
- `EMPTY_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:**

```bash
# 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:

```bash
gh pr view $PR_NUMBER --json statusCheckRollup \
  --jq '.statusCheckRollup[] | {name: .name, status: .status, conclusion: .conclusion}'
```

**Required jobs** (same list as pr-review):

- `Code Quality`
- `Unit Tests (ubuntu-latest)`
- `Unit Tests (macos-14)`
- `Unit Tests (windows-2022)`
- `Coverage Test`
- `i18n-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)

```bash
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:**

```bash
# 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:**

```bash
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:**

```bash
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:

```bash
cd "$WORKTREE_DIR"
bun run lint:fix
bun run format
bunx tsc --noEmit
bun run test
```

**Step 5 — Commit and push:**

```bash
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:**

```bash
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                                            |
| -------