dependabot-merger
Dependabot Merger
Review Dependabot PRs across configured repos, assess merge safety, map to Jira sprint tickets, and merge or report blockers.
Inputs
Raw arguments: $ARGUMENTS
Infer from the full prompt context and $ARGUMENTS:
- REPOS: local repo paths — infer from any paths mentioned in the context, or fall back to
REPO_LISTenv var - SPRINT_PREFIX: sprint keyword — infer from any sprint or project identifier in the context, or fall back to
JIRA_SPRINT_PREFIXenv var - REPO_FILTER: optional repo name to scope to one repo
- DRY_RUN: true if "dry-run" or "dry run" appears anywhere in the context
Derive the GitHub slug for each repo via:
git -C <repo_path> remote get-url origin \
| sed 's|.*github.com[:/]||;s|\.git$||'
If no repos can be resolved from either source, stop and tell the user.
Phase 1 — Collect open Dependabot PRs
For each repo (apply REPO_FILTER if set), derive the GitHub slug then list open Dependabot PRs:
gh pr list --repo <owner/repo> \
--author "app/dependabot" \
--state open \
--json number,title,headRefName,mergeable,statusCheckRollup,labels,body,url \
--limit 100
statusCheckRollup contains all CI check results — no separate check call is needed. Each entry is either a CheckRun (has conclusion: FAILURE/SUCCESS/SKIPPED) or a StatusContext (has state: SUCCESS/FAILURE/PENDING).
Phase 2 — Risk assessment per PR
Assess each PR on:
Semver level — extracted from title or body:
patch→ Low riskminor→ Medium riskmajor→ High risk
CI status:
- All checks passing → Safe
- Any failing check → Blocker (do not merge)
- Pending → Hold, note in report
Dependency type — from labels or title:
devDependencies/ test-only → lower risk- Runtime deps → higher risk
securitylabel → elevated priority
Breaking change signals — scan PR body for:
- "BREAKING CHANGE", "breaking", "removed", "deprecated"
- Major ecosystem bumps with known breaking patterns
Verdict:
- MERGE — patch, CI passing, no breaking signals
- REVIEW — minor with passing CI; or major devDep with passing CI
- BLOCK — failing CI, major runtime bump, breaking change signals, or pending CI
Phase 3 — Jira sprint ticket lookup
First resolve the sprint name, then fetch tickets scoped to it.
Resolve sprint name:
jira sprint list --state active --plain --no-headers
Tab-separated output — sprint name is column 2. Filter the results using a prefix/keyword resolved in this order:
- Any sprint name or keyword in the user's instruction
- Context clues in the conversation (team name, project name, etc.)
JIRA_SPRINT_PREFIXenv var- If still ambiguous, show the options and ask the user
Fetch tickets in that sprint:
jira issue list \
--jql "sprint = '<resolved_sprint_name>' AND parent is EMPTY AND (summary ~ 'dependabot' OR summary ~ 'dependency' OR labels = 'dependabot')" \
--raw
If no results, broaden to summary ~ 'depend'.
Build a repo → ticket ID mapping from the ticket summaries and descriptions — look for repo name mentions or ecosystem keywords (npm, gem, pip, etc.). If multiple tickets overlap, prefer the most specific match. Note any repos with no matching ticket.
Phase 4 — Merge safe PRs
For each PR with verdict MERGE (skip if DRY_RUN):
-
Prepend ticket ID to title if found:
gh pr edit <number> --repo <owner/repo> --title "[<TICKET_ID>] <original title>" -
Merge:
gh pr merge <number> --repo <owner/repo> --squash --autoFall back to
--mergeif--autois unavailable. -
Comment on the PR with the merge reason before merging:
gh pr comment <number> --repo <owner/repo> \ --body "Merged by dependabot-merger. <reason: summarise the risk assessment — semver level, CI status, dependency type, and any notable signals from the changelog>"
Record merge outcome for the report.
Phase 5 — Report
# Dependabot Merger Report — <DATE>
<DRY RUN — no changes were made> (if DRY_RUN)
## Summary
- Repos scanned: <N> | PRs found: <total>
- Merged: <N> | Needs review: <N> | Blocked: <N>
## Merged ✅
| Repo | PR | Package | Bump | Ticket |
|------|----|---------|------|--------|
| api-service | #123 | rails | 7.1.2 → 7.1.3 | [PROJ-456] |
## Needs Review ⚠️
| Repo | PR | Package | Bump | Risk Reason | Confidence |
|------|----|---------|------|-------------|------------|
| web-frontend | #45 | react | 18.2 → 18.3 | Minor runtime bump | 70% |
## Blocked 🚫
| Repo | PR | Package | Bump | Blocker | Confidence |
|------|----|---------|------|---------|------------|
| api-service | #67 | webpack | 4 → 5 | Major + CI failing + breaking config | 95% |
## Ticket Mapping Gaps
- <repo>: no sprint ticket found — PR merged without ticket prefix
Confidence scoring:
- 90–100%: Clear CI failure or explicit breaking change keyword
- 70–89%: Major bump with broad usage, no explicit breaking signal
- 50–69%: Minor bump with ambiguous changelog
- <50%: Speculative — flag for human judgment
Always include one-line reasoning per confidence score.