Skip to content

Branch Protection Setup

This guide explains how to configure branch protection rules to enforce CI/CD checks and prevent direct commits to protected branches.

Overview

Branch protection ensures that:

  • All code changes go through pull requests
  • CI checks pass before merging
  • Code reviews are required
  • Direct commits to main/dev are blocked

Setting Up Branch Protection

For main Branch

  1. Go to Settings → Branches in GitHub repository
  2. Click Add branch protection rule
  3. Configure the following:

Branch name pattern

main

Protect matching branches

✅ Require a pull request before merging

  • Require approvals: 1
  • ✅ Dismiss stale pull request approvals when new commits are pushed
  • ✅ Require review from Code Owners (optional, if CODEOWNERS file exists)

✅ Require status checks to pass before merging

  • ✅ Require branches to be up to date before merging
  • Required status checks:
    • lint (from CI workflow)
    • build (from CI workflow)
    • test (from CI workflow)
    • validate-firestore-indexes (from CI workflow)
    • all-checks-complete (from CI workflow)

✅ Require conversation resolution before merging

✅ Require signed commits (optional, recommended for production)

✅ Require linear history (optional, prevents merge commits)

✅ Do not allow bypassing the above settings

  • Even admins must follow the rules

Rules applied to administrators

  • ✅ Include administrators (recommended to prevent accidents)
  1. Click Create

For dev Branch

Repeat the same steps as above, but with dev as the branch name pattern.

Difference from main:

  • May allow more relaxed approval requirements (0-1 reviewers)
  • Same CI checks required
  • Allows faster iteration while maintaining quality

GitHub Actions Required Secrets

Before branch protection will work with CI/CD, ensure these secrets are set:

Go to Settings → Secrets and variables → Actions

Firebase (Development)

VITE_FIREBASE_API_KEY_DEV
VITE_FIREBASE_AUTH_DOMAIN_DEV
VITE_FIREBASE_PROJECT_ID_DEV
VITE_FIREBASE_STORAGE_BUCKET_DEV
VITE_FIREBASE_MESSAGING_SENDER_ID_DEV
VITE_FIREBASE_APP_ID_DEV

Firebase (Production)

VITE_FIREBASE_API_KEY_PROD
VITE_FIREBASE_AUTH_DOMAIN_PROD
VITE_FIREBASE_PROJECT_ID_PROD
VITE_FIREBASE_STORAGE_BUCKET_PROD
VITE_FIREBASE_MESSAGING_SENDER_ID_PROD
VITE_FIREBASE_APP_ID_PROD

Cloudflare

CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID

Firebase CLI

FIREBASE_TOKEN

Get Firebase token by running:

bash
firebase login:ci

Discord

DISCORD_WEBHOOK_COMMITS
DISCORD_WEBHOOK_DEV_DEPLOY
DISCORD_WEBHOOK_PROD_DEPLOY

See DISCORD_WEBHOOK_SETUP.md for detailed setup instructions.

Optional

CODECOV_TOKEN

Get from codecov.io after linking repository.


Testing Branch Protection

Test Required Status Checks

  1. Create a feature branch:

    bash
    git checkout -b test/branch-protection
  2. Make a small change (e.g., add a comment to a file)

  3. Commit and push:

    bash
    git add .
    git commit -m "test: verify branch protection"
    git push origin test/branch-protection
  4. Open a pull request to main or dev

  5. Verify:

    • ✅ CI workflow runs automatically
    • ✅ All checks must pass before "Merge" button is enabled
    • ✅ If any check fails, merge is blocked

Test Direct Commit Block

  1. Try to push directly to main:

    bash
    git checkout main
    git commit --allow-empty -m "test: direct commit"
    git push origin main
  2. Expected result:

    remote: error: GH006: Protected branch update failed
    remote: error: Required status checks are not passing
  3. If push succeeds, branch protection is not configured correctly!


Troubleshooting

Merge button is disabled but all checks passed

Issue: Required status checks are not configured correctly

Fix:

  1. Go to Settings → Branches → Edit protection rule
  2. Scroll to "Require status checks to pass before merging"
  3. Search for and add each required check:
    • Type lint and select it
    • Type build and select it
    • Type test and select it
    • Type validate-firestore-indexes and select it
    • Type all-checks-complete and select it
  4. Save changes

Note: Status checks only appear in the list AFTER they've run at least once on a PR!

Status checks never run

Issue: GitHub Actions not triggering

Fix:

  1. Verify .github/workflows/ci.yml exists in the repository
  2. Check workflow file syntax (no YAML errors)
  3. Ensure GitHub Actions are enabled: Settings → Actions → General → Allow all actions
  4. Push a new commit to trigger workflows

Can still push directly to main

Issue: Branch protection not enabled or admin bypass allowed

Fix:

  1. Verify protection rule exists for main branch
  2. Check "Include administrators" is enabled
  3. Check "Do not allow bypassing" is enabled

Codecov check failing

Issue: Missing CODECOV_TOKEN secret

Fix:

  • Set continue-on-error: true for codecov step in CI workflow (already configured)
  • Or, add CODECOV_TOKEN secret to repository

Environment Protection (Production)

For additional safety on production deployments, enable environment protection:

  1. Go to Settings → Environments
  2. Click New environment
  3. Name: production
  4. Configure protection rules:
    • ✅ Required reviewers: Add team members who can approve production deploys
    • ✅ Wait timer: 5 minutes (optional, gives time to cancel)
    • Environment secrets: Add production-specific secrets here (optional)
  5. Save

Now production deployments will:

  • Require manual approval from designated reviewers
  • Wait 5 minutes before deploying (if configured)
  • Only deploy to production environment after approval

Best Practices

Required Reviewers

  • Main branch: Require at least 1 approval
  • Dev branch: 0-1 approvals (team preference)
  • Production environment: Require senior engineer approval

Status Checks

  • Always require lint, build, test to pass
  • Include validate-firestore-indexes to catch index issues early
  • Use all-checks-complete as final gate

Bypass Settings

  • Never allow bypassing for main branch
  • Include administrators in rules to prevent accidents
  • Document any exceptions in team wiki

Monitoring

  • Review failed CI checks in GitHub Actions tab
  • Set up Slack/Discord notifications for failed merges
  • Regularly audit branch protection rules

Updating Branch Protection

To modify rules:

  1. Go to Settings → Branches
  2. Find the rule you want to edit
  3. Click Edit
  4. Make changes
  5. Click Save changes

⚠️ Changes take effect immediately


Rollback Procedure

If you need to bypass branch protection in an emergency:

  1. Go to Settings → Branches
  2. Find the protection rule
  3. Click Edit
  4. Temporarily disable "Do not allow bypassing"
  5. Make emergency commit
  6. IMMEDIATELY re-enable protection

⚠️ Document all bypasses in team log


See Also

Built with VitePress