---
name: dependabot-pr-triage
description: Use when there are multiple open Dependabot PRs to resolve, dependency update PRs piling up, or user asks to handle/merge/triage dependabot PRs
---

# Dependabot PR Triage

## Overview

Consolidate multiple Dependabot PRs into a single combined branch, tested holistically, with one commit per dependency for easy revert. Never merge Dependabot PRs one by one — it causes cascading rebases and pipeline waits for other branches.

## When to Use

- Multiple open Dependabot PRs in a repo
- User asks to "handle", "merge", "resolve", or "triage" dependabot PRs
- Dependency update PRs piling up

**Do NOT use for:** Single Dependabot PR that passes CI — just merge it directly.

## The Workflow

```dot
digraph dependabot_triage {
    "Multiple Dependabot PRs open" [shape=doublecircle];
    "List all PRs with CI status" [shape=box];
    "Any major version bumps?" [shape=diamond];
    "Ask user which majors to include" [shape=box];
    "Create combined branch from main" [shape=box];
    "For each included PR:" [shape=box];
    "Merge dependabot branch (not npm install)" [shape=box];
    "Commit (one per dep)" [shape=box];
    "More PRs?" [shape=diamond];
    "npm install (consolidate lockfile)" [shape=plaintext];
    "Run full verification" [shape=box];
    "All passing?" [shape=diamond];
    "Fix in SEPARATE commit per dep" [shape=box];
    "Re-run verification" [shape=box];
    "Push + create PR (Closes #N, version label)" [shape=box];
    "Done" [shape=doublecircle];

    "Multiple Dependabot PRs open" -> "List all PRs with CI status";
    "List all PRs with CI status" -> "Any major version bumps?";
    "Any major version bumps?" -> "Ask user which majors to include" [label="yes"];
    "Any major version bumps?" -> "Create combined branch from main" [label="no"];
    "Ask user which majors to include" -> "Create combined branch from main";
    "Create combined branch from main" -> "For each included PR:";
    "For each included PR:" -> "Merge dependabot branch (not npm install)";
    "Merge dependabot branch (not npm install)" -> "Commit (one per dep)";
    "Commit (one per dep)" -> "More PRs?";
    "More PRs?" -> "For each included PR:" [label="yes"];
    "More PRs?" -> "npm install (consolidate lockfile)" [label="no"];
    "npm install (consolidate lockfile)" -> "Run full verification";
    "Run full verification" -> "All passing?";
    "All passing?" -> "Push + create PR (Closes #N, version label)" [label="yes"];
    "All passing?" -> "Fix in SEPARATE commit per dep" [label="no"];
    "Fix in SEPARATE commit per dep" -> "Re-run verification";
    "Re-run verification" -> "All passing?";
    "Push + create PR (Closes #N, version label)" -> "Done";
}
```

## Step-by-Step

### 1. Triage — List and Categorize

```bash
# Fetch all dependabot PR metadata
gh pr list --author "app/dependabot" --state open --json number,title,headRefName,statusCheckRollup

# Check CI logs for failing PRs
gh pr checks <PR_NUMBER>
gh run view <RUN_ID> --log-failed
```

