Handling major version upgrades from update bots Jump to heading
Update bots are excellent at patch and minor updates: CI passes, someone approves, done. Major versions are different. A bot can bump "framework": "^4.2.0" to "^5.0.0" in seconds, but the changelog says three APIs were removed, a default changed and the minimum runtime moved. The pull request goes red, nobody owns it, and it sits open for months until the bot opens a newer one, which is now two majors behind. Treating majors as engineering work — with an owner, a plan and a branch people can push fixes to — turns that pattern around. This page sets up the configuration and the routine, within automated dependency updates.
When to use this approach Jump to heading
- Major-version pull requests from your update bot stay open for weeks or months.
- Several dependencies are one or more majors behind, and the gap keeps growing.
- Breaking upgrades need code changes, and it is unclear who should make them.
- Minor and patch updates already flow smoothly, as in grouping dependency updates to reduce PR noise.
Step 1 — Separate majors from routine updates Jump to heading
Majors should never be grouped with minor updates; a red group blocks every update in it. Configure the bot to open each major on its own, labelled so it is easy to find and assign.
// renovate.json
{
"packageRules": [
{ "matchUpdateTypes": ["minor", "patch"], "groupName": "non-major" },
{
"matchUpdateTypes": ["major"],
"labels": ["dependencies", "major-upgrade"],
"dependencyDashboardApproval": true,
"prBodyNotes": ["Breaking changes: read the release notes before approving. Owner pushes fixes to this branch."]
}
]
} dependencyDashboardApproval makes Renovate list majors on its dashboard issue and open the pull request only when someone ticks the box — so majors are opened when someone is ready to work on them, not at random.
Step 2 — Read what changed before touching code Jump to heading
Start from the upstream release notes and migration guide, then search the codebase for every use of the changed APIs. That turns a red CI run into a list of concrete edits.
# Where does the codebase use the APIs the changelog says were removed?
git grep -nE '\b(createLegacyClient|withRetries|parseOptions)\(' -- 'src/**/*.ts'
# How many files depend on the package at all?
git grep -lE "from ['\"]framework['\"]" -- 'src/**/*.ts' | wc -l Record the findings in the pull request description: the breaking changes that apply, the files affected, and anything that needs a decision.
Step 3 — Fix breakage on the bot’s branch Jump to heading
Bots let maintainers push to their branches. Check out the bot’s branch, make the fixes as separate commits, and push. Configure the bot not to rebase over your commits, or it will discard them.
gh pr checkout 942 # the bot's major-upgrade PR
# make the migration changes
git commit -am "refactor: migrate to framework v5 client API"
git push // renovate.json — stop Renovate rebasing once someone else has committed
{ "rebaseWhen": "conflicted" } Step 4 — Upgrade several majors in steps Jump to heading
When a dependency is several majors behind, jumping straight to the latest often hits every breaking change at once. Upgrading one major at a time, each with its own migration guide, is usually faster overall. Ask the bot for intermediate versions explicitly.
{
"packageRules": [
{
"description": "Step framework through v4 before v5",
"matchPackageNames": ["framework"],
"allowedVersions": "<5.0.0"
}
]
} Once the v4 upgrade has merged, remove the rule, and the bot proposes v5.
Step 5 — Track deferrals explicitly Jump to heading
Sometimes a major cannot be adopted yet — a platform constraint, an upstream bug. Defer it with an ignore rule that states the reason and a revisit date, rather than leaving the pull request open indefinitely.
{
"packageRules": [
{
"description": "Deferred: ORM v7 needs Postgres 15 (platform upgrade OPS-311, revisit 2027-01)",
"matchPackageNames": ["orm"],
"matchUpdateTypes": ["major"],
"enabled": false
}
]
} # A quarterly reminder: list deferral rules and their revisit dates
jq -r '.packageRules[] | select(.enabled == false) | .description' renovate.json Validation checklist Jump to heading
Frequently Asked Questions Jump to heading
Can Dependabot do the same? Jump to heading
Dependabot opens majors as separate pull requests by default when they are excluded from groups, and allows pushing to its branches. It has no dashboard approval, so use ignore for majors you are not ready for and remove the rule when you are.
How do we stop majors piling up again? Jump to heading
Review the list of outstanding majors monthly and give each one a decision: schedule, defer with a date, or drop the dependency. The list is short when it is looked at regularly.
Should major upgrades go through a feature flag? Jump to heading
For runtime libraries whose behaviour changes — HTTP clients, ORMs, serialisers — a flag or a staged rollout reduces risk. For build tooling, CI coverage is usually enough.
Related Jump to heading
- Automated Dependency Updates — the parent topic.
- Configuring Renovate for a Monorepo — the configuration these rules extend.
- Auto-Merging Patch Updates Safely — the routine end of the spectrum.
- Branch by Abstraction for Large Changes — for upgrades too large for one pull request.