How Renovate Became Our Choice for Updating Dependencies

17.01.2024 - Andy Pfister

Keeping dependencies up-to-date is a good habit. Our (ex)-colleague Tatiana mentioned in her blog post about doing a Rails update that you can prevent a couple of errors already if your dependencies are up-to-date before starting the update. But you also can avoid security issues, get bug fixes and performance improvements, and access to new features with usually only a small time effort.

We do updates for most of our projects every week. We can talk in a separate blog post about the philosophy of this approach. The short version is given in the introduction. However, this post should focus on why we ended up with Renovate as our dependency management tool.

The early days: DIY

Back in 2017, Simplificator used a website called Geckoboard to visualize various health metrics of the company. I was not with Simplificator at the time, so I assume at some point it was decided that Ruby and Rails versions should also be a part of those metrics.

Sadly, I do not find any screenshots of this implementation (we discontinued the Geckoboard earlier this year), but the code is still browsable in Git. Essentially, a helper application pulled all relevant repositories from our GitHub, extracted their Ruby and Rails version, and checked them against a list of acceptable versions. In the first iteration, that list of acceptable versions was hardcoded, but a later iteration inspected RubyGems, the main Ruby website, and the Rails maintenance policy to find the currently supported versions. The list of repositories with outdated Rails / Ruby versions was then published to the Geckoboard.

An intermediate solution: Dependabot

Focusing the update check on Ruby and Rails was too little. We started adopting Elixir and Phoenix in newer projects, which have their own maintenance policy. And Rails is not the only relevant gem to update, there are many others in standard Rails applications.

Dependabot was an answer to those requirements. We started adding it in early December 2019 to a couple of projects. The first iteration of Dependabot still offered a website where you needed to add the dependency files you wanted to monitor. Since the acquisition of Dependabot by GitHub, the configuration file does the same job. Also, the logs that you find in your insights tab were published on the website. It was an external tool after all.

Dependabot was a major step forward from our Geckoboard solution. First of all, the tool does the updates automatically: The Geckoboard solution just notified us of pending updates, but Dependabot opens a PR with the updated version. Additionally, it supports a couple more eco-systems like JavaScript / NPM and Dockerfiles. The scheduling feature is also a welcomed addition: For most projects, we configured it to receive all updates on the first day of the month.

The things still missing in Dependabot

Ultimately, the case for Renovate is that Dependabot still lacks features. We work a lot with docker-compose files for deployments for Docker Swarm, and Dependabot does not support those.

Grouping updates was another feature: It was not unusual that we got about 10 PRs by Dependabot at the start of the month, and if you activated linear history for your PRs, it usually went down like this:

  • Merge the very first Dependabot PR
  • Rebase a second one of your choice to the main branch
  • Wait for continuous integration (~5 minutes)
  • Merge the PR and repeat

Enforcing linear history on a Git repository is a good habit to avoid that code will fail once merged because it is not up-to-date with your main branch. But it made merging all those PRs a tedious process. It is to be noted that Dependabot now supports grouping updates since June 2023.

The last point: A couple of our customers host their code on a different platform, like GitLab and Bitbucket. Dependabot was and still is GitHub-only, and we wanted to have the same comfort on those platforms as well.

Renovate

Renovate is an open-source, JavaScript-based dependency manager. We first discovered it in autumn 2022, gave it a try on one of our customer’s self-hosted GitLab instances, were amazed by its capabilities, and decided to completely replace Dependabot in our projects.

Renovate does all the things that I mentioned earlier that Dependabot still lacks. But there are also three major positives about Renovate:

  1. This is a subjective one, but with Dependabot, I sometimes felt they were unable to do more complicated updates, like applying a React or Rails update. Renovate leverages the native package managers, like it executes “bundle update” behind the scenes and is, therefore, able to apply these complicated updates, or return you a meaningful error message from the package manager.
  2. It offers powerful tools: The regex manager allows you to find versions in various places, like a Node version in a Dockerfile that you like to keep up-to-date. Package rules allow disabling certain updates, grouping updates, or applying special labels depending on the update itself.
  3. Even we hit walls with Dependabot. I opened two discussions now on the Renovate repository, and for both we got an answer in just a few hours. One even led to a bugfix release not even a day later. This is great community work.

You can self-host an instance of Renovate yourself on the platform of your choice or simply use the GitHub App.

The Simplificator preset

The Renovate configuration we use across all Simplificator projects is publicly available on our GitHub. It applies the settings we think are the most valuable for our projects, like applying updates every week, or grouping all non-major updates.

We also sprinkled in some regex managers specific to the ecosystems we use, like automated updates for services on Semaphore CI, or updating the bundler version in Gemfile.lock. Even if you do not use these ecosystems, we think our preset is a good starting point for a Renovate setup. We are happy to discuss your inputs on the issues tab, in case you have additions or even a different opinion.