Keeping dependencies up to date in open source becomes easier with automation tools.
Maintaining up-to-date dependencies in open source is a laborious but necessary task to get patches for security vulnerabilities and bug fixes. It also needs to be done regularly to prevent a buildup of technical debt. Dealing with a large number of repos makes the task more challenging.
Fortunately, automation tools such as Snyk, Renovate and Dependabot can make the job considerably easier. These bots can be very helpful in dependency analysis, sending alerts when dependencies are broken or when vulnerable versions of external libraries are in use.
In this blog, we take a closer look at how Dependabot helps automate the task of dependency maintenance. Having been acquired by GitHub, Dependabot is available natively free of charge, and it’s certainly worth trying if you’re looking for an easier approach to keeping dependencies up to date.
Every day, Dependabot pulls down your dependency files and looks for any outdated requirements. If any dependencies are out of date, Dependabot opens individual pull requests to bump each one. All you need to do is check your tests pass, scan the included changelog and release notes and decide whether to merge or skip the new version.
Here is an example of a Dependabot pull request:
To proceed with this version bump, simply approve the PR, and Dependabot will merge it for you. However, if you’re managing multiple repos, you need to manually review each pull request and approve it to let Dependabot merge for you. These gaps in automation can be addressed with fastify/github-action-merge-dependabot github action.
Automating PR merges
It’s possible to reduce your PR noise by automatically merging Dependabot PRs that pass the CI checks using fastify/github-action-merge-dependabot. After an easy setup, this Github action looks over all Dependabot PRs and merges them for you. The screenshot below shows a Dependabot PR that was merged automatically after the CI checks passed.
The fastify ecosystem is huge. Furthermore, it has hundreds of dependencies that need to be monitored and upgraded as new versions come out. Doing this manually is not practical, so we created an action to simplify the task.
To configure this action in your Github workflow, first create a simple CI workflow:
Setting up the CI
On: [push, pull_request]
- uses: actions/[email protected]
- uses: actions/[email protected]
- run: npm ci
- run: npm test
This is a very basic example of running tests in Github actions. It completes the following steps:
Gets triggered on push and pull_request events
Checks out the repo
Sets up given node version (v14 in this case)
In practice, several more checks may be configured, but most of these will apply to the code changes. If you have good test coverage in your repo, a green pipeline with passing tests should be enough to give you confidence in the dependency bump.
This workflow can be extended to add auto-merging:
Here, we simply create another job in the workflow called automerge, which primarily does the following:
Waits for the test job to finish (using needs). This is important because it delays the execution of this job until the specified job(s) is finished successfully. If you have more than one job you’d like to wait for (e.g. test & build), you can pass them as an array, just like needs: [test, build].
Has a conditional expression that prevents this job from running for any event other than pull_request and any PR other than the one from Dependabot.
Note: The github_token is already provided by Github actions that we can access using secrets.github_token and supply as an input.
For packages that you want to be extra sure about before bumping their version, you can supply an exclude input to the action with an array of package names. Whenever it finds a Dependabot PR that upgrades packages from the exclude list, it skips auto-merging.
Acceptable values for merge-method input are: merge, squash & rebase.
How it works
fastify/github-action-merge-dependabot is a very simple yet useful tool. Here’s how it works under the hood:
When triggered, it checks if the PR user is strictly dependabot[bot]. If not, it does noop. This is to ensure that no other PR is touched.
It checks if the bumped dependency is one of the excluded ones. If so, it does noop.
If it passes these two checks, it simply approves the PR and merges it.
Beware of vulnerabilities
Automating the landing of dependencies in this way might introduce new vulnerabilities in the code without the developers knowing about it. Unfortunately, most developers would land those updates with little or no review; the proposed actions will essentially automate that behaviour. It is important to counterbalance this by some scrutiny — either by a human before releases or automatically, using tools such as Snyk or npm audit.
Iterative improvements are better than big-bang changes. With this strategy, it is important to stay up to date. Other apps can help you achieve this, but Dependabot is one of the easiest to set up and use. It’s also free and natively available in Github and has an open-source core.