diff --git a/README.md b/README.md index 4919704..c79cd2f 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,9 @@ Add them to the `ci-duty` team (`team-members/ci-duty.csv`). That team: checks, and on `osac` it may also bypass the required reviews (`pull_request_bypassers`). GitHub shows that checkbox only to someone who can bypass every rule on the branch. See `repositories.tf`. +- Has the `ci-maintainer` custom repository role on `osac` and `osac-test-infra`: write, plus + management of the repository's Actions secrets, variables, environments, settings and + runners, and merge queue priority (jump the queue, solo merge). See `organization.tf`. The `managers` team holds the narrower `runner-manager` role, admin on the main repositories, and ruleset bypass on every repository with required status checks. diff --git a/modules/common_repository/variables.tf b/modules/common_repository/variables.tf index 18f50b2..7fd3f63 100644 --- a/modules/common_repository/variables.tf +++ b/modules/common_repository/variables.tf @@ -86,16 +86,16 @@ variable "labels" { } variable "teams" { - description = "Teams with access to this repository" + description = "Teams with access to this repository. permission is pull, push, maintain, triage, admin, or the name of a custom repository role (see organization.tf)." type = list(object({ team_id = string permission = string })) default = [] validation { - error_message = "unknown permission: permission must be one of pull, push, maintain, triage, or admin" + error_message = "unknown permission: permission must be one of pull, push, maintain, triage, admin, or a custom repository role name" condition = alltrue([ - for v in var.teams : contains(["pull", "push", "maintain", "triage", "admin"], v.permission) + for v in var.teams : contains(["pull", "push", "maintain", "triage", "admin"], v.permission) || can(regex("^[a-z][a-z0-9-]*-[a-z0-9-]+$", v.permission)) ]) } } diff --git a/organization.tf b/organization.tf index 77eb314..e33538a 100644 --- a/organization.tf +++ b/organization.tf @@ -53,3 +53,25 @@ resource "github_organization_role_team" "cicd_admin_ci_duty" { role_id = local.cicd_admin_role_id team_slug = github_team.all["ci-duty"].slug } + +# Custom repository role for CI duty on the CI repositories (osac and +# osac-test-infra). The CI/CD admin role above covers only org-level Actions +# settings, so without this, repository secrets and variables (BUF_TOKEN, +# KONFLUX_SA_TOKEN, ...), environments, Actions settings and repository runners +# need repository admin. Permission names come from +# gh api /orgs/osac-project/repository-fine-grained-permissions +resource "github_organization_repository_role" "ci_maintainer" { + name = "ci-maintainer" + description = "Write, plus management of the repository's Actions secrets, variables, environments, settings and runners, and merge queue priority" + base_role = "write" + + permissions = [ + "write_repository_actions_secrets", + "write_repository_actions_variables", + "write_repository_actions_environments", + "write_repository_actions_settings", + "write_repository_actions_runners", + "jump_merge_queue", + "create_solo_merge_queue_entry", + ] +} diff --git a/repositories.tf b/repositories.tf index d9ce052..24744aa 100644 --- a/repositories.tf +++ b/repositories.tf @@ -144,7 +144,7 @@ module "repo_osac" { }, { team_id = github_team.all["ci-duty"].name - permission = "push" + permission = github_organization_repository_role.ci_maintainer.name } ] # Native GitHub review: one approval, dropped when a new commit is pushed. Prow stays only for the Jira reference, the @@ -323,7 +323,7 @@ module "repo_osac_test_infra" { }, { team_id = github_team.all["ci-duty"].name - permission = "push" + permission = github_organization_repository_role.ci_maintainer.name } ] required_approvals = null