Topic 8.4
Protecting main: Rulesets, CODEOWNERS, Required Checks & Merge Queues
In one line
Collaboration at scale is enforced by the hosting platform: branch protection or rulesets, required reviews from code owners, required status checks, signed commits, linear history, and merge queues that keep main always green.
Think of it like this
A building's main entrance. Staff must badge in (required checks), a department head must sign off on changes to their floor (CODEOWNERS), and visitors queue at reception so the lobby never gets crowded (merge queue).
Key ideas
- 01
BRANCH PROTECTION / RULESETS (GitHub; 'protected branches' on GitLab): block direct pushes and force-pushes to
main, require pull requests with N approvals, dismiss stale approvals when new commits are pushed, require conversation resolution, and require status checks (CI) to pass. Rulesets can target many repos and branches org-wide and apply to admins too. - 02
CODEOWNERS: a file mapping paths to owning teams (
/infra/ @org/platform,*.sql @org/dba). Owners are auto-requested and, with 'require review from code owners', their approval is mandatory for changes to their paths. It's also living documentation of who owns what. - 03
SIGNED COMMITS and TAGS (GPG, SSH, or Sigstore gitsign) prove who made a commit; 'require signed commits' rejects unsigned ones (Phase 3, commit signing). LINEAR HISTORY requires squash or rebase merges, keeping
maineasy to read and bisect. - 04
MERGE QUEUES: when many PRs pass CI individually, merging them together can still break main (their combination was never tested). A merge queue tests each PR on top of the latest main plus the PRs ahead of it, and merges only if that combination passes. Standard at busy repositories (GitHub merge queue, GitLab merge trains, Mergify).
Code & diagrams
# Last matching rule wins
* @shoplite/backend
/infra/ @shoplite/platform
/.github/workflows/ @shoplite/platform @shoplite/security
*.sql @shoplite/dba
/services/payments/ @shoplite/paymentsExplain it without notes
Two PRs both pass CI individually, and main breaks after merging both. How is that possible and what prevents it?
Practice
Design the protection rules for a payments service repo with 30 contributors.
Trade-offs
- ↔
Strict rules protect main but slow teams if CI is slow or reviewers are overloaded; invest in fast pipelines and clear ownership so protection doesn't become friction.
Done when you can
I can configure branch protection/rulesets and CODEOWNERS
I can explain why merge queues exist