Skip to content

Branch Protection (Classic)

reconcile:
branch_protection: additive
spec:
branch_protection:
- pattern: main
required_reviews: 1
dismiss_stale_reviews: true
require_code_owner_reviews: false
require_status_checks:
strict: true
contexts:
- "ci / test"
- "ci / lint"
enforce_admins: false
allow_force_pushes: false
allow_deletions: false
- pattern: "release/*"
required_reviews: 2
allow_force_pushes: false

Multiple patterns can be defined. Each entry creates a separate branch protection rule.

Classic branch protection is additive by default. gh-infra creates and updates rules listed in spec.branch_protection, but it does not delete branch protection rules that exist on GitHub and are missing from YAML.

Set reconcile.branch_protection: authoritative to make GitHub branch protection rules match YAML exactly:

reconcile:
branch_protection: authoritative
spec:
branch_protection:
- pattern: main
required_reviews: 1

With authoritative, any classic branch protection rule not declared in spec.branch_protection is planned for deletion. To delete all classic branch protection rules:

reconcile:
branch_protection: authoritative
spec:
branch_protection: []

branch_protection: null and branch_protection: are invalid. Use [] for an explicitly empty managed collection.

FieldTypeDescription
patternstringBranch name or pattern (e.g., main, release/*)
required_reviewsintNumber of required approving reviews
dismiss_stale_reviewsboolDismiss approvals when new commits are pushed
require_code_owner_reviewsboolRequire review from code owners
require_status_checks.strictboolRequire branch to be up to date before merging
require_status_checks.contextslistRequired status check names
enforce_adminsboolApply rules to admins too
allow_force_pushesboolAllow force pushes to matching branches
allow_deletionsboolAllow deleting matching branches

See Rulesets vs Classic Branch Protection for a detailed comparison and migration guidance.