Skip to content

Rulesets

Configure GitHub repository rulesets — the modern replacement for classic branch protection rules, with richer controls and enforcement modes.

reconcile:
rulesets: additive
spec:
rulesets:
- name: protect-main
target: branch
enforcement: active
bypass_actors:
- role: admin
bypass_mode: always
conditions:
ref_name:
include:
- "refs/heads/main"
- "refs/heads/release/*"
exclude:
- "refs/heads/sandbox/*"
rules:
pull_request:
required_approving_review_count: 1
dismiss_stale_reviews_on_push: true
require_code_owner_review: false
require_last_push_approval: false
required_review_thread_resolution: false
required_status_checks:
strict_required_status_checks_policy: true
contexts:
- context: "ci/test"
app: github-actions
non_fast_forward: true
deletion: true
creation: false
required_linear_history: false
required_signatures: false
- name: protect-tags
target: tag
enforcement: evaluate
conditions:
ref_name:
include: ["refs/tags/v*"]
rules:
deletion: true
non_fast_forward: true

Rulesets are additive by default. gh-infra creates and updates rulesets listed in spec.rulesets, but it does not delete rulesets that exist on GitHub and are missing from YAML.

Set reconcile.rulesets: authoritative to make GitHub rulesets match YAML exactly:

reconcile:
rulesets: authoritative
spec:
rulesets:
- name: protect-main
target: branch
rules:
non_fast_forward: true

With authoritative, any repository ruleset not declared in spec.rulesets is planned for deletion. To delete all repository rulesets:

reconcile:
rulesets: authoritative
spec:
rulesets: []

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

FieldTypeDefaultDescription
namestringrequiredRuleset name (must be unique within the repository)
targetstringbranchWhat the ruleset applies to: branch or tag
enforcementstringactiveactive (enforced), evaluate (dry-run, logged but not enforced), or disabled
bypass_actorslist[]Actors who can bypass this ruleset
conditionsobjectWhich branches or tags the ruleset applies to
rulesobjectrequiredThe rules to enforce

Each entry allows a specific actor to bypass the ruleset. Specify the actor type by field name:

bypass_actors:
- role: admin # Built-in role: admin, write, or maintain
bypass_mode: always
- team: maintainers # Organization team by slug
bypass_mode: pull_request
- app: github-actions # GitHub App by slug
bypass_mode: always
- org-admin: true # Organization administrators
- custom-role: reviewer # Enterprise Cloud custom role by name
bypass_mode: pull_request
FieldDescription
roleBuilt-in repository role: admin, write, or maintain
teamOrganization team slug (resolved via API)
appGitHub App slug (resolved via API). Private apps that cannot be resolved are exported as id:N by import, which is accepted as-is by plan and apply
org-adminSet to true for organization administrators
custom-roleEnterprise Cloud custom role name (resolved via API)
bypass_modealways (pushes and PRs) or pull_request (PRs only)

Exactly one actor type field must be specified per entry. Names are automatically resolved to numeric IDs — see Ruleset Identity Resolution for details.

Specify which branches or tags the ruleset targets using fnmatch-style patterns:

conditions:
ref_name:
include:
- "refs/heads/main"
- "refs/heads/release/*"
exclude:
- "refs/heads/sandbox/*"

Special values: ~DEFAULT_BRANCH matches the repository’s default branch, ~ALL matches all branches/tags.

Require pull request reviews before merging:

FieldTypeDefaultDescription
required_approving_review_countint0Number of required approving reviews (0–10)
dismiss_stale_reviews_on_pushboolfalseDismiss approvals when new commits are pushed
require_code_owner_reviewboolfalseRequire review from code owners
require_last_push_approvalboolfalseLast pusher cannot self-approve
required_review_thread_resolutionboolfalseAll review threads must be resolved

Require specific CI checks to pass:

rules:
required_status_checks:
strict_required_status_checks_policy: true
contexts:
- context: "ci/test"
app: github-actions
- context: "ci/lint"
FieldTypeDescription
strict_required_status_checks_policyboolRequire branch to be up to date before merging
contexts[].contextstringName of the required status check
contexts[].appstring(optional) GitHub App slug that must provide this check. Omit to accept any provider

Simple on/off rules — set to true to enable:

FieldDescription
non_fast_forwardBlock force pushes to matching refs
deletionBlock deletion of matching refs
creationBlock creation of matching refs
required_linear_historyRequire linear commit history (no merge commits)
required_signaturesRequire signed commits
FeatureClassic branch_protectionrulesets
Multiple rules per branchNo (one rule per pattern)Yes (rules stack)
Enforcement modesOn/off onlyActive, evaluate (dry-run), disabled
Bypass controlAdmin override onlyGranular per role/team/app
Tag protectionNoYes (target: tag)
Audit trailNoBuilt-in version history
Merge queueSeparate configIntegrated as a rule type (Phase 2)
Metadata rulesNoCommit message patterns, etc. (Phase 2)