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.

Using Dependabot

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.

It supports a large selection of languages, including Ruby, Python, JavaScript and PHP. You can configure Dependabot via .github/dependabot.yml file, where you can set the update schedule and limit the number of open PRs etc. Check out the documentation to find out more about the config options.

Here is an example of a Dependabot pull request:

Dependabot screenshot

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.

Dependabot PR screenshot

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

name: my-package

On: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v1
        with:
          node-version: 14
      - 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)
  • Installs dependencies
  • Runs tests

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.

Auto-merging

This workflow can be extended to add auto-merging:

automerge:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: fastify/github-action-merge-dependabot@v1
        if: ${{ github.actor == 'dependabot[bot]' &&
 github.event_name == 'pull_request' }}
        with:
          github-token: ${{secrets.github_token}}

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 step that uses fastify/github-action-merge-dependabot@v1 action
  • 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.

Excluding packages

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.

Example:

with:
    github-token: ${{secrets.github_token}}
    exclude: ['pkg-1', 'pkg-2']

Changing merge method

By default, the action will try to auto-merge Dependabot PRs using squash merge. However, it is configurable, so you can pass another input as shown below to change the merge method of your choice.

Example:

with:
    github-token: ${{secrets.github_token}}
    merge-method: 'merge'

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.

Conclusion

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.

Don’t miss a beat

Get all the latest NearForm news,
from technology to design.
View all posts  |  Technology  |  Business  |  Culture  |  Opinion  |  Design
Follow us for more information on this and other topics.