Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions modules/common_repository/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,38 +32,48 @@ module "repo_docs" {
## Requirements

| Name | Version |
|------|---------|
| ---- | ------- |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.9.0 |
| <a name="requirement_github"></a> [github](#requirement\_github) | ~> 6.0 |

## Providers

| Name | Version |
|------|---------|
| ---- | ------- |
| <a name="provider_github"></a> [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 |
|------|-------------|------|---------|:--------:|
| ---- | ----------- | ---- | ------- | :------: |
| <a name="input_all_members_permission"></a> [all\_members\_permission](#input\_all\_members\_permission) | Permission for all organization members | `string` | `"triage"` | no |
| <a name="input_allow_merge_commit"></a> [allow\_merge\_commit](#input\_allow\_merge\_commit) | Allow merge commits on pull requests | `bool` | `true` | no |
| <a name="input_allow_rebase_merge"></a> [allow\_rebase\_merge](#input\_allow\_rebase\_merge) | Allow rebase merging on pull requests | `bool` | `true` | no |
| <a name="input_allow_squash_merge"></a> [allow\_squash\_merge](#input\_allow\_squash\_merge) | Allow squash merging on pull requests | `bool` | `true` | no |
| <a name="input_archived"></a> [archived](#input\_archived) | Whether the repository is archived | `bool` | `false` | no |
| <a name="input_branch_protection"></a> [branch\_protection](#input\_branch\_protection) | Configure branch protection if true | `bool` | `true` | no |
| <a name="input_description"></a> [description](#input\_description) | Repository description | `string` | `""` | no |
| <a name="input_description"></a> [description](#input\_description) | Repository description | `string` | n/a | yes |
| <a name="input_environments"></a> [environments](#input\_environments) | GitHub environments to create for this repository | <pre>list(object({<br/> name = string<br/> reviewers = optional(object({<br/> teams = optional(list(string), [])<br/> users = optional(list(string), [])<br/> }))<br/> deployment_branch_policy = optional(object({<br/> protected_branches = optional(bool, true)<br/> custom_branch_policies = optional(bool, false)<br/> }))<br/> }))</pre> | `[]` | no |
| <a name="input_is_template"></a> [is\_template](#input\_is\_template) | Set this to true if this is a template repository | `bool` | `false` | no |
| <a name="input_labels"></a> [labels](#input\_labels) | List of labels to configure on the repository | <pre>list(object({<br/> name = string<br/> color = string<br/> description = string<br/> }))</pre> | `null` | no |
| <a name="input_merge_queue"></a> [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. | <pre>object({<br/> merge_method = optional(string, "SQUASH")<br/> min_entries_to_merge = optional(number, 1)<br/> max_entries_to_merge = optional(number, 5)<br/> check_response_timeout_minutes = optional(number, 90)<br/> grouping_strategy = optional(string, "ALLGREEN")<br/> })</pre> | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | The name of the repository | `string` | n/a | yes |
| <a name="input_pages"></a> [pages](#input\_pages) | Configuration for github pages | <pre>object({<br/> source = optional(object({<br/> branch = string<br/> path = string<br/> }))<br/> build_type = optional(string, "legacy")<br/> cname = optional(string)<br/> })</pre> | `null` | no |
| <a name="input_push_allowances"></a> [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 |
| <a name="input_required_approvals"></a> [required\_approvals](#input\_required\_approvals) | Number of approvals required before merging a pull request | `number` | `1` | no |
| <a name="input_required_status_checks"></a> [required\_status\_checks](#input\_required\_status\_checks) | A list of status checks that must pass before a PR can merge | `list(string)` | `[]` | no |
| <a name="input_strict_status_checks"></a> [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 |
| <a name="input_teams"></a> [teams](#input\_teams) | Teams with access to this repository | <pre>list(object({<br/> team_id = string<br/> permission = string<br/> }))</pre> | `[]` | no |
| <a name="input_use_public_template"></a> [use\_public\_template](#input\_use\_public\_template) | Use the public\_template repository as the template for a new repository | `bool` | `true` | no |
| <a name="input_users"></a> [users](#input\_users) | Users with access to this repository | <pre>list(object({<br/> username = string<br/> permission = string<br/> }))</pre> | `[]` | no |
Expand Down
43 changes: 42 additions & 1 deletion modules/common_repository/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Comment on lines +101 to 103

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Automatically disable strict status checks when a merge queue is configured.

GitHub does not allow requiring branches to be up to date before merging when a merge queue is active. To prevent API errors and reduce the configuration burden on module consumers, consider automatically enforcing strict = false when var.merge_queue is provided.

♻️ Proposed refactor
   required_status_checks {
-    strict   = var.strict_status_checks
+    strict   = var.merge_queue != null ? false : var.strict_status_checks
     contexts = var.required_status_checks
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
strict = var.strict_status_checks
contexts = var.required_status_checks
}
required_status_checks {
strict = var.merge_queue != null ? false : var.strict_status_checks
contexts = var.required_status_checks
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@modules/common_repository/main.tf` around lines 101 - 103, Update the strict
status-check assignment in the branch protection configuration to force false
whenever var.merge_queue is configured, while preserving
var.strict_status_checks when no merge queue is provided. Keep the existing
required status-check contexts unchanged.


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
}
}
Comment on lines +136 to +144

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that if var.merge_queue == null the count will be zero. But, will TF also skip trying to make these assignments?

Suggested change
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
}
}
rules {
# Use a dynamic block to only generate the merge_queue configuration
# if var.merge_queue is not null.
dynamic "merge_queue" {
for_each = var.merge_queue != null ? [var.merge_queue] : []
content {
merge_method = merge_queue.value.merge_method
min_entries_to_merge = merge_queue.value.min_entries_to_merge
max_entries_to_merge = merge_queue.value.max_entries_to_merge
check_response_timeout_minutes = merge_queue.value.check_response_timeout_minutes
grouping_strategy = merge_queue.value.grouping_strategy
}
}
}


depends_on = [github_repository.repo]
}

resource "github_repository_environment" "env" {
for_each = {
for env in var.environments :
Expand Down
28 changes: 28 additions & 0 deletions modules/common_repository/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
37 changes: 22 additions & 15 deletions repositories.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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" {
Expand All @@ -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" {
Expand Down Expand Up @@ -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" {
Expand All @@ -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" {
Expand Down
Loading