diff --git a/modules/common_repository/README.md b/modules/common_repository/README.md index 6b66bd5..7ddfa01 100644 --- a/modules/common_repository/README.md +++ b/modules/common_repository/README.md @@ -32,38 +32,48 @@ module "repo_docs" { ## Requirements | Name | Version | -|------|---------| +| ---- | ------- | | [terraform](#requirement\_terraform) | >= 1.9.0 | | [github](#requirement\_github) | ~> 6.0 | ## Providers | Name | Version | -|------|---------| +| ---- | ------- | | [github](#provider\_github) | ~> 6.0 | ## Resources | Name | Type | -|------|------| +| ---- | ---- | | [github_branch_protection.repo_protection](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_protection) | resource | | [github_issue_label.repo_labels](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/issue_label) | resource | | [github_repository.repo](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | | [github_repository_collaborators.repo_collaborators](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_collaborators) | resource | +| [github_repository_environment.env](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_environment) | resource | +| [github_repository_ruleset.merge_queue](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_ruleset) | resource | ## Inputs | Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| +| ---- | ----------- | ---- | ------- | :------: | | [all\_members\_permission](#input\_all\_members\_permission) | Permission for all organization members | `string` | `"triage"` | no | +| [allow\_merge\_commit](#input\_allow\_merge\_commit) | Allow merge commits on pull requests | `bool` | `true` | no | +| [allow\_rebase\_merge](#input\_allow\_rebase\_merge) | Allow rebase merging on pull requests | `bool` | `true` | no | +| [allow\_squash\_merge](#input\_allow\_squash\_merge) | Allow squash merging on pull requests | `bool` | `true` | no | +| [archived](#input\_archived) | Whether the repository is archived | `bool` | `false` | no | | [branch\_protection](#input\_branch\_protection) | Configure branch protection if true | `bool` | `true` | no | -| [description](#input\_description) | Repository description | `string` | `""` | no | +| [description](#input\_description) | Repository description | `string` | n/a | yes | +| [environments](#input\_environments) | GitHub environments to create for this repository |
list(object({
name = string
reviewers = optional(object({
teams = optional(list(string), [])
users = optional(list(string), [])
}))
deployment_branch_policy = optional(object({
protected_branches = optional(bool, true)
custom_branch_policies = optional(bool, false)
}))
})) | `[]` | no |
| [is\_template](#input\_is\_template) | Set this to true if this is a template repository | `bool` | `false` | no |
| [labels](#input\_labels) | List of labels to configure on the repository | list(object({
name = string
color = string
description = string
})) | `null` | no |
+| [merge\_queue](#input\_merge\_queue) | Enable GitHub merge queue for the default branch. When set, a repository ruleset is created that requires PRs to pass through the merge queue before merging. | object({
merge_method = optional(string, "SQUASH")
min_entries_to_merge = optional(number, 1)
max_entries_to_merge = optional(number, 5)
check_response_timeout_minutes = optional(number, 90)
grouping_strategy = optional(string, "ALLGREEN")
}) | `null` | no |
| [name](#input\_name) | The name of the repository | `string` | n/a | yes |
| [pages](#input\_pages) | Configuration for github pages | object({
source = optional(object({
branch = string
path = string
}))
build_type = optional(string, "legacy")
cname = optional(string)
}) | `null` | no |
+| [push\_allowances](#input\_push\_allowances) | Actors allowed to push to the protected branch. When set, restricts both direct pushes and PR merges to these actors only. Actor names must begin with '/' for users or 'org-name/' for teams. | `list(string)` | `null` | no |
| [required\_approvals](#input\_required\_approvals) | Number of approvals required before merging a pull request | `number` | `1` | no |
| [required\_status\_checks](#input\_required\_status\_checks) | A list of status checks that must pass before a PR can merge | `list(string)` | `[]` | no |
+| [strict\_status\_checks](#input\_strict\_status\_checks) | Require the PR branch to be up to date with the base branch before merging. Disable when using merge queues, which handle this automatically. | `bool` | `true` | no |
| [teams](#input\_teams) | Teams with access to this repository | list(object({
team_id = string
permission = string
})) | `[]` | no |
| [use\_public\_template](#input\_use\_public\_template) | Use the public\_template repository as the template for a new repository | `bool` | `true` | no |
| [users](#input\_users) | Users with access to this repository | list(object({
username = string
permission = string
})) | `[]` | no |
diff --git a/modules/common_repository/main.tf b/modules/common_repository/main.tf
index fa0f0b1..e90bcc9 100644
--- a/modules/common_repository/main.tf
+++ b/modules/common_repository/main.tf
@@ -98,13 +98,54 @@ resource "github_branch_protection" "repo_protection" {
}
required_status_checks {
- strict = true
+ strict = var.strict_status_checks
contexts = var.required_status_checks
}
depends_on = [github_repository.repo, github_repository_collaborators.repo_collaborators]
}
+data "github_team" "merge_queue_bypass" {
+ for_each = var.merge_queue != null ? toset(["wg-infra", "org-admins"]) : []
+ slug = each.value
+}
+
+resource "github_repository_ruleset" "merge_queue" {
+ count = var.merge_queue != null ? 1 : 0
+ name = "merge-queue"
+ repository = github_repository.repo.name
+ target = "branch"
+ enforcement = "active"
+
+ conditions {
+ ref_name {
+ include = ["~DEFAULT_BRANCH"]
+ exclude = []
+ }
+ }
+
+ dynamic "bypass_actors" {
+ for_each = data.github_team.merge_queue_bypass
+ content {
+ actor_id = bypass_actors.value.id
+ actor_type = "Team"
+ bypass_mode = "pull_request"
+ }
+ }
+
+ rules {
+ merge_queue {
+ merge_method = var.merge_queue.merge_method
+ min_entries_to_merge = var.merge_queue.min_entries_to_merge
+ max_entries_to_merge = var.merge_queue.max_entries_to_merge
+ check_response_timeout_minutes = var.merge_queue.check_response_timeout_minutes
+ grouping_strategy = var.merge_queue.grouping_strategy
+ }
+ }
+
+ depends_on = [github_repository.repo]
+}
+
resource "github_repository_environment" "env" {
for_each = {
for env in var.environments :
diff --git a/modules/common_repository/variables.tf b/modules/common_repository/variables.tf
index 4512a3a..0d9fd38 100644
--- a/modules/common_repository/variables.tf
+++ b/modules/common_repository/variables.tf
@@ -26,6 +26,12 @@ variable "required_status_checks" {
default = []
}
+variable "strict_status_checks" {
+ description = "Require the PR branch to be up to date with the base branch before merging. Disable when using merge queues, which handle this automatically."
+ type = bool
+ default = true
+}
+
variable "visibility" {
description = "Repository visibility (public or private)"
type = string
@@ -175,6 +181,28 @@ variable "environments" {
}
}
+variable "merge_queue" {
+ description = "Enable GitHub merge queue for the default branch. When set, a repository ruleset is created that requires PRs to pass through the merge queue before merging."
+ type = object({
+ merge_method = optional(string, "SQUASH")
+ min_entries_to_merge = optional(number, 1)
+ max_entries_to_merge = optional(number, 5)
+ check_response_timeout_minutes = optional(number, 90)
+ grouping_strategy = optional(string, "ALLGREEN")
+ })
+ default = null
+
+ validation {
+ condition = var.merge_queue == null || contains(["MERGE", "SQUASH", "REBASE"], var.merge_queue.merge_method)
+ error_message = "merge_method must be MERGE, SQUASH, or REBASE"
+ }
+
+ validation {
+ condition = var.merge_queue == null || contains(["ALLGREEN", "HEADGREEN"], var.merge_queue.grouping_strategy)
+ error_message = "grouping_strategy must be ALLGREEN or HEADGREEN"
+ }
+}
+
variable "all_members_permission" {
description = "Permission for all organization members"
type = string
diff --git a/repositories.tf b/repositories.tf
index 0a1f401..e7d4fbc 100644
--- a/repositories.tf
+++ b/repositories.tf
@@ -107,11 +107,12 @@ module "repo_fulfillment_service" {
]
required_approvals = null
required_status_checks = [
- "ci/prow/unit",
"e2e-vmaas-full-install / e2e"
]
- push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
- environments = [{ name = "e2e-test" }]
+ push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
+ environments = [{ name = "e2e-test" }]
+ merge_queue = {}
+ strict_status_checks = false
pages = {
build_type = "workflow"
source = {
@@ -138,11 +139,12 @@ module "repo_cloudkit_operator" {
]
required_approvals = null
required_status_checks = [
- "ci/prow/temp",
"e2e-vmaas-full-install / e2e"
]
- push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
- environments = [{ name = "e2e-test" }]
+ push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
+ environments = [{ name = "e2e-test" }]
+ merge_queue = {}
+ strict_status_checks = false
}
module "repo_cloudkit_aap" {
@@ -162,11 +164,12 @@ module "repo_cloudkit_aap" {
]
required_approvals = null
required_status_checks = [
- "ci/prow/temp",
"e2e-vmaas-full-install / e2e"
]
- push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
- environments = [{ name = "e2e-test" }]
+ push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
+ environments = [{ name = "e2e-test" }]
+ merge_queue = {}
+ strict_status_checks = false
}
module "repo_cloudkit_aap_ee" {
@@ -215,9 +218,11 @@ module "repo_osac_installer" {
"e2e-vmaas-full-install / e2e"
]
- required_approvals = null
- push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
- environments = [{ name = "e2e-test" }]
+ required_approvals = null
+ push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
+ environments = [{ name = "e2e-test" }]
+ merge_queue = {}
+ strict_status_checks = false
}
module "repo_enhancement_proposals" {
@@ -244,9 +249,11 @@ module "repo_osac_test_infra" {
permission = "admin"
}
]
- required_approvals = null
- push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
- environments = [{ name = "e2e-test" }]
+ required_approvals = null
+ push_allowances = ["/openshift-merge-robot", "osac-project/wg-infra", "osac-project/org-admins"]
+ environments = [{ name = "e2e-test" }]
+ merge_queue = {}
+ strict_status_checks = false
}
module "repo_massopencloud_templates" {