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.

Majors in a group against majors on their ownGrouping a major with minor updates means one breaking change turns the whole group red and blocks every update in it. Opening each major separately, on demand, keeps routine updates flowing and gives the major an owner and a branch for fixes.Major inside a groupMajor on its owna breaking changeblocks the groupblocks only itselfownerunclearassigned on approvalfixes pushed tonobody's branchthe bot's PR branchroutine updates should never wait on a major

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" }
A major upgrade as shared workThe bot opens the upgrade after a maintainer approves it on the dashboard. The owner checks out the bot's branch, pushes migration commits, and CI runs on the combined change. The bot leaves the branch alone because someone else has committed, and the upgrade merges when green.maintainerbotownerCIapprove on dashboardPR: framework v5migration commitspush to bot branchgreenthe bot does the bump; a person does the migration, on the same pull request

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
What to do with an open major upgradeIf it passes CI after reading the changelog, review and merge. If it fails and the team can migrate now, assign an owner who pushes fixes to the bot's branch. If it cannot be adopted yet, close it and record a deferral with a reason and a revisit date.State of the major-upgrade PRgreen, changes understoodReview + mergenormal reviewred, migration possibleAssign ownerfix on bot branchblocked by constraintDefer explicitlyreason + revisit datean open, unowned, red major is the one state to avoid

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.