Renovate/Dependabot: How to Take Control of Dependency Updates
At Devoxx France 2024, held in April at the Palais des Congrès in Paris, Jean-Philippe Baconnais and Lise Quesnel, consultants at Zenika, presented a 30-minute talk titled Renovate/Dependabot, ou comment reprendre le contrôle sur la mise à jour de ses dépendances. The session explored how tools like Dependabot and Renovate automate dependency updates, reducing the tedious and error-prone manual process. Through a demo and lessons from open-source and client projects, they shared practical tips for implementing Renovate, highlighting its benefits and pitfalls. 🚀
The Pain of Dependency Updates
The talk opened with a relatable skit: Lise, working on a side project (a simple Angular 6 app showcasing women in tech), admitted to neglecting updates due to the effort involved. Jean-Philippe emphasized that this is a common issue across projects, especially in microservice architectures with numerous components. Updating dependencies is critical for:
- Security: Applying patches to reduce exploitable vulnerabilities.
- Features: Accessing new functionalities.
- Bug Fixes: Benefiting from the latest corrections.
- Performance: Leveraging optimizations.
- Attractiveness: Using modern tech stacks (e.g., Node 20 vs. Node 8) to appeal to developers.
However, the process is tedious, repetitive, and complex due to transitive dependencies (e.g., a median of 683 for NPM projects) and cascading updates, where one update triggers others.
Automating with Dependabot and Renovate
Dependabot (acquired by GitHub) and Renovate (from Mend) address this by scanning project files (e.g., package.json
, Maven POM, Dockerfiles) and opening pull requests (PRs) or merge requests (MRs) for available updates. These tools:
- Check registries (NPM, Maven Central, Docker Hub) for new versions.
- Provide visibility into dependency status.
- Save time by automating version checks, especially in microservice setups.
- Enhance reactivity, critical for applying security patches quickly.
Setting Up the Tools
Dependabot: Configured via a dependabot.yml
file, specifying ecosystems (e.g., NPM), directories, and update schedules (e.g., weekly). On GitHub, it integrates natively via project settings. GitLab users can use a similar approach.
# dependabot.yml version: 2 updates: - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly"
Renovate: Configured via a renovate.json
file, extending default presets. It supports GitHub and GitLab via apps or CI/CD pipelines (e.g., GitLab CI with a Docker image). For self-hosted setups, Renovate can run as a Docker container or Kubernetes CronJob.
# renovate.json { "extends": [ "config:recommended" ] }
In their demo, Jean-Philippe and Lise showcased Renovate on a GitLab project, using a .gitlab-ci.yml
pipeline to run Renovate on a schedule, creating MRs for updates like rxjs
(from 6.3.2 to 6.6.7).
Customizing Renovate
Renovate’s strength lies in its flexibility through presets and custom configurations:
- Presets: Predefined rules (e.g.,
npm:unpublishSafe
waits 3 days before proposing updates). Presets can extend others, forming a hierarchy (e.g.,config:recommended
extends base presets). - Custom Presets: Organizations can define reusable configs in a dedicated repository (e.g.,
renovate-config
) and apply them across projects.
// renovate-config/default.json { "extends": [ "config:recommended", ":npm" ] }
- Grouping Updates: Combine related updates (e.g., all ESLint packages) using
packageRules
or presets likegroup:recommendedLinters
to reduce PR noise.
{ "packageRules": [ { "matchPackagePatterns": ["^eslint"], "groupName": "eslint packages" } ] }
- Dependency Dashboard: An issue tracking open, rate-limited, or ignored MRs, activated via the
dependencyDashboard
field or preset.
Going Further: Automerge and Beyond
To streamline updates, Renovate supports automerge, automatically merging MRs if the pipeline passes, relying on robust tests. Options include:
automerge: true
for all updates.automergeType: "pr"
orstrategy
for specific behaviors.- Presets like
automerge:patch
for patch updates only.
The demo showed an automerged rxjs
update, triggering a new release (v1.2.1) via semantic-release, tagged, and deployed to Google Cloud Run. A failed Angular update (due to a major version gap) demonstrated how failing tests block automerge, ensuring safety.
Renovate can also update itself and its configuration (e.g., deprecated fields) via the config:migration
preset, creating MRs for self-updates.
Lessons Learned and Recommendations
From their experiences, Jean-Philippe and Lise shared key tips:
- Manage PR Overload: Limit concurrent PRs (e.g.,
prConcurrentLimit: 5
) and group related updates to reduce noise. - Use Schedules: Run Renovate at off-peak times (e.g., nightly) to avoid overloading CI runners and impacting production deployments.
- Ensure Robust Tests: Automerge relies on trustworthy tests; weak test coverage can lead to broken builds.
- Balance Frequency: Frequent runs catch updates quickly but risk conflicts; infrequent runs may miss critical patches.
- Monitor Resource Usage: Excessive pipelines can strain runners and increase costs in autoscaling environments (e.g., cloud platforms).
- Handle Transitive Dependencies: Renovate manages them like direct dependencies, but cascading updates require careful review.
- Support Diverse Ecosystems: Renovate works well with Java (e.g., Spring Boot, Quarkus), Scala, and NPM, with grouping to manage high-dependency ecosystems like NPM.
- Internal Repositories: Configure Renovate to scan private registries by specifying URLs.
- Major Updates: Use presets to stage major updates incrementally, avoiding risky automerge for breaking changes.
Takeaways
Jean-Philippe and Lise’s talk highlighted how Dependabot and Renovate transform dependency management from a chore to a streamlined process. Their demo and practical advice showed how Renovate’s flexibility—via presets, automerge, and dashboards—empowers teams to stay secure and up-to-date, especially in complex microservice environments. However, success requires careful configuration, robust testing, and resource management to avoid overwhelming teams or infrastructure. 🌟