diff --git a/repositories.tf b/repositories.tf index f46d493..7b63450 100644 --- a/repositories.tf +++ b/repositories.tf @@ -252,6 +252,176 @@ module "repo_osac" { } } +# Branch protection for any release-X.Y stabilization branch (e.g. +# release-0.4, cut per docs/RELEASING.md in osac-project/osac), mirroring +# repo_osac's own ci-status-checks ruleset above: same three required +# checks, same review requirements (real approving-review-count embedded +# directly in the ruleset's own pull_request rule, not left to classic +# branch protection -- github_branch_protection can't target a branch +# that doesn't exist yet, so there's no equivalent of main's "real review +# enforcement happens at the classic-protection level" split here), same +# bypass actors as repo_osac's own ruleset_bypass_team_ids (managers, +# ci-duty) plus the GitHub Merge Queue app (262318) -- that one specific +# bypass actor matches the module's own dynamic bypass_actors block +# (modules/common_repository/main.tf): it exists so the queue bot can +# push a rebased commit past deletion/non_fast_forward after queue checks +# pass, needed here because non_fast_forward (unlike repo_osac's +# merge_queue-bundled ruleset, which has no such rule to bypass at all) +# is part of this ruleset. Also blocks deletion/force-push, since a +# release branch has none of main's own reasons to allow force-push. +# +# NOT generated by the shared module: release-* is an osac-specific +# pattern, not something every repo this module manages needs, so this +# is a standalone resource rather than a new module variable (unlike +# tag_rulesets above, which genuinely is generic across repos). +# +# Created out-of-band via the GitHub API on 2026-11-04 when release-0.4 +# was actually cut (before this repo's own plan/apply cycle could run); +# codified here afterward so it's reviewable and reproducible like +# everything else in this file, via the `import` block below. +resource "github_repository_ruleset" "release_branch_protection" { + name = "release-branch-protection" + repository = "osac" + target = "branch" + enforcement = "active" + + bypass_actors { + actor_id = 1 + actor_type = "OrganizationAdmin" + bypass_mode = "always" + } + bypass_actors { + actor_id = 262318 + actor_type = "Integration" + bypass_mode = "always" + } + bypass_actors { + actor_id = github_team.all["managers"].id + actor_type = "Team" + bypass_mode = "always" + } + bypass_actors { + actor_id = github_team.all["ci-duty"].id + actor_type = "Team" + bypass_mode = "always" + } + + conditions { + ref_name { + include = ["refs/heads/release-*"] + exclude = [] + } + } + + rules { + required_status_checks { + # Matches repo_osac's own merge_queue-enabled branches: the queue + # already re-tests against latest before merging, so requiring + # checks to be re-run up to date here would be redundant. + strict_required_status_checks_policy = false + + required_check { + context = "CI" + integration_id = 15368 + } + required_check { + context = "jira-reference" + integration_id = 15368 + } + required_check { + context = "E2E" + integration_id = 4966101 + } + } + + pull_request { + required_approving_review_count = 1 + dismiss_stale_reviews_on_push = true + require_code_owner_review = true + require_last_push_approval = false + required_review_thread_resolution = false + allowed_merge_methods = ["merge", "squash", "rebase"] + } + + deletion = true + non_fast_forward = true + } + + depends_on = [module.repo_osac] +} + +import { + to = github_repository_ruleset.release_branch_protection + id = "osac:26559405" +} + +# Merge queue for release-0.4 specifically. GitHub rejects a wildcard +# ref_name pattern when a merge_queue rule is present ("Wildcard ref +# names are not supported when merge queue is enabled" -- confirmed +# live), so this can't be folded into release_branch_protection above. +# A sibling resource like this one is needed per release branch going +# forward (0.5, 0.6, ...), unlike that wildcard ruleset which only had +# to be created once. +# +# Matches the live ruleset's actual bypass_actors exactly (it has no +# restrictive rule for them to bypass -- merge_queue alone doesn't +# restrict direct pushes, that's release_branch_protection's job -- but +# they were set on creation and this codifies what's live rather than +# narrowing it as a drive-by cleanup under this change's scope). +resource "github_repository_ruleset" "release_0_4_merge_queue" { + name = "release-0.4-merge-queue" + repository = "osac" + target = "branch" + enforcement = "active" + + bypass_actors { + actor_id = 1 + actor_type = "OrganizationAdmin" + bypass_mode = "always" + } + bypass_actors { + actor_id = 262318 + actor_type = "Integration" + bypass_mode = "always" + } + bypass_actors { + actor_id = github_team.all["managers"].id + actor_type = "Team" + bypass_mode = "always" + } + bypass_actors { + actor_id = github_team.all["ci-duty"].id + actor_type = "Team" + bypass_mode = "always" + } + + conditions { + ref_name { + include = ["refs/heads/release-0.4"] + exclude = [] + } + } + + rules { + merge_queue { + merge_method = "SQUASH" + max_entries_to_build = 4 + max_entries_to_merge = 5 + min_entries_to_merge = 1 + min_entries_to_merge_wait_minutes = 5 + check_response_timeout_minutes = 180 + grouping_strategy = "ALLGREEN" + } + } + + depends_on = [module.repo_osac] +} + +import { + to = github_repository_ruleset.release_0_4_merge_queue + id = "osac:26569686" +} + module "repo_cloudkit_operator" { source = "./modules/common_repository" visibility = "public"