Categorize each PR:
- **Passing + minor/patch** → include automatically
- **Passing + major** → ask user whether to include
- **Failing + any** → ask user whether to include (show what's failing)

**STOP: Always ask the user which major version bumps to include.** Major bumps (e.g., Sentry 7→10) can require significant migration work. Never silently include them.

### 2. Create Combined Branch

```bash
git checkout main
git pull origin main
git fetch origin  # REQUIRED: fetch all remote branches including dependabot ones
git checkout -b NO-TICKET-dependabot-updates
```

### 3. Merge Each Dependabot Branch — ONE COMMIT PER DEPENDENCY

**Merge order:** passing PRs first (lowest risk), then failing PRs (highest risk last). This way if a complex migration stalls, you still have a branch with the easy wins ready to ship.

For each included PR, merge its actual branch (do NOT manually `npm install`):

```bash
# Merge the dependabot branch — preserves provenance
git merge --no-ff origin/dependabot/npm_and_yarn/<dep-name>-<version> -m "NO-TICKET Bump <package> from X to Y"
```

**CRITICAL RULES:**
- **One commit per dependency.** Never bundle multiple deps in one commit. This is the whole point — easy `git revert` if one update breaks production.
- **Merge the actual Dependabot branch**, not `npm install`. This preserves the lockfile changes Dependabot computed and maintains commit provenance.
- **If merge conflicts occur** between two Dependabot branches (usually in `package-lock.json`), resolve them, then run `npm install` to regenerate a clean lockfile.

### 4. Consolidate and Verify

After all merges:

```bash
npm install  # Ensure lockfile is consistent after all merges

# Run FULL verification — all four checks:
npm run lint
npm run typecheck
npm run test:unit
npm run build
```

**All four checks are mandatory.** Lint and typecheck alone are not sufficient — tests catch runtime breakage that types miss.

### 5. Fix Breakages — SEPARATE Commits

If verification fails, fix the issue and commit the fix separately:

```bash
# Fix the compatibility issue in source/test files
# Then commit with a clear reference to which dep caused it:
git add <changed-files>
git commit -m "NO-TICKET Fix <package> vX compatibility — <what broke>"
```

**NEVER mix dependency bump commits with fix commits.** The bump commit should be a clean merge of the Dependabot branch. The fix commit shows exactly what code had to change for compatibility. This separation makes it trivial to understand what a dependency update required.

Re-run full verification after each fix. Repeat until all green.

### 6. Version Bump

**Do NOT bump the version manually.** Most repos use a GitHub Action triggered by a PR label (e.g., `version:patch`, `version:minor`) to handle version bumping on merge. Check the repo's workflows and labels to determine the correct approach.

Add the appropriate version label when creating the PR (see step 7).

### 7. Push and Create PR

```bash
git push -u origin NO-TICKET-dependabot-updates

# Create PR — do NOT enable auto-merge. User must review and merge manually.
# Add version label for automated version bumping (check repo for correct label name)
gh pr create --title "NO-TICKET Bump dependencies" --label "version:patch" --body "$(cat <<'EOF'
## Summary
- Bump `<dep1>` from X to Y
- Bump `<dep2>` from X to Y
- ...

Closes #11, Closes #12, Closes #13, Closes #14

## Verification
- [x] Lint passes
- [x] Typecheck passes
- [x] All unit tests pass
- [x] Build succeeds

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOF
)"
```

**Use `Closes #N`** for each Dependabot PR — GitHub auto-closes them when this PR merges. Do NOT manually close them with `gh pr close`.

**Do NOT use `--auto` or `gh pr merge --auto`.** The combined PR must be reviewed and merged manually by the user. This is not a Dependabot PR — it's a manually created PR that consolidates multiple updates and potentially includes migration fixes.

### 8. Excluded PRs

For major bumps the user chose to skip:
- Leave the Dependabot PRs open — they serve as reminders
- Optionally comment: `@dependabot ignore this major version` if the user confirms they won't adopt it

## Common Mistakes

| Mistake | Why it's wrong | Do this instead |
|---|---|---|
| Bundle multiple deps in one commit | Can't revert one without the other | One commit per dependency, always |
| `npm install <pkg>` instead of merging branch | Loses Dependabot lockfile changes and provenance | `git merge` the actual Dependabot branch |
| Mix fix code into the bump commit | Can't tell what the dep update required | Separate commit for fixes |
| Merge passing PRs individually first | Causes rebase cascade for other branches | Consolidate everything into one branch |
| Skip tests, only run lint+typecheck | Tests catch runtime breakage types miss | Run all four: lint, typecheck, test, build |
| Include all major bumps without asking | Major bumps can need significant migration | Always ask user about major versions |
| Manually close Dependabot PRs | Redundant if using `Closes #N` syntax | Let GitHub auto-close on merge |
| Forget `git fetch origin` | Dependabot branches are remote-only | Always fetch before merging |
| Bump version manually | Most repos use GitHub Actions + PR labels for versioning | Add `version:patch` label to the PR instead |
| Keep old direct dep after package swap | Causes peer dep conflicts or duplicate packages | If new package pulls old one transitively, remove old from direct deps |
| Use `^` in pinned-version repos | Allows uncontrolled upgrades | Always pin exact versions (no `^` or `~`) |
