upsidr/merge-gatekeeper

Get better merge control

Go

142

120 commits

updated Oct 6, 2026

See the code

README

Merge Gatekeeper

Merge Gatekeeper provides extra control for Pull Request management.

🌄 What Does Merge Gatekeeper Provide, and Why?

Pull Request plays a significant part in day-to-day development, and it is essential to ensure all merges are well controlled and managed to build robust system. GitHub provides controls over CI, reviews, etc., but there are some limitations around handling specific use cases. Merge Gatekeeper helps overcome those by adding extra controls, such as monorepo friendly branch protection.

At UPSIDER, we have a few internal repositories set up with a monorepo structure, with many types of code in a single repository. This comes with its own pros and cons, but one difficulty is how we end up with various CI jobs, which only run for changes that touch relevant files. With GitHub's branch protection, there is no way to specify "Ensure Go build and test pass if and only if Go code is updated", or "Ensure E2E tests are run and successful if and only if frontend code is updated". This is due to the GitHub branch protection design to specify a list of jobs to pass, which is only driven by the target branch name, regardless of change details. Because of this limitation, we would either need to run all the CI jobs for any Pull Requests, or do not set any limitation based on the CI status. (*1)

Merge Gatekeeper was created to provide more control for merges. By placing Merge Gatekeeper to run for all PRs, it can check all other CI jobs that get kicked off, and ensure all the jobs are completed successfully. If there is any job that has failed, Merge Gatekeeper will fail as well. This allows merge protection based on Merge Gatekeeper, which can effectively ensure any CI failure will block merge. All you need is the Merge Gatekeeper as one of the PR based GitHub Action, and set the branch protection rule as shown below.

Branch protection example

We are looking to add a few more features, such as extra signoff from non-coder, label based check, etc.

NOTE:
(*1) There are some other hacks, such as using an empty job with the same name to override the status, but those solutions do not provide the flexible control we are after.

You can find more details here.

🚀 How Can I Use Merge Gatekeeper?

The easiest approach is to copy the standard definition, and save it under .github/workflows directory. There is no further modification required unless you have some specific requirements.

With curl

curl -sSL https://raw.githubusercontent.com/upsidr/merge-gatekeeper/main/example/merge-gatekeeper.yml \
  > .github/workflows/merge-gatekeeper.yml

Directly copy YAML

The below is the copy of /example/merge-gatekeeper.yml, with extra comments.

---
name: Merge Gatekeeper

on:
  pull_request:
    branches:
      - main
      - master

jobs:
  merge-gatekeeper:
    runs-on: ubuntu-latest
    # Restrict permissions of the GITHUB_TOKEN.
    # Docs: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
    permissions:
      checks: read
      statuses: read
    steps:
      - name: Run Merge Gatekeeper
        # NOTE: Pinned to commit SHA for supply-chain safety. Update by replacing
        #       both the SHA and the version tag in the trailing comment.
        #       https://github.com/upsidr/merge-gatekeeper/tags
        #       https://github.com/upsidr/merge-gatekeeper/branches
        uses: upsidr/merge-gatekeeper@09af7a82c1666d0e64d2bd8c01797a0bcfd3bb5d # v1.2.1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

You can find more details here.

🧪 Action Inputs

There are some customisation available for Merge Gatekeeper.

NameDescriptionRequired
tokenGITHUB_TOKEN or Personal Access Token with repo scopeYes
selfThe name of Merge Gatekeeper job, and defaults to merge-gatekeeper. This is used to check other job status, and do not check Merge Gatekeeper itself. If you updated the GitHub Action job name from merge-gatekeeper to something else, you would need to specify the new name with this value.
intervalCheck interval to recheck the job status. Default is set to 5 (sec).
timeoutTimeout setup to give up further check. Default is set to 600 (sec).
initial-delayDelay in seconds before the first validation. Useful when other jobs are known to take a while, to avoid needless polling at the start. This delay is not counted towards timeout. Default is set to 0 (sec).
ignoredJobs to ignore regardless of their statuses. Defined as a comma-separated list.
refGit ref to check out. This falls back to the HEAD for given PR, but can be set to any ref.

You can find more details here.

ci
github-action
github-actions-docker
go
pull-request

upsidr/merge-gatekeeper

Get better merge control

Go

142

120 commits

updated Oct 6, 2026

See the code

README

Merge Gatekeeper

Merge Gatekeeper provides extra control for Pull Request management.

🌄 What Does Merge Gatekeeper Provide, and Why?

