Claude
Skills
Sign in
Back

merge-prs

Included with Lifetime
$97 forever

Merges feature-flow PRs in batch. Invoked directly with PR numbers or patterns (standalone mode), or as "merge-prs feature-flow" to merge all labeled PRs (cross-session mode).

General

What this skill does


# Merge-PRs — Ship Phase Orchestrator

Discover, order, and merge feature-flow PRs. Supports three invocation modes determined by `$ARGUMENTS`.

**Announce at start:** "Starting Ship phase — discovering feature-flow PRs..."

---

## Mode Detection

Inspect `$ARGUMENTS`:

| Pattern | Mode | Example |
|---------|------|---------|
| Contains PR numbers (e.g. `185 186`) | **Standalone** | `merge-prs 185 186` |
| Contains `all open` | **Standalone** | `merge-prs all open` |
| Contains `epic N` | **Standalone** | `merge-prs epic 175` |
| Equals `feature-flow` | **Cross-session** | `merge-prs feature-flow` |

---

## Standalone Mode

Accepts explicit PR targets:

| Argument pattern | Behavior |
|-----------------|----------|
| `185 186` | Merge PRs #185 and #186 in the given order |
| `all open` | Query all open PRs on current base branch; merge in optimal order |
| `epic 175` | Query PRs linked to issue #175 via body/title; merge in optimal order |

For `all open`:
```bash
gh pr list --base <current_branch> --state open --json number,title,headRefName,mergeable,statusCheckRollup
```

For `epic N`:
```bash
gh pr list --state open --json number,title,body --jq "[.[] | select(.body | test(\"#N\"))]"
```

For `all open` and `epic N`: execute Step 3 (dependency analysis + merge order), then Step 4 (sequential merge) and Step 5 (summary) as described in the sections below.

For explicit PR numbers (e.g. `185 186`): skip Step 3 — the user specified the order. Execute Step 4 and Step 5 directly.

---

## Cross-Session Mode

Argument: `feature-flow`

Discover all PRs labeled `feature-flow`:
```bash
gh pr list --label feature-flow --state open --json number,title,headRefName,baseRefName,mergeable,statusCheckRollup
```

Then execute Step 3 (merge order), Step 4 (sequential merge), and Step 5 (summary) as described in the sections below.

---

## Step 3: Determine Merge Order

**Read `references/dependency-analysis.md`** to perform cross-PR import dependency analysis before applying heuristics.

Sort the discovered PRs to minimize conflicts:

1. **Dependency constraints** — if PR B's changed files import a file that PR A changes, PR A merges first. Run dependency analysis per `references/dependency-analysis.md` before applying heuristics 2–5. If a circular dependency is detected, warn and skip to heuristics 2–5.
2. PRs with no pending CI checks first (fastest path)
3. PRs with fewest changed files second (lowest conflict surface)
4. PRs targeting `main` / `master` before PRs targeting feature branches
5. Within ties: ascending PR number (oldest first)

**Express/YOLO:** Announce: `Express: merge-prs — Merge order: #[N1] → #[N2] → ... Proceeding...`
**Interactive:** Present order, wait for confirmation via `AskUserQuestion` before proceeding.

## Step 4: Sequential Merge Execution

For each PR in merge order:

**4a. Pre-merge checks:**

**4a.0 Parse feature-flow-metadata block.** Fetch the PR body and parse the `feature-flow-metadata` block per ../../references/feature-flow-metadata-schema.md §Parsing:
```bash
gh pr view <number> --json body --jq '.body'
```
- On successful parse: bind `metadata.sibling_prs`, `metadata.depends_on_prs`, `metadata.risk_areas`, and `metadata.remediation_log` into the PR's pre-merge context for use in dependency analysis (Step 3) and CI remediation de-duplication (Step 4b).
- On absent block, unparseable block, unknown version, or missing required fields: log one warning (per ../../references/feature-flow-metadata-schema.md §Parsing warning budget), bind `metadata` to `null`, and continue with diff-based inference. This is the expected path for PRs created outside the lifecycle.
- See `references/fixtures/` for test cases: `metadata-block-happy.md` (success path), `metadata-block-minimal.md` (required-only / optional fields default to null), `metadata-block-unparseable.md`, `metadata-block-absent.md`, `metadata-block-unknown-version.md`.

