Renovating with Renovate
Table of Contents
Renovate was originally created to scratch an internal itch, so we’ve been both enjoying its capabilities and testing them from day one. When people get started or get comfortable with using Renovate, it’s pretty understandable that they might look at the Renovate project itself as a reference user. We’ve put together this post to share how we as “power users” use Renovate in our day-to-day activity, as a little inspiration.
Installation and enablement
We host the Renovate source code on github.com, and so use the Mend Renovate hosted app for maximum convenience.
We use a renovate.json config file in the root so it’s easy for everyone to spot, and it extends our default organization preset in github>renovatebot/.github. We’ll describe how our organization preset works later.
Now that the repository is installed via the app, and onboarded via a config file, it means the hosted app will usually run:
- On schedule, usually every 1-2 hours
- On-demand, if anyone ticks an embedded checkbox in any Renovate Issue or PR
- As-needed if webhook activity indicates that a Renovate PR has been merged, Renovate’s config has been updated, or a notable package file has been edited any other way
Dependency update automation
Automating dependency updates is the main reason people use Renovate, and we aim to keep the project as up-to-date as possible. After all, a professional painter shouldn’t live in a house that needs a new coat, should they?
The key points about how we use Renovate to update dependencies are:
- We extend the config:base preset that all new accounts are recommended. Importantly this means that the most common “monorepos” already come pre-grouped without us needing to configure those.
- We set stabilityDays to 3, meaning that we don’t want any PRs created automatically for new releases which are less than 3 days old. There aren’t many circumstances where any project needs a release that soon, unless it’s an internal release or something you’re specifically waiting for.
- We don’t raise major updates by default. Instead, they are buffered for approval in the “Dependency Dashboard”, which is like a mini dashboard in the repository. This lets us raise them on-demand when we are ready for them.
- We defer updating Microsoft’s dev container for VS Code to once per month. It usually updates more often than that, but we don’t have any urgent need for updates and prefer to keep noise down.
- We don’t custom group package updates — unless they are from known monorepos which must be updated in lockstep. This way one bad update to a dependency doesn’t block all the other updates if they all combined into a single PR.
- We keep the default config:base settings of maximum 2 PRs created per hour or 20 concurrently, but we usually don’t get close to that at all, and try to merge PRs right away once they reach stability and pass our tests.
Organization default preset
The renovatebot organization on GitHub has a .github repository used to share common files, including Renovate configuration files. There are two files which are relevant:
- A renovate-config.json file which is used by Renovate to determine the default onboarding config whenever we add a new repository. By having this repository file in place, it means the hosted app proposes our custom config instead of the default, meaning one less step for us to perform every time a new repository is onboarded.
- A default.json file which is the org’s default preset
Renovate’s org preset also contains some pretty clever “regex manager” rules which we use to apply custom dependency updates to our Dockerfiles and documentation. Both of these are worthy of their own post!
Repository assimilation
We’re a believer that great tools should fit into a developer’s workflows, rather than request developers adjust to a tool’s workflows. For Renovate, this means adapting to a project’s conventions for branch naming, commit syntax, labeling, etc.
In Renovate’s case:
- We use semantic commits, defaulting to “chore” but using “build” for non-dev dependencies so that each update triggers our semantic-release config.
- Speaking of semantic-release, we use “build” semantic commit type — even though it’s a dev dependency, because we always want to test that any new update works and releases.
- We don’t have a need for labels, and don’t apply them. Renovate doesn’t pollute project’s labels by default.
- Renovate automatically assigns two of the project maintainers to each PR.
Merge Confidence
A great new feature introduced by Mend last year is Merge Confidence, and we rely on it heavily.
We built Merge Confidence on the premise that:
- There is always the potential that new releases contain an unintentionally breaking change or bug.
- Relying on your own tests alone is rarely enough to be certain.
- By aggregating test results and version adoption amongst Renovate’s user base, we can determine with a high degree of accuracy whether a new release is safe or not.
In practice, that means Pull Requests for new versions look like this:
Based on the above, it’s clear why the Confidence is “High” and I have no problem merging it, especially as it passed my tests too.
Downstream automation
Another aspect of how we use Renovate to build Renovate is downstream automation. It was mentioned earlier that in most cases you don’t need new releases immediately after they’re released, but internal packages are an exception that an increasing number of Renovate users utilize to improve productivity between projects and teams.
Similar to how many projects are built, Renovate is developed and published across multiple repositories. Once a new release of Renovate is made, we have repositories which build and publish a Docker Image as well as a GitHub Action. App users are often eager to try out new Renovate features right away, so we make sure there is no stability days restriction on our own packages and that PRs are created right away.
Further, there is no need for us to review or approve our own packages in this case, so we also enable branch automerge. What this means is that usually within about an hour of releasing Renovate, the downstream Docker and GitHub Action repositories have already received an automated upgrade of Renovate and are on their way to finishing the process. Because we release up to dozens of times per release, this is not something that can be handled manually.
Additionally, the Mend Renovate App also needs updating, and a similar process applies. In this case although we create the PR immediately, we do require a manual approval/merge before updating the hosted app, because sometimes there are new features which should ideally be observed post-upgrade just to make sure all goes smoothly. We wouldn’t want an accidental bug taking down the app “automatically” during an hour when nobody’s watching closely, so we use a manual approval step for upgrading Renovate in the app. This is again not something which would scale well with manual dependency updates and commits.
Wrapping up
We hope sharing our experience with Renovate helps you find ways to tweak Renovate to your needs, including custom package updates, scheduling, stability, and workflow features. If you have any questions, always feel free to post to Renovate’s Discussion Forum.