Pull Request plays a significant part in day-to-day development, and it is essential to ensure all merges are well controlled and managed to build robust system. GitHub provides controls over CI, reviews, etc., but there are some limitations around handling specific use cases. Merge Gatekeeper helps overcome those by adding extra controls, such as monorepo friendly branch protection.

At UPSIDER, we have a few internal repositories set up with a monorepo structure, with many types of code in a single repository. This comes with its own pros and cons, but one difficulty is how we end up with various CI jobs, which only run for changes that touch relevant files. With GitHub's branch protection, there is no way to specify "Ensure Go build and test pass if and only if Go code is updated", or "Ensure E2E tests are run and successful if and only if frontend code is updated". This is due to the GitHub branch protection design to specify a list of jobs to pass, which is only driven by the target branch name, regardless of change details. Because of this limitation, we would either need to run all the CI jobs for any Pull Requests, or do not set any limitation based on the CI status. (*1)

Merge Gatekeeper was created to provide more control for merges. By placing Merge Gatekeeper to run for all PRs, it can check all other CI jobs that get kicked off, and ensure all the jobs are completed successfully. If there is any job that has failed, Merge Gatekeeper will fail as well. This allows merge protection based on Merge Gatekeeper, which can effectively ensure any CI failure will block merge. All you need is the Merge Gatekeeper as one of the PR based GitHub Action, and set the branch protection rule as shown below.

Branch protection example

We are looking to add a few more features, such as extra signoff from non-coder, label based check, etc.

NOTE:
(*1) There are some other hacks, such as using an empty job with the same name to override the status, but those solutions do not provide the flexible control we are after.

You can find more details here.

🚀 How Can I Use Merge Gatekeeper?

The easiest approach is to copy the standard definition, and save it under .github/workflows directory. There is no further modification required unless you have some specific requirements.

With curl

curl -sSL https://raw.githubusercontent.com/upsidr/merge-gatekeeper/main/example/merge-gatekeeper.yml \
  > .github/workflows/merge-gatekeeper.yml

Directly copy YAML

The below is the copy of /example/merge-gatekeeper.yml, with extra comments.

---
name: Merge Gatekeeper

on:
  pull_request:
    branches:
      - main
      - master

jobs:
  merge-gatekeeper:
    runs-on: ubuntu-latest
    # Restrict permissions of the GITHUB_TOKEN.
    # Docs: https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
    permissions:
      checks: read
      statuses: read
    steps:
      - name: Run Merge Gatekeeper
        # NOTE: Pinned to commit SHA for supply-chain safety. Update by replacing
        #       both the SHA and the version tag in the trailing comment.
        #       https://github.com/upsidr/merge-gatekeeper/tags
        #       https://github.com/upsidr/merge-gatekeeper/branches
        uses: upsidr/merge-gatekeeper@09af7a82c1666d0e64d2bd8c01797a0bcfd3bb5d # v1.2.1
        with:
          token: ${{ secrets.GITHUB_TOKEN }}

You can find more details here.

🧪 Action Inputs

There are some customisation available for Merge Gatekeeper.

NameDescriptionRequired
tokenGITHUB_TOKEN or Personal Access Token with repo scopeYes
selfThe name of Merge Gatekeeper job, and defaults to merge-gatekeeper. This is used to check other job status, and do not check Merge Gatekeeper itself. If you updated the GitHub Action job name from merge-gatekeeper to something else, you would need to specify the new name with this value.
intervalCheck interval to recheck the job status. Default is set to 5 (sec).
timeoutTimeout setup to give up further check. Default is set to 600 (sec).
initial-delayDelay in seconds before the first validation. Useful when other jobs are known to take a while, to avoid needless polling at the start. This delay is not counted towards timeout. Default is set to 0 (sec).
ignoredJobs to ignore regardless of their statuses. Defined as a comma-separated list.
refGit ref to check out. This falls back to the HEAD for given PR, but can be set to any ref.

You can find more details here.

ci
github-action
github-actions-docker
go
pull-request

Project health

Overall

5.2/10

Maintained

3/10

Code review

10/10
OpenSSF Scorecard

Latest release

v1.2.1 · Jan 29, 2023

Releases this year

0

Significant stargazers

Maximilian Roos

1,930 followers · starred May 2022

Maxime Brunet

52 followers · starred Mar 2025

Pi

124 followers · starred Apr 2022

Shohei Ueda

618 followers · starred Jun 2025