Preventing a pull request from being merged until it's safe

Sometimes, a pull request is ready to go, but shouldn't be merged before some other changes are merged first. While the patch is valid on its own, it might depend on other changes, and could even break the application if merged before the other.

I'll demonstrate a simple technique relying on Github Actions and pull request labels to fully block a pull request from being merged until deemed safe (at least without some admin privileges on the repository).

First, we introduce a Github Actions workflow executed when a pull request is opened, labeled or unlabeled. This workflow will fail if labeled with do not merge.

name: Check do not merge

on:
  # Check label at every push in a feature branch
  push:
    branches-ignore:
      - main
  # Check label during the lifetime of a pull request
  pull_request:
    types:
    - opened
    - labeled
    - unlabeled

jobs:
  fail-for-do-not-merge:
    if: contains(github.event.pull_request.labels.*.name, 'do not merge')
    runs-on: ubuntu-latest
    steps:
      - name: Fail if PR is labeled with do not merge
        run: |
          echo "This PR can't be merged, due to the 'do not merge' label."
          exit 1

We then define a branch protection rule for our main branch, by going to the repository Settings, then Branches. We add a new rule if none exist, tick Require status checks to pass before merging, and add the fail-for-do-not-merge to the list of required checks.

Finally, apply the do not merge label to your pull request.

At that point, the fail-for-do-not-merge check will run and fail, preventing the PR to be merged.

When the pull request is finally safe to merge, simply remove the do not merge tag, and the checks will automagically pass, thus allowing you to merge.

Comments