Skip to content

Commit

Permalink
feat: split repo owners (#2775)
Browse files Browse the repository at this point in the history
  • Loading branch information
apeabody authored Dec 28, 2024
1 parent c1f3ebb commit 9b23ce2
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 108 deletions.
12 changes: 10 additions & 2 deletions infra/terraform/modules/branch_protection/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,10 @@ resource "github_branch_protection" "default" {
required_pull_request_reviews {
required_approving_review_count = 1
require_code_owner_reviews = true
pull_request_bypassers = setunion(
[var.admin],
formatlist("/%s", lookup(var.repos_map[each.key], "admins", []))
)
}

required_status_checks {
Expand All @@ -37,7 +41,11 @@ resource "github_branch_protection" "default" {
enforce_admins = false

restrict_pushes {
push_allowances = [var.admin]
push_allowances = setunion(
[var.admin],
formatlist("/%s", setunion(lookup(var.repos_map[each.key], "admins", []), lookup(var.repos_map[each.key], "maintainers", []))),
formatlist("${var.repos_map[each.key].org}/%s", lookup(var.repos_map[each.key], "groups", []))
)
blocks_creations = false
}
}
13 changes: 12 additions & 1 deletion infra/terraform/modules/branch_protection/variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -23,6 +23,17 @@ variable "repo_list" {
type = map(any)
}

variable "repos_map" {
description = "Map of Repos"
type = map(object({
name = string
org = string
admins = optional(list(string), [])
maintainers = optional(list(string), [])
groups = optional(list(string), [])
}))
}

variable "admin" {
description = "GitHub Admin"
type = string
Expand Down
2 changes: 1 addition & 1 deletion infra/terraform/modules/codeowners_file/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
locals {
commit_author = "CFT Bot"
commit_email = "[email protected]"
owners = { for value in var.repos_map : value.name => "${join(" ", formatlist("@%s", value.owners))} " if length(value.owners) > 0 }
owners = { for value in var.repos_map : value.name => "${join(" ", formatlist("@%s", sort(setunion(lookup(value, "admins", []), lookup(value, "maintainers", [])))))} " if length(setunion(lookup(value, "admins", []), lookup(value, "maintainers", []))) > 0 }
groups = { for value in var.repos_map : value.name => "${join(" ", formatlist("@${value.org}/%s", value.groups))} " if length(value.groups) > 0 }
header = "# NOTE: This file is automatically generated from values at:\n# https://github.com/GoogleCloudPlatform/cloud-foundation-toolkit/blob/master/infra/terraform/test-org/org/locals.tf\n"
footer_prefix = "# NOTE: GitHub CODEOWNERS locations:\n# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#codeowners-and-branch-protection\n"
Expand Down
11 changes: 6 additions & 5 deletions infra/terraform/modules/codeowners_file/variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,10 +32,11 @@ variable "owner" {
variable "repos_map" {
description = "Map of Repos"
type = map(object({
name = string
org = string
owners = optional(list(string), [])
groups = optional(list(string), [])
name = string
org = string
admins = optional(list(string), [])
maintainers = optional(list(string), [])
groups = optional(list(string), [])
}))
}

Expand Down
36 changes: 27 additions & 9 deletions infra/terraform/modules/repositories/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022-2023 Google LLC
* Copyright 2022-2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,11 +15,20 @@
*/

locals {
owners = flatten([
admins = flatten([
for repo, val in var.repos_map : [
for owner in val.owners : {
for admin in val.admins : {
"repo" : repo
"owner" : owner
"admin" : admin
}
]
])

maintainers = flatten([
for repo, val in var.repos_map : [
for maintainer in val.maintainers : {
"repo" : repo
"maintainer" : maintainer
}
]
])
Expand Down Expand Up @@ -79,13 +88,22 @@ resource "github_repository_collaborator" "cftbot" {
permission = "admin"
}

resource "github_repository_collaborator" "owners" {
resource "github_repository_collaborator" "admins" {
for_each = {
for v in local.owners : "${v.repo}/${v.owner}" => v
for v in local.admins : "${v.repo}/${v.admin}" => v
}
repository = each.value.repo
username = each.value.owner
permission = "admin"
username = each.value.admin
permission = "maintain"
}

resource "github_repository_collaborator" "maintainers" {
for_each = {
for v in local.maintainers : "${v.repo}/${v.maintainer}" => v
}
repository = each.value.repo
username = each.value.maintainer
permission = "write"
}

resource "github_team_repository" "groups" {
Expand All @@ -94,7 +112,7 @@ resource "github_team_repository" "groups" {
}
repository = each.value.repo
team_id = each.value.group
permission = "admin"
permission = "write"
}

resource "github_team_repository" "ci_teams" {
Expand Down
5 changes: 3 additions & 2 deletions infra/terraform/modules/repositories/variables.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022 Google LLC
* Copyright 2022-2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,7 +25,8 @@ variable "repos_map" {
short_name = optional(string)
org = string
description = optional(string)
owners = optional(list(string), [])
admins = optional(list(string), [])
maintainers = optional(list(string), [])
homepage_url = optional(string, null)
module = optional(bool, true)
topics = optional(string)
Expand Down
2 changes: 2 additions & 0 deletions infra/terraform/test-org/github/protection.tf
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,15 @@ import {
module "branch_protection_tgm" {
source = "../../modules/branch_protection"
repo_list = { for k, v in module.repos_tgm.repos : k => v if k != "terraform-example-foundation" }
repos_map = local.tgm_modules_map
admin = data.github_team.cft-admins.node_id
providers = { github = github }
}

module "branch_protection_gcp" {
source = "../../modules/branch_protection"
repo_list = module.repos_gcp.repos
repos_map = local.gcp_modules_map
admin = data.github_team.blueprint-solutions.node_id
providers = { github = github.gcp }
}
Expand Down
13 changes: 4 additions & 9 deletions infra/terraform/test-org/org/github.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2023 Google LLC
* Copyright 2023-2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,16 +16,11 @@
provider "github" {}

locals {
owners = distinct(
flatten(
[for repo, val in local.repos : [for owner in val.owners : lower(owner)] if try(val.owners != null, false)]
)
owners = flatten(
[for repo, val in local.repos : [for owner in setunion(lookup(val, "admins", []), lookup(val, "maintainers", [])) : owner]]
)

org_members = setunion(
[for login in data.github_organization.tgm.users[*].login : lower(login)],
[for login in data.github_organization.gcp.users[*].login : lower(login)]
)
org_members = [for login in setunion(data.github_organization.tgm.users[*].login, data.github_organization.gcp.users[*].login) : login]

invalid_owners = setsubtract(local.owners, local.org_members)
}
Expand Down
Loading

0 comments on commit 9b23ce2

Please sign in to comment.