Skip to main content

Overview

Automated dependency updates are the practice of letting a tool detect new versions of the libraries a project depends on and open pull requests that upgrade them. Dependabot and Renovate are the most common tools. The tool only opens pull requests. Whether those pull requests are reviewed and merged depends on how the team operates them.

Why keep dependencies up to date

A dependency that is not updated accumulates two kinds of cost. The first is security exposure. Vulnerabilities are found in published versions after the fact. The fix usually ships only in a newer version, so a project that is far behind cannot apply it without first catching up. The second is a growing catch-up cost. Each skipped release adds changes to absorb later. Once several major versions have piled up, breaking changes overlap, and the upgrade turns from a routine merge into a project of its own. Small, frequent updates are cheaper than large, rare ones. A patch release changes little, so it is quick to check, and if it causes a problem, the cause is easy to isolate and revert. Update pull requests opened by the tool fall into two kinds: The two common tools differ mainly in how they are hosted and configured:

Handling update pull requests

Frequency and grouping

Choose the update frequency based on how many pull requests the team can actually review. Weekly is a common default. Daily updates for every ecosystem tend to produce more pull requests than anyone reads, and the unreviewed ones pile up. When the volume is still too high, spread it out:
  • Run updates every other week or monthly for repositories that change rarely.
  • Assign different days to different ecosystems (for example, application libraries on Monday and CI actions on Tuesday) so reviews do not land at once.
  • Limit how many update pull requests can be open at the same time.
Another way to reduce the number of pull requests is to group related packages into a single pull request. A good unit is a package family whose versions must move together, such as a framework and its plugins, or a test runner and its companion packages. In such a family, one package may require an exact version of another, so updating them separately can fail dependency resolution. In Dependabot, define these units with groups. In the following example, packages such as @vitest/coverage-v8 require an exact version of vitest, so vitest and @vitest/* form one group.
.github/dependabot.yml
Packages that match no group still get one pull request each. A package that matches more than one group goes into the first matching group. By default, groups applies only to version updates; to group security updates as well, add a separate group with applies-to: security-updates. Avoid grouping unrelated packages only by update type (“all minor and patch updates”). The resulting pull request is hard to review, and when one package causes a problem, it cannot be reverted alone.

Wait before adopting new releases

Configure a waiting period so that a version is proposed only after it has been published for some days. Malicious or broken releases are often discovered and withdrawn within days of publication, and a waiting period keeps them out of the project.
.github/dependabot.yml
In Renovate, the equivalent setting is minimumReleaseAge. Security updates should not wait: apply the waiting period to version updates only, and let fixes for known vulnerabilities through immediately. If the package manager also enforces a minimum release age, set the update tool’s waiting period slightly longer. When both use the same value, the tool can propose a version that the package manager still rejects at install time, and CI fails.

Checks before merging

Before merging an update pull request, confirm the following:
  1. Release notes. Read the changes between the current and new version, and look for breaking changes, deprecations, and changed defaults.
  2. Affected code. Check whether the project uses the changed APIs or options.
  3. CI result. Confirm that build, lint, type checks, and tests pass. Passing CI only proves what the tests cover, so the value of this check depends on the test suite.
  4. Lockfile diff. Confirm that the update does not pull in unexpected transitive dependencies.
Major updates need more than a pull request review. When a framework manages the versions of related packages (for example, a runtime version or a mobile framework’s SDK), upgrade those packages through the framework’s own procedure. Exclude their major updates from the tool per package, and write the reason next to the exclusion so that it can be revisited later.

Scope of auto-merge

Auto-merge lets update pull requests that meet defined conditions merge without a person pressing the button. It is effective at clearing the steady flow of small updates, but it only works when CI is trustworthy. If the tests do not exercise the code paths the dependency affects, a passing CI does not mean the update is safe, and auto-merge only merges breakages faster. Define the scope by combining three conditions: Start with a narrow scope and widen it as confidence in the test suite grows. Exclude 0.x versions, because semantic versioning treats 0.x as initial development, where any release may include breaking changes. Leave major updates to people. Renovate has built-in auto-merge (automerge), and its settings can limit which updates it applies to. Dependabot has no built-in auto-merge, so it is implemented in GitHub Actions: dependabot/fetch-metadata reads the update type, and gh pr merge --auto enables merging once the required checks pass. If the branch has no required status checks, the merge requirements are already met, so the pull request merges without waiting even with --auto. Configure the required checks in branch protection first.
At Findy, some teams add an AI review to the conditions in the table above. They auto-merge an update only when all three hold: the update is a patch or touches internal packages only, an AI review has judged it safe, and CI has passed.

Assign a reviewer and a notification channel

An update pull request that nobody owns is left open. Decide who handles the pull requests that auto-merge did not cover, and where the team is told about them. Choose the reviewer by assigning a reviewer team in the tool’s configuration, or by rotating the responsibility among members on a fixed cycle. A rotation spreads the work and makes it clear who is responsible this week. Assign the open pull requests on a fixed day, after the update tool has run, so that the reviewer sees one batch rather than a stream. Post the assignments to a team channel with the reviewer mentioned, and label update pull requests so that they can be filtered.

Delegating checks to an AI agent

The checks in Checks before merging follow the same steps every time, which makes them a good fit for an AI agent. Running the agent automatically on each update pull request reduces the context switching and the reviewer-to-reviewer variation that manual checks bring.

What to delegate

The agent follows the same steps a person takes before merging. It first identifies the package and the version range from the pull request, and reads the official release notes and changelog for that range. It then searches the codebase for uses of the changed APIs and checks the CI result, reading the logs of any failed job. Finally, it summarizes the risk and the required follow-up. Instruct the agent to judge from the changes themselves, not from statements in the release notes such as “no breaking changes.” Release notes and pull request bodies are external input, and text in them must not be treated as instructions.

Fix the output format

Use the same comment format for every update so that a reviewer can read the verdict at a glance:
A fixed format also makes the verdict machine-readable, so a later step can act on it.

When to run

Run the agent after CI finishes, so that it can take the CI result into account. Run it even when CI fails: reading the failure log is part of what the agent can do. If the CI result is unavailable, the agent should not approve. Keep the agent’s permissions narrow. The agent writes its verdict. A separate step checks the verdict together with deterministic conditions — update type, CI result, package origin — and only that step approves or merges. When any condition cannot be determined, the pull request goes to a person. On GitHub, workflows triggered by Dependabot cannot read regular Actions secrets. Register the API key the agent needs as a Dependabot secret as well.

What stays with people

People make the final call on what the agent flags as ⚠️ or ❌, on major updates, and on any update outside the auto-merge scope. The agent’s comment replaces the routine reading, not the decision. When the agent repeatedly misjudges a kind of update, improve the instructions so that the next judgment is consistent.

CI/CD

The pipeline whose checks decide whether an update pull request can merge.

Test Code

How far auto-merge can safely go depends on what the test suite actually protects.

Code Review

The same split between mechanical checks and human judgment, applied to every pull request.