Dependency updates: where Dependabot fails
Dependabot reliably opens pull requests — and that's where many people stop.
Opening a pull request is not the same as updating dependencies: without grouping rules and auto-merge conditions, changes pile up in the queue, colleagues stop opening identical tickets, and the pipeline runs for weeks on outdated dependencies.
The wider the graph, the faster the queue grows — dozens of small pull requests compete for one check, and none gets it on time.
A typical failure looks like this. A transitive dependency pulls in a major version incompatible with the version pinned in the version file, and the broken build arrives in a module nobody touched.
The cause is not new code, but the version difference accumulated over months: it has to be untangled manually, rolling back changes one by one.
While pull requests hang unverified, vulnerabilities in dependencies remain open: there is an alert, a patch exists, but it never made it to the main branch.
An update split into hundreds of small steps reaches the release branch only every other time, and the accumulated backlog is dealt with in one go.
We break down how this is resolved: grouping changes by ecosystem, scheduling, auto-merging safe updates, and a separate procedure for major versions.
What managed dependency updates provide
A vulnerability in a transitive dependency lives in the project not because it goes unnoticed, but because no one gets around to it.
Dependabot reads lockfiles, finds outdated packages, and opens a change with the new version itself — a stream of tasks instead of manually traversing registries.
Without a policy, this stream overwhelms the team: dozens of identical changes per week, and time to close a vulnerability is again measured in months.
- Time to close a vulnerability — a critical patch gets into a change within the first hours after publication, not in the next planning cycle: priority is set by a policy based on severity level.
- Share of changes without a human — patch versions and routine updates are merged automatically after green checks, usually 70–80% of the stream. Review remains for major versions and public interface changes.
- Number of failed builds — grouping updates by ecosystem and limiting simultaneous changes removes conflicts over a single lockfile.
- Time for manual triage — a weekly summary instead of daily email: the engineer looks only at unaccepted changes.
For private registries and non-standard ecosystems, the same rules are described in Renovate — the configuration lives in the repository and is versioned along with the code.
The result is measurable: dependency security stops depending on a free window in the schedule, technical debt from outdated packages decreases, and build time does not grow from accumulated versions.
Dependabot or Renovate: which mode to choose
The platform's built-in bot GitHub and an external scheduler solve the same task — but integrate into the process differently.
Dependabot is configured in the repository itself and does not require a separate service that someone has to keep alive; Renovate lives as a standalone scheduler with a configuration file in the repository and can traverse many projects at once, including on different platforms.
The third option is manual mode, when updates are made according to the release procedure and checked by a human.
| Option | When it fits | Limitations |
|---|---|---|
| Platform's built-in bot | Single repositories, a team without a dedicated engineer | Change rules are limited by platform settings, fine-grained grouping logic unavailable |
| External scheduler | Many repositories, monorepos, custom change acceptance rules | Requires a configuration file and an access token that is updated during permission rotation |
| Manual mode | Strict dependency control, infrequent releases | Dependencies age faster than someone gets around to them; vulnerable versions live for weeks |
In any mode, behavior is most affected by the update schedule and grouping. Without grouping, patches for thirty dependencies arrive as thirty separate pull requests — review drowns in noise, and after two weeks no one reads it.
The setting "update once a week, minor versions in one group, major versions separately" reduces the stream to two or three reviewable packages, while security updates are left out of the schedule.
The modes are not mutually exclusive: the built-in bot is used for small repositories, the external scheduler for large projects with custom rules.
Switching between them does not block work: the configurations are independent, and rollback amounts to deleting the settings file and returning to the previous schedule.
Implementation order: from audit to handover
Implementing auto-updates is not installing a bot, but setting up a mode in which dependency changes arrive predictably and do not break the build.
We work according to a fixed scheme: first see the real picture of dependencies, then agree on rules, and only then enable automation.
- Dependency audit. We inventory direct and transitive packages, separate production and dev, find unused and abandoned libraries. The output is a table with priorities: what to update first and what requires manual intervention.
- Update policy scheme. We fix package groups, check schedule, and limit of simultaneously open changes. Patches and minor versions go with auto-merge on green tests, major versions only with manual confirmation.
- Automation setup. We write the configuration, rules for ignoring problematic packages, labels, and owners. Each change gets a description of changes and a link to the release so the reviewer doesn't have to guess.
- Test run on a test branch. We enable the stream of changes in an isolated branch and observe real behavior: how many arrive per week, whether the build and tests pass, where conflicts arise.
- Triage of the first changes. We manually go through the first dozen updates and calibrate the rules: remove noisy packages, add missed checks, set priorities.
- Handover with training. We give the team configurations, the procedure, and analysis of typical situations: how to roll back a change, how to pause the stream, what to do on a version conflict.
After handover, the team has a working scheme and a clear procedure — updates happen in the background instead of turning into a rush before release.
Configurations, rules, and update procedures
The output is not a set of one-off changes left in the repository, but a working update loop: configuration under version control, merge rules, and a procedure by which the queue is handled without our involvement. Below is a list of artifacts and the purpose of each.
- Configuration file — check schedule, limit of simultaneously open pull requests, list of ecosystems and directories that the tool traverses or ignores.
- Grouping rules — related updates of one library or one set (tests, linters, types) are collected into one pull request so the review queue does not grow.
- Auto-merge matrix — line by line: update class (patch, minor, major), state of the check suite, who has the right to merge. A patch with green tests goes through on its own, a major waits for review and a manual scenario run.
- Exception matrix — packages pinned to a specific branch, with the reason: incompatibility with the current runtime, lack of support, waiting for a planned migration.
- Update and on-call procedures — who triages the queue, on which days, response time to a critical vulnerability alert, what to do when the check suite is red.
- Rollback procedure — how auto-merge is canceled, on which branch rollback is tested, which labels show that the rule worked.
- Documentation and acceptance checklist — how to put a new package under observation, how to verify that a rule fired, and where the reason for an exception is recorded so that any engineer can understand it six months later.
Case: how the update stream stopped piling up
What it was before
The project — several services where manifests and lockfiles were edited manually, once a quarter.
By the time of the review, more than a hundred open changes had accumulated, some had been hanging for months, and a vulnerability in a transitive dependency took three to four weeks to close.
The release branch failed on roughly every third build — version incompatibility surfaced already at release.
What was changed
We configured Dependabot in groups: patch and minor updates of related packages arrive as one change, so there are almost no conflicts in the lockfile. We enabled auto-merge of changes — only with green checks and a full test run, in a window outside release.
Major versions were put into a separate queue with manual triage and a description of breaking changes; rollback — restoring the previous lockfile.
What it became
About three quarters of changes are accepted automatically. The engineer reviews the rest in minutes: updates are already grouped, changes are compact.
Time to close a vulnerability decreased from weeks to two or three days — a warning about a dependency problem turns into an accepted change the next morning.
There are several times fewer builds broken by updates on the release branch: incompatibilities are caught on small changes, not at release. The number of open changes stays around ten — the update stream stopped piling up.
What to do if Dependabot opened hundreds of changes?
If Dependabot opened hundreds of changes, these are not hundreds of tasks, but one dependency debt that accumulated for months and spilled out all at once.
You cannot merge everything indiscriminately: among the accumulated changes there are security patches and major updates that break the build. We start with a baseline — bring the main branch to a fixed lockfile state and from there count what actually requires attention.
Next — triage the update queue by risk levels. Patch versions and security fixes go into the first batch: they are run through automated checks and merged in groups by ecosystem, not one change at a time.
Minor versions are the second batch, after the first has settled in staging. Major versions go in a separate list: we read each one by its change description and check manually.
We limit the batches, otherwise triage will take months: no more than one or two grouped updates per day and only after green checks.
In the bot itself, we enable grouping by ecosystem, a schedule instead of a daily stream of changes, and a delay for the minimum release age — a fresh version has time to settle before entering the queue.
We close the cause separately: a limit on the number of simultaneously open changes, auto-merging patches after checks, and a procedure for major upgrades with a rollback plan.
Then dependency debt stops growing and does not return a quarter later: the queue is measured in dozens of changes instead of hundreds.
Common technical doubts about auto-updates
Auto-merge, rollback, and access to private registries are three settings that determine whether dependency updates can be handed to a robot at all.
In Dependabot and related bots, we set rules so that a broken build does not reach the main branch, and any version can be returned with one operation.
Is auto-merge applied to all updates?
No — only to patch versions within the current major branch: there are no public behavior changes. Minor and major updates, as well as runtime and build dependencies, go as separate pull requests, through the pipeline and engineer review.
What to do if the build fails after an update?
The pipeline blocks merging on the first test failure — the bot's branch does not reach the main branch.
Rollback is restoring the exact versions file to the previous revision: it pins both direct and transitive dependencies, so the build returns to a reproducible state with one cancellation.
Does the bot see private packages?
Yes, through an access token to the internal registry — it lives in pipeline secrets and grants read-only access. The bot gets the list of versions and metadata, but cannot publish or delete packages; the token is scoped and revoked with one entry.
How are dependency conflicts resolved?
The bot resolves a conflict in the exact versions file itself: it rebuilds the branch on top of the main branch and recalculates the graph.
A conflict in code, when files with manual edits are affected, blocks auto-merge — the task goes to an engineer, and others' changes are not overwritten.
Let's discuss your dependency update scheme
To make the update scheme work from the first run, and not after several iterations, we need a brief input on your repository.
Below is what we request at the start and what we return: the frequency of checks, the level of auto-merge, and the bot's behavior on conflicts depend on this data.
- Composition of repositories and package managers — where dependencies are located, whether there are private registries, which branches are closed to external updates. This determines how to configure Dependabot and Renovate so that the stream of pull requests does not clog the review queue.
- Branching scheme and release mode. If release is once every two weeks, we synchronize the update interval with it and target the development branch, not the main one.
- Security requirements — whether you respond only to critical vulnerabilities or to all. We set up grouped updates, commit signatures, and package provenance verification.
- Merge rules: what is accepted automatically (patches and minor versions), what requires manual review. We enable auto-merge only with green checks.
- Set of checks before merge — tests, linters, build. The denser the coverage, the wider the automation can be opened without risk to the main branch.
- Access and notifications: tokens for reading registries, permissions to create branches, notification channel, and the person responsible for stuck updates.
The output is configuration files for each repository, an update policy with a schedule, auto-merge rules, and a work plan with checkpoints. Then, at your choice, we hand the project over for support or run it together with your team. Describe the task — we will come back with an estimate and a plan for your branching scheme.







