As a developer of several open source libraries using Angular, React, and Next.js, I have struggled with keeping them up-to-date and ensuring a smooth user experience for updates.
Especially if I rarely used my published libraries, they often ended up being outdated.
Problem with manual updates
I relied on 2 methods:
- periodical manual checkup on all my repositories
- wait for the user to submit a new issue
Both methods are obviously wrong. I end up with my library being obsolete for too long and user might end up frustrated if he wants to update to new version, but my library causes a bump on the road.
Semi automate
I considered several methods to semi-automate updating:
- Use built-in tools like Dependabot or Renovate.
- Building my own scheduled GitHub action that checks for outdated dependencies and opens a new issue
However, creating a custom GitHub action might not cover all use cases, such as avoiding the creation of a new issue if it's already reported, and it wouldn't be language agnostic.
Dependabot
First choice, as it's already blended into GitHub repositories. At first it can be an annoying little intrusive tool that occasionally opens up several pull requests in a row. In response, I would often close these pull requests, preferring to verify the dependency updates manually to ensure they didn't introduce any issues. This led me to frequently disable Dependabot altogether.
But instead of disabling it, I should have fine tuned it.
In .github/dependabot.yml you can specify a frequency of checkups and list dependencies that dependabot should ignore or list dependencies that dependabot should focus on.
e.g.
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
allow:
- dependency-name: "mongoose"
In this example, I configured Dependabot to check for new Mongoose versions weekly and open a PR with proposed changes.
One downside of Dependabot is that it lacks certain configuration options, such as targeting specific dependency update types or monitoring versions up to a certain point.
Renovate
In contrast to Dependabot, Renovate offers more intuitive package rules. For example, I can define a package rule that matches package names containing "angular" and allows versions less than or equal to 16. This level of customization can be helpful in ensuring that updates don't cause unexpected problems.
{
"packageRules": [
{
"matchPackageNames": ["angular"],
"allowedVersions": "<=16"
}
]
}"
More on available package rules here https://docs.renovatebot.com/configuration-options/#packagerules
Using Renovate on Github
Renovate can be used in two ways:
- As a self hosted github app - To be able to use renovatebot on Github, you have to install it as an app. Navigate to https://github.com/apps/renovate and click install. Select which repositories you want renovate to access.
- Use renovate bot - You would need to define a RENOVATE_TOKEN and scope permissions, and
Add a github action that runs renovatebot.
By using the GitHub app, whenever you push to the repository, renovate app will read from renovate.json
and according to its configuration check dependencies. It will then open a PR if there's any matching dependency that needs updating. I chose the option with self hosted Github app.
Defining package rules
Package rules are more configurable with Renovate than Dependabot, though they can get complicated. For example, the following configuration instructs Renovate to only monitor major updates for Mongoose and ignore all other dependencies:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"packageRules": [
{
"packagePatterns": ["*"],
"excludePackagePatterns": ["mongoose"],
"enabled": false
},
{
"matchUpdateTypes": [
"major"
],
"matchPackageNames": [
"mongoose"
],
"enabled": true
}
]
}