All of our projects have external dependencies.
It's always a good idea to keep them up-to-date. Here are a few reasons why:
Fortunately, dependabot is here to save the day.
It's a tool from GitHub that can be easily integrated with your repositories. If you haven't heard about it yet, go and check their awesome docs.
Dependabot monitors for vulnerabilities and updates in the dependencies of your project.
It opens PRs, to a target branch, on a scheduled period of time.
Each PR contains:
The pull requests are opened per dependency, meaning that if there are 10 packages that need to be updated, dependabot will open 10 PRs.
Additionally, when we merge something, dependabot will rebase the rest of its opened PRs. This is great because dependabot will automatically make sure that the PR is against the latest version of the target branch.
We're free to decide what to do with the dependabot's PRs:
In this blog post, we'll tell you what's the process that we follow.
We'll go through the basic depentabot setup.
dependabot.yml file. It should be located in the
.github/ directory of your repository.
your_repository/ |-- .github/ | |-- dependabot.yml
Add the following lines to the file and save it:
version: 2 updates: # Enable version updates for Python - package-ecosystem: "pip" directory: "/" # Check for updates once a week schedule: interval: "weekly"
NOTE! We're going to setup dependabot for a Python repository. Change the
package-ecosystemif you'd like to make it work for another language. Here is a list of all available options.
You can find a full list of the
.yml config options here.
Push this file to the default branch of your your origin and you're ready! Dependabot will start making PRs to your repository every week.
You can assert if everything is fine by checking the
Dependency Graph under the
Insights tab in your GitHub repository. Click on
Dependabot and you should see something like this:
In most cases, you'd be good to go with the default Dependabot configuration.
In case merging dependency updates straight to your default branch sounds a bit reckless to you, we can improve our setup.
The potential issues of merging straight to the default branch are:
If we want to avoid that, we have a couple of options:
We prefer the second option. Here is what we need to do next to accomplish that.
Create a new branch and push it to our origin.
$ git checkout master $ git pull origin master $ git checkout -b dependencies $ git push origin dependencies
Now, go to the
.github/workflows/dependabot.yml file and add
target-branch: "dependencies". Here is how the file should look like:
version: 2 updates: # Enable version updates for Python - package-ecosystem: "pip" directory: "/" # Check for updates once a week schedule: interval: "weekly" target-branch: "dependencies"
That's it! The next time dependabot creates a new PR it'll be targeted to the new
Our goal is to merge all dependabot PRs into the
dependencies branch. This will allow us to test if everything is fine with them before we push them to our default branch.
Here is how a typical PR from the
dependencies branch would look like once we merge all of the dependabot PRs:
There are a couple of considerations that we need to take into account about our new
We have a branch rule in our repository - the branches of all PRs that are merged are being deleted after that. We don't want this for the
dependencies branch. We don't want to allow anybody to delete it at all.
We can prevent this from happening by adding a new branch protection rule.
Go to your GitHub repository settings and a new branch protection rule:
We also want to allow force pushes to your branch (it's disabled by default). This will let you fix the branch if there is a problem with the git history.
Here is what we've achieved so far:
dependenciesinto the default branch and we are good to go.
The problem here is at the 4th step.
dependencies to always be up to date with our default branch.
This is something that we can easily forget to do, since it needs to be done by hand.
Wouldn't it be nice if we can keep
dependencies equal with the default branch without doing any extra manual actions?
Here is how we solved this. GitHub Actions is the tool that we're searching for!
Heads up 👀 We have additional GitHub Actions related articles - GitHub Actions in action - Setting up Django and Postgres and Optimize Django build to run faster on GitHub Actions
To set up a new GitHub action, we need to add a new
.yml file (we name it
rebase_dependencies.yml) to our
.github directory. It should be located in the
your_repository/ |-- .github/ | |-- workflows/ | | | -- rebase_dependencies.yml | |-- dependabot.yml
Here is the content of your file:
name: Automatic Rebase on: push: branches: - master jobs: rebase: name: Rebase `dependencies` with `master` runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 0 # otherwise, you will fail to push refs to dest repo ref: dependencies - run: | git config user.name github-actions git config user.email email@example.com git rebase origin/master git push origin dependencies --force
Here is what this configuration means in simple words:
--forcebecause of the
It's fine if you prefer to use
--force-with-leaseto prevent from some unexpected outcomes.
If you don't want to use the built-in
github-actionsuser, you can add a new PAT and configure the action to work with the user that's associated with it.
To assert that everything is fine with our new workflow, we can go to the
Actions tab in the GitHub Repository. The name of the workflow ("Automatic Rebase") should be visible in the left sidebar:
We should see a new workflow run on every new commit in the
In this article, we showed you how we use the powers of GitHub Actions and dependabot to keep the external dependencies of our projects up-to-date.
We hope we make your dev life better!
Stay tuned to our blog for more posts like this!