**4a.1 Check current state (parallel `gh` calls):**
```bash
# Check current state
gh pr view <number> --json state,mergeable,statusCheckRollup,reviews
```

- If `state: "MERGED"`: announce "PR #N already merged — skipping." Continue.
- If `mergeable: "CONFLICTING"`: attempt conflict resolution (see §Conflict Resolution).
- If CI failing: enter bounded remediation loop. Read `../../references/ci-remediation.md` and apply the attempt loop (default: 3 attempts, 10-min wall-clock, 30s poll interval). Skip only after budget exhausted or an `unknown` category is encountered.
- If any unresolved review threads, discussion comments, or formal reviews exist: enter single-pass review triage loop. Read `../../references/review-triage.md` and apply the triage flow (fetch all feedback surfaces in parallel, filter stale/resolved/self-reply threads, classify and fix, post replies). Review triage runs **before** the CI remediation loop so that any fix commits trigger a fresh CI run which `../../references/ci-remediation.md` can then handle. Skip the PR only if an unfixable blocker remains or (in YOLO) an unclear thread is found.

**4b. Merge:**
```bash
gh pr merge <number> --squash --delete-branch
```

Merge strategy from `.feature-flow.yml` `merge.strategy` (default: `squash`).
Delete branch from `merge.delete_branch` (default: `true`).

**4c. Post-merge actions:**
```bash
# Comment on merged PR
gh pr comment <number> --body "Merged via feature-flow merge-prs (batch merge, order: N/M)"
```

<!-- Issue closure happens via `Closes #N` in PR bodies (GitHub native auto-close).
     The lifecycle no longer closes issues here — see issue #228. -->

**4c.1 Post-merge cleanup (non-blocking):**

Invoke `feature-flow:cleanup-merged` for this PR:

```
Skill(skill: "feature-flow:cleanup-merged", args: "<pr_number>")
```

If `cleanup-merged` fails or throws an error, log a warning and continue:
```
merge-prs: cleanup-merged failed for PR #<pr_number>: <error> — handoff retained for next opportunistic run.
```

Cleanup failure **must not** fail the merge operation itself. The handoff file remains on disk for the next `start:` session's pre-flight to retry.

**4d. Opportunistic Vercel deploy check (non-blocking):**
Check `.feature-flow.yml` `plugin_registry` for any key containing `vercel`:
```bash
# Only if vercel plugin detected:
gh api repos/{owner}/{repo}/deployments --jq '.[0].statuses_url' 2>/dev/null || true
```
Log result but do not block on it.

**4e. Rate limiting:**
For batches of 10+ PRs: add a 1-second delay between merge operations (`sleep 1`).

## Step 5: Merge Summary

After all PRs are processed:

```
Merge Summary:
  Merged: #185, #186 (2/3)
  Skipped: #190 — behavioral conflict in src/api/handler.ts, could not auto-resolve

  Action needed: Resolve conflict in #190 manually, then run `merge-prs 190`
```

Fire the notification from `notifications.on_stop` in `.feature-flow.yml` if set.

## Step 6: Changelog Consolidation

After all PRs have been processed (merged, skipped, or failed), consolidate any `.changelogs/` fragment files into `CHANGELOG.md`:

1. Check for fragments: `ls .changelogs/*.md 2>/dev/null`
   - If no fragments exist: skip silently
   - If fragments exist: continue

2. Read all fragment files. For each fragment:
   - Parse frontmatter (date, pr, scope)
   - Parse categorized entries (Added, Fixed, Changed, etc.)

3. Read existing `CHANGELOG.md` (or create with Keep a Changelog header if absent):
   ```markdown
   # Changelog

   All notable changes to this project will be documented in this file.

   The format is based on [Keep a Changelog](https://keepachangelog.com/),
   and this project adheres to [Semantic Versioning](https://semver.org/).

   ## [Unreleased]
   ```

4. Merge all fragment entries into `CHANGELOG.md` under `[Unreleased]`:
   - For each category, append entries from all fragments
   - Deduplicate entries with identical text (case-insensitive)
   - Sort categories in standard order: Added, Fixed, Changed, Documentation, Testing, Maintenance
   - Within each category, sort entri
Files: 7
Size: 29.6 KB
Complexity: 53/100
Category: General

Related in General