diff --git a/.github/rulesets/Optimus-Branch.json b/.github/rulesets/Optimus-Branch.json deleted file mode 100644 index 03ad4882..00000000 --- a/.github/rulesets/Optimus-Branch.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "Optimus-Branch", - "target": "branch", - "enforcement": "active", - "conditions": { - "ref_name": { - "include": ["~DEFAULT_BRANCH"], - "exclude": [] - } - }, - "bypass_actors": [], - "rules": [ - { - "type": "deletion" - }, - { - "type": "non_fast_forward" - }, - { - "type": "required_signatures" - }, - { - "type": "pull_request", - "parameters": { - "required_approving_review_count": 2, - "dismiss_stale_reviews_on_push": true, - "require_code_owner_review": true, - "require_last_push_approval": true, - "required_review_thread_resolution": true, - "require_extra_approval_for_unattributed_changes": true, - "required_reviewers": [], - "allowed_merge_methods": [] - } - }, - { - "type": "required_status_checks", - "parameters": { - "strict_required_status_checks_policy": true, - "do_not_enforce_on_create": false, - "required_status_checks": [] - } - } - ] -} diff --git a/.github/rulesets/README.adoc b/.github/rulesets/README.adoc index 333bf504..1b797261 100644 --- a/.github/rulesets/README.adoc +++ b/.github/rulesets/README.adoc @@ -25,7 +25,7 @@ be described as existing. gh api --method POST \ -H "Accept: application/vnd.github+json" \ "/repos/{owner}/{repo}/rulesets" \ - --input .github/rulesets/tag-protection.json + --input .github/rulesets/base.json # List what is actually in force — the only authoritative answer: gh api "/repos/{owner}/{repo}/rulesets" --jq '.[] | "\(.id)\t\(.name)\t\(.enforcement)"' @@ -33,18 +33,20 @@ gh api "/repos/{owner}/{repo}/rulesets" --jq '.[] | "\(.id)\t\(.name)\t\(.enforc # Update an existing ruleset in place (needs its numeric id from the list above): gh api --method PUT \ "/repos/{owner}/{repo}/rulesets/" \ - --input .github/rulesets/tag-protection.json + --input .github/rulesets/base.json ---- == Files -`tag-protection.json`:: Makes release tags immutable — blocks tag creation, -update and deletion, and requires signed tags. `bypass_actors` grants the -repository *admin* role (`actor_id: 5`) an always-bypass, so a maintainer can -still cut a release. +`base.json`:: Canonical branch protection ruleset for the default branch (`~DEFAULT_BRANCH`). +Enforces required signatures, linear history, squash merge, and deletion/force-push protection +without unsatisfiable coverage or deadlocking approval requirements. + +`Immutable-Tags.json`:: Makes release tags immutable — blocks tag deletion, +non-fast-forward updates, and overwrites, and requires signed tags. == Verifying Do not infer that a ruleset is active because the JSON is present. Check with the `gh api ... /rulesets` list above. A ruleset that exists as a file but was never -POSTed is the tag-protection equivalent of a check that cannot fail. +POSTed is the protection equivalent of a check that cannot fail. diff --git a/.github/rulesets/base.json b/.github/rulesets/base.json new file mode 100644 index 00000000..136c0a0d --- /dev/null +++ b/.github/rulesets/base.json @@ -0,0 +1,102 @@ +{ + "name": "Base", + "target": "branch", + "enforcement": "active", + "conditions": { + "ref_name": { + "include": [ + "~DEFAULT_BRANCH" + ], + "exclude": [] + } + }, + "bypass_actors": [ + { + "actor_id": 5, + "actor_type": "RepositoryRole", + "bypass_mode": "pull_request" + }, + { + "actor_id": 1236702, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 29110, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 15368, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 347564, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 46505, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 1143301, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 1144995, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 12526, + "actor_type": "Integration", + "bypass_mode": "pull_request" + }, + { + "actor_id": 2538504, + "actor_type": "Integration", + "bypass_mode": "pull_request" + } + ], + "rules": [ + { + "type": "deletion" + }, + { + "type": "non_fast_forward" + }, + { + "type": "required_signatures" + }, + { + "type": "required_linear_history" + }, + { + "type": "pull_request", + "parameters": { + "required_approving_review_count": 0, + "dismiss_stale_reviews_on_push": true, + "require_code_owner_review": false, + "require_last_push_approval": false, + "required_review_thread_resolution": true, + "require_extra_approval_for_unattributed_changes": false, + "required_reviewers": [], + "allowed_merge_methods": [ + "squash" + ] + } + }, + { + "type": "required_status_checks", + "parameters": { + "strict_required_status_checks_policy": true, + "do_not_enforce_on_create": false, + "required_status_checks": [] + } + } + ] +}