Auto Merge Dependabot Pull Requests with GitHub Actions

• 4 min read

A good year ago it was announced that Dependabot is being integrated natively into GitHub. This task is soon complete, as the old Dependabot ("Dependabot Preview") will be shut down on August 3rd, 2021.1

A feature that is still missing in the native GitHub integration is the option to auto merge Dependabot Pull Requests after a successful CI run.

As so often these days, I've solved this problem by using GitHub Actions. Here's how I've done it.

Before we begin

On March 1st, 2021 GitHub changed how permissions work in GitHub Actions runs triggered by Dependabot. Since March 1st the GITHUB_TOKEN is ready only.

This means that any Workflow run that is triggered by Dependabot can not change anything in your repository. It can't add new files nor can it auto merge the Pull Request. (This change broke my previous approach to auto-merge which ran in the same Workflow as my normal Continous Integration checks)

The Workflow

First you need a GitHub Actions Workflow that tests that the introduced changes didn't break anything.

This Workflow ususally runs your test suite or generates a new build of your software.

In this article we're going to use my Alfred Emoji pack project as an example. It's a PHP console application that generates an Emoji snippet pack for Alfred.

I've called the Workflow "Integrate" and it looks like this:

name: Integrate

on:
    push:
        branches:
            - main
    pull_request:

jobs:
    build:
        name: Build

        runs-on: ubuntu-latest

        steps:
            - name: Checkout code
              uses: actions/checkout@v2

            - name: Setup PHP
              uses: shivammathur/setup-php@v2
              with:
                  php-version: 8.0
                  extension: zip, json

            - name: Install dependencies
              run: composer install --prefer-dist --no-interaction --no-suggest

            - name: Generate new Emoji Pack
              run: php app generate

If you're new to GitHub Actions, this syntax might look confusing. But don't worry, it's easy to understand. The code above tells GitHub Actions:

  • To run this Workflow whenever a commit is made to the main-branch or when a Pull Request is opened or a new commit is made to a Pull Request.
  • To run this Workflow on a server running Ubuntu.
  • To install PHP 8.0 and the project's dependencies
  • And to execute php app generate to create a new Snippet pack

This simple Workflow ensures that the app works as expected. In an application with a Phpunit test suite you would run vendor/bin/phpunit instead of php app generate. Or if you work in Node you might run something like npm run test.

Now that we can be sure that nothing breaks when Dependabot opens a Pull Request, we want to automatically merge it.

For this we create a new Workflow which uses the fantastic ridedott/merge-me Action. First create a new file in .github/workflows called auto-merge.yml.

Inside we add the following code:

name: Merge me!

on:
    workflow_run:
        types:
            - completed
        workflows:
            - 'Integrate'

jobs:
    merge-me:
        name: Merge me!

        runs-on: ubuntu-latest

        steps:
            - name: Merge me!
              if: ${{ github.event.workflow_run.conclusion == 'success' }}
              uses: ridedott/merge-me-action@v2
              with:
                  # Depending on branch prodtection rules, a  manually populated
                  # `GITHUB_TOKEN_WORKAROUND` secret with permissions to push to
                  # a protected branch must be used.
                  #
                  # When using a custom token, it is recommended to leave the following
                  # comment for other developers to be aware of the reasoning behind it:
                  #
                  # This must be used as GitHub Actions token does not support pushing
                  # to protected branches.
                  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
                  PRESET: DEPENDABOT_MINOR

The code is straight from the example of the Action itself. But I would like to go through the Workflow quickly and explain what it does.

on:
    workflow_run:
        types:
            - completed
        workflows:
            - 'Integrate'

At the beginning, we tell the Workflow to listen to the completed event of other Workflows. As you can see under the workflows array, I've added the name of my previously mentioned Workflow "Integrate". This means that this Workflow will be triggered, whenever my "Integrate" run is completed.

steps:
    - name: Merge me!
      if: ${{ github.event.workflow_run.conclusion == 'success' }}
      uses: ridedott/merge-me-action@v2
      with:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PRESET: DEPENDABOT_MINOR

Next to the core of the Workflow. Before the ridedott/merge-me-action is executed, we check if the "Integrate" run – that triggered this Workflow run – was successful. This protects us from auto merging Dependabot Pull Requests which break our application.

As my repository doesn't use protected branches, I use the default token GitHub provides by using secrets.GITHUB_TOKEN. (Read the merge-me-action docs for more details on how to use it with protected branches).

The PRESET is set to DEPENDABOT_MINOR. This will tell the Action to merge minor and patch dependency updates automatically. If you want to go the safer route, use DEPENDABOT_PATCH to only merge patch dependency updates. (Read more about this feature in the docs)

And that's it!
Commit and push the new auto-merge.yml Workflow to your GitHub repository and when new Dependabot Pull Requests come in, they will be automatically be merged if your test suite or build is successful.

Example Pull Request

As mentioned earlier, the "Integrate" Workflow is from my "alfred-emoji-pack" project. In #17 you find a Pull Request that has been created by Dependabot and has then been automatically merged by GitHub Actions.

Conclusion

As you can see, adding an auto-merge feature to your GitHub repository isn't that complicated at all. All you need is an existing Workflow that checks if everything in your app works and a second Workflow that "listens" to your first "Continous Integration" Workflow.

I hope that the native integration of Dependabot in GitHub is now stable enough that this approach will still work in 12 months time and will save me countless hours of merging Pull Requests.

Before I leave you, there is one caveat: The "auto-merge" Workflow run will not be shown in the Pull Request "checks" list, as the Workflow is not triggered through the pull_request Event.


  1. I've learned about the end of Dependabot Preview through a Pull Request in my dotfiles repository

Webmentions