Merging pull requests with GitHub Actions

In May 2019, GitHub acquired Dependabot, and recently GitHub announced that Dependabot is moving into GitHub.

When you follow the instructions, you will find that the migration is straightforward. However, there is one thing missing: after migrating from version 1 to version 2, Dependabot will not automatically merge pull requests anymore. That the feature is currently missing could indicate that GitHub will bring automatic merges onboard - independently from Dependabot.

In the meantime, you can configure a workflow with GitHub Actions and actions/github-script that will automatically merge pull requests created by Dependabot. actions/github-script uses octokit/rest.js, which is well documented, and it is often more convenient to use than maintaining a full-blown GitHub action.

Here is an example of a workflow that will run when the Integrate workflow has successfully completed for a pull request opened by dependabot[bot] that updates development or production dependencies for composer, or updates GitHub actions.

name: "Merge"

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

jobs:
  merge:
    name: "Merge"

    runs-on: "ubuntu-latest"

    if: >
      github.event.workflow_run.event == 'pull_request' &&
      github.event.workflow_run.conclusion == 'success' &&
      github.actor == 'dependabot[bot]' && (
        startsWith(github.event.workflow_run.head_commit.message, 'composer(deps)') ||
        startsWith(github.event.workflow_run.head_commit.message, 'composer(deps-dev)') ||
        startsWith(github.event.workflow_run.head_commit.message, 'github-actions(deps)')
      )

    steps:
      - name: "Request review from @ergebnis-bot"
        uses: "actions/github-script@v5"
        with:
          github-token: "${{ secrets.ERGEBNIS_BOT_TOKEN }}"
          script: |
            const pullRequest = context.payload.workflow_run.pull_requests[0]
            const repository = context.repo

            const reviewers = [
              "ergebnis-bot",
            ]

            await github.rest.pulls.requestReviewers({
              owner: repository.owner,
              repo: repository.repo,
              pull_number: pullRequest.number,
              reviewers: reviewers,
            })

      - name: "Assign @ergebnis-bot"
        uses: "actions/github-script@v5"
        with:
          github-token: "${{ secrets.ERGEBNIS_BOT_TOKEN }}"
          script: |
            const pullRequest = context.payload.workflow_run.pull_requests[0]
            const repository = context.repo

            const assignees = [
              "ergebnis-bot",
            ]

            await github.rest.issues.addAssignees({
              owner: repository.owner,
              repo: repository.repo,
              assignees: assignees,
              issue_number: pullRequest.number
            })

      - name: "Approve pull request"
        uses: "actions/github-script@v5"
        with:
          github-token: "${{ secrets.ERGEBNIS_BOT_TOKEN }}"
          script: |
            const pullRequest = context.payload.workflow_run.pull_requests[0]
            const repository = context.repo

            await github.rest.pulls.createReview({
              event: "APPROVE",
              owner: repository.owner,
              repo: repository.repo,
              pull_number: pullRequest.number,
            })

      - name: "Merge pull request"
        uses: "actions/github-script@v5"
        with:
          github-token: "${{ secrets.ERGEBNIS_BOT_TOKEN }}"
          script: |
            const pullRequest = context.payload.workflow_run.pull_requests[0]
            const repository = context.repo

            await github.rest.pulls.merge({
              merge_method: "merge",
              owner: repository.owner,
              pull_number: pullRequest.number,
              repo: repository.repo,
            })

You can see this workflow in action in ergebnis/php-package-template.

Since the workflow references pull request titles, it works best when using it in conjunction with an explicit configuration for Dependabot.

# https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2

updates:
  - commit-message:
      include: "scope"
      prefix: "composer"
    directory: "/"
    labels:
      - "dependency"
    open-pull-requests-limit: 10
    package-ecosystem: "composer"
    schedule:
      interval: "daily"
    versioning-strategy: "increase"

  - commit-message:
      include: "scope"
      prefix: "github-actions"
    directory: "/"
    labels:
      - "dependency"
    open-pull-requests-limit: 10
    package-ecosystem: "github-actions"
    schedule:
      interval: "daily"

Did you find this article helpful?

Follow @localheinz on Twitter Share post on Twitter