Enforcing Protected Branches with Required CI Checks and Reviewers on GitHub
Learn how to lock your main branch, block direct pushes, and require CI checks and a set number of approving reviews before a pull request can merge. Follow the step-by-step guide, verify the rule, and handle emergency merges safely.
02 Sept 2026, 07:17 UTC

Goal: Block Direct Pushes and Require CI & Reviews
After this guide you will have a protected branch (e.g., main) that cannot receive force pushes, direct pushes, or merges that bypass status checks and review counts. Pull requests must pass all CI jobs and obtain the configured number of approving reviews before the Merge button becomes active.
Prerequisites
- Admin access to the repository or an organization role that can edit branch rules.
- At least one CI workflow configured (e.g., GitHub Actions) that reports status checks with known names.
- Decide on the required number of approvals (the default is one).
- Optional: a list of branches that should be protected or a branch pattern (e.g.,
mainorrelease/*).
Step-by-Step Configuration
- Navigate to the Settings page of the repository. You must be on the
Settingstab, notCodeorInsights. - Open Branch protection rules. From the left sidebar, click Branches and then the Add rule button.
- Define the branch pattern. Enter
main(or your chosen pattern). The pattern supports glob syntax (e.g.,release/*). - Require a pull request before merging. Check the box and set the required approving reviews to the desired number (e.g.,
2). Optionally enable Dismiss stale pull request approvals when new commits are pushed for stricter review enforcement. - Require status checks to pass before merging. Check this option, then click Search status checks…. GitHub will list status checks that have run on the repository. Select the exact names your CI workflow reports, for example
build,test, andlint. Click Save changes once all desired checks are selected. - Optional: Require branches to be up to date before merging. Enabling this forces the PR to be rebased or merged with the latest base before the merge button appears. This prevents stale code from passing CI on an old base commit.
Example GitHub Actions Workflow That Generates Status Checks
name: CI
on:
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run build
run: echo "Building"
test:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/checkout@v4
- name: Run tests
run: echo "Testing"
Each job (build and test) produces a status check with the same name. These are the names you will select in the protection rule.
Verifying the Rule
- Attempt a direct push from a non-bypass account. Try
git push origin main. GitHub should reject it with a branch protection error (typically a pre-receive hook decline). - Create a test pull request that fails a CI job (e.g., modify the workflow to fail deliberately). The PR merge button should remain disabled until the job succeeds.
- Open a PR that passes all checks but has fewer approvals than required. The merge button stays disabled until the approval threshold is met.
- Audit the rule by revisiting Settings > Branches and confirming the pattern, required reviews, and selected status checks.
Rollback & Emergency Merge
Changing a rule is a state-changing operation. If you accidentally mis-select a status check or need an urgent merge:
- To correct a status check name, edit the rule, deselect the incorrect check, and re-select the proper one.
- To perform an emergency merge, an admin can temporarily disable the rule or adjust its requirements for a single commit. After the merge, re-enable the rule immediately.
- Always review the audit log (repository or organization level, depending on your plan) to see who changed the rule and when.
Using Rulesets for Organization-Wide Policies
For organizations that need consistent rules across many repos, Rulesets provide a more granular, organization-level approach. Navigate to Settings > Rules > Rulesets, create a new ruleset, and select the same options as above. Rulesets support bypass lists and an evaluate mode, so you can observe what would be blocked before enforcing the rules.
Limitations & Practical Checks
- Check names must match exactly; renaming a workflow job will break the rule until it is updated.
- Enabling “Require branches to be up to date” can increase merge friction in fast-moving repos because it forces frequent rebases.
- Admins can bypass protection by default; consider restricting bypass via rulesets if compliance matters.
- UI labels and ruleset capabilities change over time and differ between free, Pro, and Enterprise plans.
After configuring, test the rule with a non-admin account to confirm the expected behavior. If the rule behaves as described, your branch is now protected against direct pushes and merges that do not satisfy CI and review requirements.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.