From bef192e638b1b87de6636976dd81bb948566fb37 Mon Sep 17 00:00:00 2001 From: Elior Erez Date: Tue, 3 Nov 2026 11:18:24 -0500 Subject: [PATCH 1/5] NO-ISSUE: Add ownership to github-config: team files and the owner A change to team-members/.csv needs an approval from that team (CODEOWNERS, with code owner reviews turned on), and every pull request needs an approval from github-config-owners, a team of one person, through a ruleset with required reviewers: CODEOWNERS cannot ask for two different owners of one path. Signed-off-by: Elior Erez --- CODEOWNERS | 29 ++++++++++++++++ README.md | 6 ++++ repositories.tf | 50 +++++++++++++++++++++++++++ team-members/github-config-owners.csv | 2 ++ teams.csv | 1 + 5 files changed, 88 insertions(+) create mode 100644 CODEOWNERS create mode 100644 team-members/github-config-owners.csv diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..318b560 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,29 @@ +# CODEOWNERS of github-config. +# +# A change to the member file of a team needs an approval from that team (any member except the author), so a team decides +# who joins it. The team must be visible (closed) and have write access to this repository, which the teams below have +# (the contributor teams of teams.csv). A team that cannot be an owner (secret, or without access) has no rule here, and its +# file needs only the owners' approval: ci-duty, documentation-wg, fulfillment-wg, observability-wg, org-admins, personas-wg. +# +# Every pull request also needs an approval of github-config-owners (the ruleset "owner-review" in repositories.tf), which +# CODEOWNERS cannot say: it takes one owner per path, not two. + +/team-members/architects.csv @osac-project/architects +/team-members/contributors.csv @osac-project/contributors +/team-members/managers.csv @osac-project/managers +/team-members/wg-architecture.csv @osac-project/wg-architecture +/team-members/wg-bmaas.csv @osac-project/wg-bmaas +/team-members/wg-caas.csv @osac-project/wg-caas +/team-members/wg-connectivity.csv @osac-project/wg-connectivity +/team-members/wg-core.csv @osac-project/wg-core +/team-members/wg-e2e.csv @osac-project/wg-e2e +/team-members/wg-enclave.csv @osac-project/wg-enclave +/team-members/wg-infra.csv @osac-project/wg-infra +/team-members/wg-leads.csv @osac-project/wg-leads +/team-members/wg-maas.csv @osac-project/wg-maas +/team-members/wg-metering.csv @osac-project/wg-metering +/team-members/wg-qe.csv @osac-project/wg-qe +/team-members/wg-soln-eng.csv @osac-project/wg-soln-eng +/team-members/wg-storage.csv @osac-project/wg-storage +/team-members/wg-ui.csv @osac-project/wg-ui +/team-members/wg-vmaas.csv @osac-project/wg-vmaas diff --git a/README.md b/README.md index 8bc0d76..52734bc 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,12 @@ When a commit is pushed to the `main` branch (e.g., when a pull request merges), Set `` to `true` to give the team push access on every repository that uses `local.contributor_teams` in `repositories.tf` (the working group teams), or `false` otherwise. Set `` to `true` or `false` (see the next section); a team that is not explicitly authorized to approve changes is `false`. +### Who approves a change to this repository? + +- Every pull request needs an approval of `github-config-owners` (a team of one person, `team-members/github-config-owners.csv`): the ruleset `owner-review` in `repositories.tf`. The author of a pull request cannot approve it, so a pull request of an owner is approved by someone else, or merged by an organization admin who bypasses the ruleset. +- A change to `team-members/.csv` also needs an approval from that team (`CODEOWNERS`), so that a team decides who joins it. A team that is secret or has no access to this repository cannot be a code owner (`fulfillment-wg`, `observability-wg`, `personas-wg`, `documentation-wg`, `org-admins`, `ci-duty`): its file has no rule and needs only the owners' approval. +- When you add a team to `teams.csv` with `contributor` set to `true` and a `closed` privacy, add a line for its file to `CODEOWNERS` (`/team-members/.csv @osac-project/`). + ### Let a team approve changes (be a maintainer)? 1. Open `teams.csv` diff --git a/repositories.tf b/repositories.tf index b65c591..4ee0936 100644 --- a/repositories.tf +++ b/repositories.tf @@ -55,15 +55,65 @@ module "repo_github_config" { ] ruleset_bypass_team_ids = [github_team.all["managers"].id] + # An approval of a code owner is needed where CODEOWNERS names one (a team file needs its team, see CODEOWNERS). + require_code_owner_reviews = true + contributor_teams = local.contributor_teams teams = [ { team_id = github_team.all["managers"].name permission = "admin" + }, + { + team_id = github_team.all["github-config-owners"].name + permission = "push" } ] } +# Every pull request to github-config needs an approval of github-config-owners, whatever files it changes. CODEOWNERS cannot +# say "this team AND that team" (one owner per path is enough), so the team files get their own team from CODEOWNERS and this +# ruleset adds the owners on top. The author of a pull request cannot approve it, so a pull request of an owner is approved by +# someone else, or merged by an organization admin, who may bypass the ruleset like the status checks one. Required +# reviewers is a beta feature of GitHub rulesets. +resource "github_repository_ruleset" "github_config_owner_review" { + name = "owner-review" + repository = "github-config" + target = "branch" + enforcement = "active" + + bypass_actors { + actor_id = 1 + actor_type = "OrganizationAdmin" + bypass_mode = "always" + } + + conditions { + ref_name { + include = ["~DEFAULT_BRANCH"] + exclude = [] + } + } + + rules { + pull_request { + required_approving_review_count = 0 + + required_reviewers { + minimum_approvals = 1 + file_patterns = ["**"] + + reviewer { + id = tonumber(github_team.all["github-config-owners"].id) + type = "Team" + } + } + } + } + + depends_on = [module.repo_github_config] +} + module "repo_dotgithub_private" { source = "./modules/common_repository" visibility = "private" diff --git a/team-members/github-config-owners.csv b/team-members/github-config-owners.csv new file mode 100644 index 0000000..84dfee9 --- /dev/null +++ b/team-members/github-config-owners.csv @@ -0,0 +1,2 @@ +username,role +eliorerz,maintainer diff --git a/teams.csv b/teams.csv index 3311142..bdc78f8 100644 --- a/teams.csv +++ b/teams.csv @@ -24,3 +24,4 @@ wg-ui,OSAC UI working group,closed,true,true wg-e2e,OSAC E2E working group,closed,true,true wg-soln-eng,OSAC Solution Engineering working group,closed,true,true wg-qe,OSAC QE working group,closed,true,true +github-config-owners,Approves every pull request to github-config,closed,false,false From 36b0c11c87da6119a417541dc762117a7f3ba584 Mon Sep 17 00:00:00 2001 From: Elior Erez Date: Tue, 3 Nov 2026 12:01:57 -0500 Subject: [PATCH 2/5] NO-ISSUE: Say the owner approval is for the default branch The owner-review ruleset covers the default branch only, so the CODEOWNERS comment and the README say so. Required reviewers came in provider 6.11, so the constraint is ~> 6.11 (the lock stays on 6.12.1). Signed-off-by: Elior Erez --- .terraform.lock.hcl | 2 +- CODEOWNERS | 4 ++-- README.md | 2 +- versions.tf | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index f31c90b..c451787 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -3,7 +3,7 @@ provider "registry.opentofu.org/integrations/github" { version = "6.12.1" - constraints = "~> 6.0" + constraints = "~> 6.11" hashes = [ "h1:bGz4LIep/7PVrqy6P8cTYbAJpdxXGrupUJjkCczlzIs=", "zh:3e1a4081ecb9518fdf0074db83c16ad00dc81ffe8249a6e3cf1894e947e28df6", diff --git a/CODEOWNERS b/CODEOWNERS index 318b560..0b7a1f5 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -5,8 +5,8 @@ # (the contributor teams of teams.csv). A team that cannot be an owner (secret, or without access) has no rule here, and its # file needs only the owners' approval: ci-duty, documentation-wg, fulfillment-wg, observability-wg, org-admins, personas-wg. # -# Every pull request also needs an approval of github-config-owners (the ruleset "owner-review" in repositories.tf), which -# CODEOWNERS cannot say: it takes one owner per path, not two. +# Every pull request to the default branch also needs an approval of github-config-owners (the ruleset "owner-review" in +# repositories.tf), which CODEOWNERS cannot say: it takes one owner per path, not two. /team-members/architects.csv @osac-project/architects /team-members/contributors.csv @osac-project/contributors diff --git a/README.md b/README.md index 52734bc..1cc40bc 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ When a commit is pushed to the `main` branch (e.g., when a pull request merges), ### Who approves a change to this repository? -- Every pull request needs an approval of `github-config-owners` (a team of one person, `team-members/github-config-owners.csv`): the ruleset `owner-review` in `repositories.tf`. The author of a pull request cannot approve it, so a pull request of an owner is approved by someone else, or merged by an organization admin who bypasses the ruleset. +- Every pull request to the default branch needs an approval of `github-config-owners` (a team of one person, `team-members/github-config-owners.csv`): the ruleset `owner-review` in `repositories.tf`. The author of a pull request cannot approve it, so a pull request of an owner is approved by someone else, or merged by an organization admin who bypasses the ruleset. - A change to `team-members/.csv` also needs an approval from that team (`CODEOWNERS`), so that a team decides who joins it. A team that is secret or has no access to this repository cannot be a code owner (`fulfillment-wg`, `observability-wg`, `personas-wg`, `documentation-wg`, `org-admins`, `ci-duty`): its file has no rule and needs only the owners' approval. - When you add a team to `teams.csv` with `contributor` set to `true` and a `closed` privacy, add a line for its file to `CODEOWNERS` (`/team-members/.csv @osac-project/`). diff --git a/versions.tf b/versions.tf index b818412..5cccad3 100644 --- a/versions.tf +++ b/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { github = { source = "integrations/github" - version = "~> 6.0" + version = "~> 6.11" # 6.11 added required reviewers to rulesets (repositories.tf: owner-review) } } } From b78dc57a2f4b6377b88d10febcc587caeee650b3 Mon Sep 17 00:00:00 2001 From: Elior Erez Date: Tue, 3 Nov 2026 12:15:20 -0500 Subject: [PATCH 3/5] NO-ISSUE: Merge an approved github-config pull request by itself A workflow turns on GitHub's auto-merge for every pull request that is not a draft, so it merges the moment the owner, the team of a team file, the other approvals and pre-commit are there. Because nothing waits for a person any more, a new commit must drop the approvals (dismiss_stale_reviews, and on push for the owner ruleset), and one approval besides the owner's is no longer needed. Signed-off-by: Elior Erez --- .github/workflows/auto-merge.yaml | 38 +++++++++++++++++++++++++++++++ README.md | 1 + repositories.tf | 8 +++++-- 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/auto-merge.yaml diff --git a/.github/workflows/auto-merge.yaml b/.github/workflows/auto-merge.yaml new file mode 100644 index 0000000..95cd7e7 --- /dev/null +++ b/.github/workflows/auto-merge.yaml @@ -0,0 +1,38 @@ +name: Auto-merge + +# A pull request merges by itself once everything it needs is there: the approval of the owner (github-config-owners), of the +# team whose member file it changes (CODEOWNERS), the other approvals and the checks. This turns on GitHub's auto-merge for +# every pull request that is not a draft; GitHub then merges it the moment the rules are met, and not before. The rules are +# the branch protection and the rulesets (repositories.tf), which a new commit resets (stale approvals are dismissed). +# +# It runs from the default branch (pull_request_target) and checks out nothing of the pull request. The merge is made with +# the token of this workflow, which starts no other workflow (apply.yaml runs on its schedule, every 4 hours, or by hand). +on: # zizmor: ignore[dangerous-triggers] -- nothing of the pull request is checked out or run + pull_request_target: + types: [opened, reopened, synchronize, ready_for_review] + +permissions: {} + +jobs: + auto-merge: + name: Enable auto-merge + if: ${{ !github.event.pull_request.draft }} + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: write + pull-requests: write + steps: + - name: Turn on auto-merge + env: + GH_TOKEN: ${{ github.token }} + NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + run: | + set -euo pipefail + [[ "${NUMBER}" =~ ^[0-9]+$ ]] || { echo "::error::The pull request number must be digits only." >&2; exit 1; } + if [[ "$(gh pr view "${NUMBER}" --repo "${REPO}" --json autoMergeRequest --jq '.autoMergeRequest != null')" == "true" ]]; then + echo "Auto-merge is already on for #${NUMBER}" + exit 0 + fi + gh pr merge "${NUMBER}" --repo "${REPO}" --auto --squash diff --git a/README.md b/README.md index 1cc40bc..2332bf1 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ When a commit is pushed to the `main` branch (e.g., when a pull request merges), ### Who approves a change to this repository? - Every pull request to the default branch needs an approval of `github-config-owners` (a team of one person, `team-members/github-config-owners.csv`): the ruleset `owner-review` in `repositories.tf`. The author of a pull request cannot approve it, so a pull request of an owner is approved by someone else, or merged by an organization admin who bypasses the ruleset. +- A pull request **merges by itself** once it has what it needs: the owner's approval, the team's approval for a team file, the other approvals and a green `pre-commit`. `.github/workflows/auto-merge.yaml` turns on GitHub's auto-merge for every pull request that is not a draft; GitHub merges it the moment the rules are met. A new commit drops the approvals (`dismiss_stale_reviews`), so nothing changes after it was reviewed. To keep a pull request from merging, make it a draft or request changes. The merge is made with the workflow's token, which starts no workflow, so `apply.yaml` follows on its schedule (every 4 hours) or by hand. - A change to `team-members/.csv` also needs an approval from that team (`CODEOWNERS`), so that a team decides who joins it. A team that is secret or has no access to this repository cannot be a code owner (`fulfillment-wg`, `observability-wg`, `personas-wg`, `documentation-wg`, `org-admins`, `ci-duty`): its file has no rule and needs only the owners' approval. - When you add a team to `teams.csv` with `contributor` set to `true` and a `closed` privacy, add a line for its file to `CODEOWNERS` (`/team-members/.csv @osac-project/`). diff --git a/repositories.tf b/repositories.tf index 4ee0936..f46d493 100644 --- a/repositories.tf +++ b/repositories.tf @@ -49,14 +49,17 @@ module "repo_github_config" { name = "github-config" description = "Repository for managing osac-project github organization" use_public_template = false - required_approvals = 2 + required_approvals = 1 required_status_checks = [ { context = "pre-commit", integration_id = 15368 }, ] ruleset_bypass_team_ids = [github_team.all["managers"].id] - # An approval of a code owner is needed where CODEOWNERS names one (a team file needs its team, see CODEOWNERS). + # An approval of a code owner is needed where CODEOWNERS names one (a team file needs its team, see CODEOWNERS), and every + # pull request needs the owner (the ruleset below). Pull requests merge by themselves once approved (see + # .github/workflows/auto-merge.yaml), so a new commit must drop the approvals: nothing reviewed may change afterwards. require_code_owner_reviews = true + dismiss_stale_reviews = true contributor_teams = local.contributor_teams teams = [ @@ -98,6 +101,7 @@ resource "github_repository_ruleset" "github_config_owner_review" { rules { pull_request { required_approving_review_count = 0 + dismiss_stale_reviews_on_push = true required_reviewers { minimum_approvals = 1 From b729caa047dcc2ee03571f59176aa135e19d30aa Mon Sep 17 00:00:00 2001 From: Elior Erez Date: Tue, 3 Nov 2026 12:45:50 -0500 Subject: [PATCH 4/5] NO-ISSUE: Fix the provider floor, the auto-merge trigger and the README Provider 6.12.1 cannot read the team reviewer id of a ruleset (fixed in go-github 86, so in provider 6.13), and the apply would fail after GitHub created the ruleset: require ~> 6.13 and lock 6.13.0 (zh hashes of its release; tofu init adds the local one). pull_request_target is blocked by default in public repositories from 2 December, so auto-merge runs when pre-commit ends instead, for pull requests to the default branch only, and adds no row to a pull request. The README says that a pull request written by the only owner can be merged only by an organization admin. Signed-off-by: Elior Erez --- .github/workflows/auto-merge.yaml | 42 ++++++++++++++++++++----------- .terraform.lock.hcl | 32 +++++++++++------------ README.md | 4 +-- versions.tf | 2 +- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/.github/workflows/auto-merge.yaml b/.github/workflows/auto-merge.yaml index 95cd7e7..96f4302 100644 --- a/.github/workflows/auto-merge.yaml +++ b/.github/workflows/auto-merge.yaml @@ -2,37 +2,49 @@ name: Auto-merge # A pull request merges by itself once everything it needs is there: the approval of the owner (github-config-owners), of the # team whose member file it changes (CODEOWNERS), the other approvals and the checks. This turns on GitHub's auto-merge for -# every pull request that is not a draft; GitHub then merges it the moment the rules are met, and not before. The rules are -# the branch protection and the rulesets (repositories.tf), which a new commit resets (stale approvals are dismissed). +# every pull request to the default branch that is not a draft, each time pre-commit has run for it; GitHub then merges it +# the moment the rules are met, and not before. The rules are the branch protection and the rulesets (repositories.tf), which +# a new commit resets (stale approvals are dismissed). # -# It runs from the default branch (pull_request_target) and checks out nothing of the pull request. The merge is made with -# the token of this workflow, which starts no other workflow (apply.yaml runs on its schedule, every 4 hours, or by hand). +# It runs when pre-commit ends, from the default branch, and runs nothing of the pull request (pull_request_target, which +# GitHub blocks by default in public repositories from 2 December 2026, is not used). It is a run of the default branch, so +# it adds no row to a pull request. The merge is made with the token of this workflow, which starts no other workflow +# (apply.yaml runs on its schedule, every 4 hours, or by hand). on: # zizmor: ignore[dangerous-triggers] -- nothing of the pull request is checked out or run - pull_request_target: - types: [opened, reopened, synchronize, ready_for_review] + workflow_run: + workflows: [pre-commit] + types: [completed] permissions: {} jobs: auto-merge: name: Enable auto-merge - if: ${{ !github.event.pull_request.draft }} + if: ${{ github.event.workflow_run.event == 'pull_request' }} runs-on: ubuntu-latest timeout-minutes: 5 permissions: contents: write pull-requests: write steps: - - name: Turn on auto-merge + - name: Turn on auto-merge for the pull request of this commit env: GH_TOKEN: ${{ github.token }} - NUMBER: ${{ github.event.pull_request.number }} REPO: ${{ github.repository }} + SHA: ${{ github.event.workflow_run.head_sha }} + BASE: ${{ github.event.repository.default_branch }} run: | set -euo pipefail - [[ "${NUMBER}" =~ ^[0-9]+$ ]] || { echo "::error::The pull request number must be digits only." >&2; exit 1; } - if [[ "$(gh pr view "${NUMBER}" --repo "${REPO}" --json autoMergeRequest --jq '.autoMergeRequest != null')" == "true" ]]; then - echo "Auto-merge is already on for #${NUMBER}" - exit 0 - fi - gh pr merge "${NUMBER}" --repo "${REPO}" --auto --squash + [[ "${SHA}" =~ ^[0-9a-f]{40}$ ]] || { echo "::error::The commit must be 40 lower-case hexadecimal digits." >&2; exit 1; } + # The open pull requests to the default branch whose head is this commit (found by the commit: the run itself does not list a fork pull request). + numbers=$(gh api "repos/${REPO}/commits/${SHA}/pulls" \ + | jq -r --arg base "${BASE}" '.[] | select(.state == "open" and .base.ref == $base) | .number') + for number in ${numbers}; do + [[ "${number}" =~ ^[0-9]+$ ]] || continue + view=$(gh pr view "${number}" --repo "${REPO}" --json isDraft,autoMergeRequest,headRefOid) + if jq -e --arg sha "${SHA}" '.isDraft or (.autoMergeRequest != null) or (.headRefOid != $sha)' <<<"${view}" >/dev/null; then + echo "#${number}: a draft, or auto-merge is already on, or it moved on to another commit" + continue + fi + gh pr merge "${number}" --repo "${REPO}" --auto --squash + done diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index c451787..40d8808 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,23 +2,21 @@ # Manual edits may be lost in future updates. provider "registry.opentofu.org/integrations/github" { - version = "6.12.1" - constraints = "~> 6.11" + version = "6.13.0" + constraints = "~> 6.13" hashes = [ - "h1:bGz4LIep/7PVrqy6P8cTYbAJpdxXGrupUJjkCczlzIs=", - "zh:3e1a4081ecb9518fdf0074db83c16ad00dc81ffe8249a6e3cf1894e947e28df6", - "zh:4cb8224b7f530795b674ac044675f6b22a7c9154f55eb9f76c5af6c7534056a4", - "zh:560bc08637926191f6871a89e986022ca67c70afda5bebca34b5216e6fac69c9", - "zh:5a70b5d2ac650c5c9819a1875411ebda229d0fcc6c9f57f9d751852ca3cd77ac", - "zh:8668d93bd4dc2ffa2545e1473af600a925d479b16033a71a4498a16f3b683c0c", - "zh:86eacc6059fd057948e178b665ba5cce74bd5488a9e1035734e60ff5ef1b6f8f", - "zh:a329fac98881d8dfc211a9bdc0ec6f2948f0b0c2704d1b6cbe5307403c7ad1b2", - "zh:dadd44abab3c52b9d572955afaef1658790e17ea355ee22b58996d81d28e02d8", - "zh:de9f455ef342cc38fb76bce844bfcd376fb81a4b9f9bc2fae023ff99efdf1338", - "zh:f8c6d2e8351b334491790358574e0a30a7c6d7f5b80f7daf32a7c0f3e9b1ab19", - "zh:fab41971a3edee04ab6eceaeab4eeb9a2b2f38a2af3b06eda93e2117b64994be", - "zh:fb1279b566dd9c8c117b2e4e0cc8344413b8fc8f2a3e24be22a9b2610551777b", - "zh:fbd1fee2c9df3aa19cf8851ce134dea6e45ea01cb85695c1726670c285797e25", - "zh:fe79d2a861fb9af420fa5bd7f02c031b2a0a3edf5dbc46022c8ecc7a33cf2b6d", + "zh:0ab29fc21699f34345cf0bbbe44745fd1b143b7c73b410c1dc4abe05ffad0a84", + "zh:1aed10d06755d420bb3a893bf548ab2932297a9d094c04c5a8501e949ca186ed", + "zh:2a6a11c21eae408055f45b9533c07afd2e845f6d496fd1b645aec2e873012103", + "zh:5dd05dee677f6ebdbed00cbb1b9be444ab2d1062d345cbc9ec50a47cb41b8622", + "zh:6b757d034831243d67ddda869eac4368cef539848bd97511f4d68f1aa38a9c88", + "zh:947c9b5b238f0364c57a705beabd24d3eea3159a6f3a24c07e3fbb13657ffae0", + "zh:a676549a98164b61630658cbeb6c17820331ca04a049dc9b5095996a0c31ffbe", + "zh:a8a81b7fe41dd61eb6a6fa5e08a4dd9ee070e862868252a7fd4cfce30364efee", + "zh:c26a9bca4865665084e7f59b1402d7aff34ee63a418d7401a0658fa280cad4d4", + "zh:c638d8d0762e62ea188f86302954ef4c92803f2160f0a45fca0cd13974bd3725", + "zh:e739a0b7e81ca816944a18a38e679f4015edf8be7ac319815cdea865ba7727d7", + "zh:ec099487ea3de8999c84b3b791e242d728461e51fe344832b37bd8d521201c77", + "zh:f016ff9e2daab5b88185cec0795213049d105439ffd585d3309a714514ccae13", ] } diff --git a/README.md b/README.md index 2332bf1..9530b00 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,8 @@ When a commit is pushed to the `main` branch (e.g., when a pull request merges), ### Who approves a change to this repository? -- Every pull request to the default branch needs an approval of `github-config-owners` (a team of one person, `team-members/github-config-owners.csv`): the ruleset `owner-review` in `repositories.tf`. The author of a pull request cannot approve it, so a pull request of an owner is approved by someone else, or merged by an organization admin who bypasses the ruleset. -- A pull request **merges by itself** once it has what it needs: the owner's approval, the team's approval for a team file, the other approvals and a green `pre-commit`. `.github/workflows/auto-merge.yaml` turns on GitHub's auto-merge for every pull request that is not a draft; GitHub merges it the moment the rules are met. A new commit drops the approvals (`dismiss_stale_reviews`), so nothing changes after it was reviewed. To keep a pull request from merging, make it a draft or request changes. The merge is made with the workflow's token, which starts no workflow, so `apply.yaml` follows on its schedule (every 4 hours) or by hand. +- Every pull request to the default branch needs an approval of `github-config-owners` (a team of one person, `team-members/github-config-owners.csv`): the ruleset `owner-review` in `repositories.tf`. The author of a pull request cannot approve it, and the team has one member, so a pull request written by that owner can only be merged by an organization admin, who bypasses the ruleset (the owner is one). Add a second person to `team-members/github-config-owners.csv` to change that. +- A pull request **merges by itself** once it has what it needs: the owner's approval, the team's approval for a team file, the other approvals and a green `pre-commit`. `.github/workflows/auto-merge.yaml` turns on GitHub's auto-merge for every pull request to the default branch that is not a draft, each time `pre-commit` has run for it (it runs when `pre-commit` ends, as a run of the default branch, so it adds no row to a pull request); GitHub merges it the moment the rules are met. A new commit drops the approvals (`dismiss_stale_reviews`), so nothing changes after it was reviewed. To keep a pull request from merging, make it a draft or request changes. The merge is made with the workflow's token, which starts no workflow, so `apply.yaml` follows on its schedule (every 4 hours) or by hand. - A change to `team-members/.csv` also needs an approval from that team (`CODEOWNERS`), so that a team decides who joins it. A team that is secret or has no access to this repository cannot be a code owner (`fulfillment-wg`, `observability-wg`, `personas-wg`, `documentation-wg`, `org-admins`, `ci-duty`): its file has no rule and needs only the owners' approval. - When you add a team to `teams.csv` with `contributor` set to `true` and a `closed` privacy, add a line for its file to `CODEOWNERS` (`/team-members/.csv @osac-project/`). diff --git a/versions.tf b/versions.tf index 5cccad3..e43e739 100644 --- a/versions.tf +++ b/versions.tf @@ -3,7 +3,7 @@ terraform { required_providers { github = { source = "integrations/github" - version = "~> 6.11" # 6.11 added required reviewers to rulesets (repositories.tf: owner-review) + version = "~> 6.13" # 6.13 reads the team reviewer id of a ruleset (required reviewers, repositories.tf: owner-review) } } } From dc4982e6aff3dd142ae93b69cdd67a8ce3b71cb0 Mon Sep 17 00:00:00 2001 From: Elior Erez Date: Tue, 3 Nov 2026 13:03:04 -0500 Subject: [PATCH 5/5] NO-ISSUE: Run pre-commit when a draft is marked ready Auto-merge starts when pre-commit ends and skips a draft, and marking a pull request ready did not start another pre-commit run, so it would not have been turned on until a new commit. Add ready_for_review to the pull request types, with the default ones. Signed-off-by: Elior Erez --- .github/workflows/pre-commit.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 671123b..9a9d658 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -3,6 +3,9 @@ name: pre-commit on: workflow_dispatch: pull_request: + # The default types plus ready_for_review: auto-merge.yaml acts when pre-commit ends, and skips a draft, so a pull request + # that is marked ready needs a run of its own. + types: [opened, synchronize, reopened, ready_for_review] push: branches-ignore: - main