7 min read • Guide 327 of 877
Configuring Branch Protection Rules
Branch protection rules are your automated gatekeepers. They ensure code reviews happen, tests pass, and critical branches stay stable. Properly configured protection prevents costly mistakes and enforces team standards without manual policing.
Protection Options
| Protection | Purpose | Recommended |
|---|---|---|
| Require PR | No direct push | ✓ Always |
| Require review | Code quality | ✓ Always |
| Require CI | Tests pass | ✓ Always |
| Up to date | No merge conflicts | ✓ Usually |
| Block force push | Preserve history | ✓ Always |
GitHub Configuration
Setting Up Protection
GITHUB BRANCH PROTECTION
════════════════════════
ACCESS:
─────────────────────────────────────
Settings → Branches → Add rule
├── Branch name pattern: main
└── Configure protections
REQUIRED PROTECTIONS:
─────────────────────────────────────
☑ Require a pull request before merging
├── Required approvals: 1 (small team) or 2 (larger)
├── Dismiss stale pull request approvals
│ └── Changes after approval need re-review
├── Require review from Code Owners
│ └── Use CODEOWNERS file
└── Require approval of most recent push
└── Prevents sneaky commits after approval
☑ Require status checks to pass
├── Require branches to be up to date
├── Add checks:
│ ├── ci/build
│ ├── ci/test
│ ├── ci/lint
│ └── security/scan
└── All must pass before merge
☑ Require conversation resolution
└── All PR comments must be resolved
☑ Require signed commits (optional)
└── For high-security repos
PUSH RESTRICTIONS:
─────────────────────────────────────
☑ Restrict who can push to matching branches
├── Select allowed teams/users
├── Only for emergencies
└── Usually: nobody (all via PR)
☑ Do not allow bypassing the above settings
└── Even admins must follow rules
☑ Block force pushes
└── Protect history
☑ Block deletions
└── Can't delete protected branches
GitHub Rulesets
GITHUB RULESETS (NEWER)
═══════════════════════
ADVANTAGES OVER BRANCH RULES:
─────────────────────────────────────
├── Apply at organization level
├── Target multiple branches/repos
├── More granular bypass permissions
├── Tag rules included
├── Better audit trail
└── Recommended for enterprise
CREATING A RULESET:
─────────────────────────────────────
Repository → Settings → Rules → Rulesets
New ruleset:
├── Name: "Production Protection"
├── Enforcement: Active
├── Target branches: main, release/*
└── Configure rules
RULESET OPTIONS:
─────────────────────────────────────
Branch rules:
├── Restrict creations
├── Restrict updates
├── Restrict deletions
├── Require linear history
├── Require deployments to succeed
├── Require signed commits
├── Require a pull request
├── Require status checks
└── Block force pushes
Bypass list:
├── Repository admins
├── Specific teams (e.g., Release Team)
├── Deploy keys
└── Emergency access defined
GitLab Configuration
Protected Branches
GITLAB PROTECTED BRANCHES
═════════════════════════
ACCESS:
─────────────────────────────────────
Settings → Repository → Protected branches
CONFIGURATION:
─────────────────────────────────────
Branch: main
Allowed to merge:
├── Maintainers (common)
├── Developers + Maintainers
├── No one (via MR only)
└── Role-based control
Allowed to push:
├── No one (recommended)
├── Force CI/MR workflow
└── All changes via MR
Allowed to force push:
├── No (always)
└── Protects history
Code owner approval:
├── Required from CODEOWNERS
└── Domain expertise enforced
MERGE REQUEST SETTINGS:
─────────────────────────────────────
Settings → Merge Requests
☑ Pipelines must succeed
☑ All threads must be resolved
☑ Skipped pipelines considered successful: No
☑ Merge method: Merge commit / Squash / Rebase
└── Team preference
Status Checks
Requiring CI to Pass
STATUS CHECK CONFIGURATION
══════════════════════════
WHICH CHECKS TO REQUIRE:
─────────────────────────────────────
Essential:
├── Build: Must compile/build
├── Test: Unit tests pass
├── Lint: Code standards met
└── Non-negotiable gates
Recommended:
├── Security scan
├── Type checking
├── Integration tests
├── Coverage threshold
└── Higher quality bar
Optional:
├── Performance tests
├── Preview deployment
├── Documentation check
└── Nice-to-have
SETTING UP CHECKS:
─────────────────────────────────────
1. Create workflow that reports status:
name: CI
on: pull_request
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
- run: npm test
2. Add to required checks:
Settings → Branches → Edit rule
→ Add "build" to required checks
HANDLING FLAKY TESTS:
─────────────────────────────────────
Options:
├── Fix the flaky test (best)
├── Retry logic in CI
├── Remove from required (temporary)
└── Don't let flaky block team
Emergency Bypass
Handling Urgent Fixes
EMERGENCY PROCEDURES
════════════════════
BYPASS OPTIONS:
─────────────────────────────────────
Option 1: Bypass list
├── Specific people can bypass
├── Senior engineers / leads
├── Emergency-only usage
├── Audited in git history
└── Define in ruleset
Option 2: Hotfix branch rules
├── hotfix/* has lighter protection
├── Maybe 1 reviewer vs 2
├── Same CI requirements
├── Faster path for urgent
└── Separate protection rule
Option 3: Temporary disable
├── Admin disables rule
├── Push fix
├── Re-enable immediately
├── Document in incident log
├── Last resort
└── Has audit trail
EMERGENCY PROCESS:
─────────────────────────────────────
1. Create hotfix/* branch
2. Make minimal fix
3. Fast review (1 person)
4. CI must pass (abbreviated)
5. Merge to main
6. Cherry-pick to release if needed
7. Full post-mortem review
8. Log in incident record
BALANCE:
─────────────────────────────────────
├── Protection is important
├── Emergencies happen
├── Define process ahead of time
├── Don't make bypasses common
├── Review after every bypass
└── Continuous improvement
Code Owners
Domain-Based Review
CODEOWNERS FILE
═══════════════
PURPOSE:
─────────────────────────────────────
├── Automatic review assignment
├── Ensure right experts review
├── Ownership of code areas
├── Required approval for changes
└── Domain expertise enforcement
FILE LOCATION:
─────────────────────────────────────
.github/CODEOWNERS
# or
docs/CODEOWNERS
# or
CODEOWNERS (root)
SYNTAX:
─────────────────────────────────────
# Default owners for everything
* @team-lead @senior-dev
# Frontend ownership
/src/components/ @frontend-team
*.tsx @frontend-team
*.css @frontend-team
# Backend ownership
/src/api/ @backend-team
/src/services/ @backend-team
# Infrastructure
/terraform/ @platform-team
/docker/ @platform-team
*.yml @devops-team
# Security sensitive
/src/auth/ @security-team @team-lead
/src/payments/ @security-team @backend-team
RESULT:
─────────────────────────────────────
├── PR touching /src/auth/ → security-team auto-added
├── Must approve for merge
├── Domain experts involved
├── No changes slip through
└── Automatic assignment
GitScrum Integration
Protection Visibility
GITSCRUM WITH BRANCH PROTECTION
═══════════════════════════════
PR STATUS VISIBILITY:
─────────────────────────────────────
On task:
├── PR status shown
├── Checks passing/failing
├── Review status
├── Merge readiness
└── At-a-glance health
WORKFLOW AWARENESS:
─────────────────────────────────────
├── Task moves "In Review" → PR opened
├── Task sees PR checks status
├── Blocked if checks fail
├── Unblocked when ready to merge
└── Task status reflects reality
Best Practices
For Branch Protection
- Protect main always — Non-negotiable
- Require reviews — Code quality gate
- Require CI — Automated verification
- Use Code Owners — Right experts review
- Plan emergency path — But use rarely
Anti-Patterns
BRANCH PROTECTION MISTAKES:
✗ No protection on main
✗ Admins bypass routinely
✗ Optional CI checks
✗ No required reviews
✗ Too many bypasses
✗ Force push allowed
✗ No CODEOWNERS for critical code
✗ Emergency process undefined