> **Page index:** https://km.oslo.systems/llms.txt lists every page on this site, with a link to its Markdown version.

# Automatically merge dependency updates with Renovate

This guide shows how to let Renovate merge dependency updates automatically in an application repository. Renovate calls this `automerge`.

You choose which updates Renovate can merge. For all other updates, Renovate opens a pull request as before.

Before you start, Renovate must already update the dependencies of your application. To set that up, see [Update application dependencies with Renovate](<https://km.oslo.systems/application/update-application-dependencies-with-renovate/index.md>).

```
/golden-path:renovate-automerge Let Renovate merge patch and minor updates of test dependencies.
/golden-path:renovate-branch-checks Run our workflows on the branches Renovate pushes, so the checks test every update.
/golden-path:dependency-test-gaps Find dependencies that no test uses, before Renovate merges updates of them.
```

```
Let Renovate merge one class of dependency updates. Follow `{page}`.
```

## Step 1: Add the configuration

Add `platformAutomerge`, two limits, and one rule to `renovate.json5` in the root of your application repository. This example lets Renovate merge small updates of test dependencies.

renovate.json5

```
{
  $schema: "https://docs.renovatebot.com/renovate-schema.json",
  extends: [
    "github>oslokommune/golden-path-renovate:default.json5",
    "github>oslokommune/golden-path-renovate:golden-path-v2.json5",
  ],
  platformAutomerge: false, // (1)!
  prConcurrentLimit: 5, // (2)!
  branchConcurrentLimit: 10, // (3)!
  packageRules: [
    {
      description: "Automerge patch and minor updates of test dependencies",
      matchDepTypes: ["test"], // (4)!
      matchUpdateTypes: ["patch", "minor"], // (5)!
      automerge: true,
      automergeType: "branch", // (6)!
      automergeSchedule: ["after 9am and before 3pm every weekday"], // (7)!
    },
  ],
}
```

1. Renovate merges the update itself, not GitHub. GitHub's auto-merge [ignores `automergeSchedule`](<https://docs.renovatebot.com/configuration-options/#automergeschedule>), so it can merge at night.
2. Renovate opens at most 5 pull requests at a time. This keeps the list of updates that need a person short. The preset allows 10.
3. Renovate keeps at most 10 update branches at a time. A branch with a pull request counts too, so at least 5 branches are left for updates that Renovate merges itself. Without this line, the limit is 5 branches.
4. This line is an example. It picks [test dependencies](<https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope>) in a Maven project. To pick other dependencies, use the `match` settings for your package manager.
5. The rule covers patch and minor updates, such as 1.2.3 to 1.2.4 or to 1.3.0. A major update, such as 1.2.3 to 2.0.0, always gets a pull request.
6. Renovate pushes the update to a branch and waits for the checks. If they pass, Renovate merges the branch into the default branch, and no pull request opens. If a check fails, Renovate opens a pull request so a person can review it.
7. Renovate merges only on weekdays from 09:00 to 15:00, when people are at work and can fix a problem. The preset sets the time zone to `Europe/Oslo`.

The preset also waits 7 days after a third-party release before Renovate updates to it.

## Step 2: Test every update

Renovate merges an update as soon as the status checks pass, without anyone reviewing it. Your GitHub Actions workflows are the only review, so set them up before Renovate merges anything.

> [!NOTE]
>
> **What is a status check?**
>
> A [status check](<https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks> "About status checks") is a result that GitHub shows on a commit, such as a run of a GitHub Actions workflow. You might know them from the bottom of a pull request, which shows the status checks of its latest commit. The rest of this guide calls them checks.

1. Run your workflows when Renovate pushes a branch. The branch names start with `ok-renovate/`. A workflow that runs only on `pull_request` doesn't test the update, because no pull request opens.
2. Allow Renovate to push to the default branch. If a ruleset requires a pull request, add the `kjoremiljo-renovate` app to the bypass list of that ruleset.

> [!WARNING]
>
> **A test must use the dependency**
>
> If no test uses a dependency, the checks pass even when an update breaks it. Before you let Renovate merge updates of a runtime dependency or a Docker base image, check that a test fails when the dependency is broken.

## Step 3: Add one class of updates at a time

Don't let Renovate merge every update at once. Add one class of updates at a time, so you learn whether your tests catch a broken update before you trust them with riskier ones. A class is a group of updates with similar risk, such as test dependencies or GitHub Actions. Risk depends on how much of the application a dependency reaches. Each dependency is one of three kinds:

- **Tools** build and check the application but aren't part of it. When an update breaks a tool, a check fails.
- **Leaf** dependencies serve one isolated part of the application, such as PDF export. A broken update affects only that part.
- **Core** dependencies are used across the application, such as the web framework or the JSON library. A broken update can affect the whole program.

| Class | Examples | Kind | Let Renovate merge |
| --- | --- | --- | --- |
| Test libraries | JUnit, AssertJ, pytest, Vitest | Tool | Yes, start here |
| Linters and formatters | Ruff, ESLint, Prettier | Tool | Yes |
| GitHub Actions | `actions/checkout`, `actions/setup-node` | Tool | Yes |
| Leaf libraries | A PDF library, the SDK for one external service | Leaf | Only if a test covers that part |
| Core libraries | Jackson, Hibernate, the logging library | Core | Only if many tests use the library |
| Docker base images | `eclipse-temurin`, `python`, `node` | Core | Only if a workflow builds and runs the image |
| Frameworks and compilers | Spring Boot, Django, Java, TypeScript | Core | No, a person reviews these |

1. Start with the class that has the lowest risk, such as test dependencies.
2. Add one rule to `packageRules` for that class.
3. Add the next class when you know that your tests cover it.

```
Find the lowest-risk class of dependency updates that Renovate doesn't merge yet. If our tests cover it, add a rule for it to `renovate.json5`. Follow `{page}`.
```

## Step 4: Verify

Wait for the next update that the rule applies to, then check the commits on the default branch. You should see a commit by `kjoremiljo-renovate[bot]` that has no pull request.

Renovate runs every hour on weekdays and merges one update in each run, so a backlog takes time to clear.

If Renovate opens a pull request instead, one of these happened:

- A check failed on the branch.
- Renovate isn't allowed to push to the default branch.
