Skip to content

Commit

Permalink
feat: add v4 branch protections
Browse files Browse the repository at this point in the history
Signed-off-by: Trevor Wood <[email protected]>
  • Loading branch information
taharah committed Sep 2, 2022
1 parent fd18262 commit 4a001f6
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 22 deletions.
94 changes: 72 additions & 22 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,17 @@ locals {
topics = concat(local.standard_topics, var.extra_topics)
template = var.template == null ? [] : [var.template]
issue_labels_create = var.issue_labels_create == null ? lookup(var.defaults, "issue_labels_create", local.issue_labels_create_computed) : var.issue_labels_create
branch_protections_v3 = var.branch_protections_v3 == null ? var.branch_protections : var.branch_protections_v3
branch_protections_v3 = [
for b in coalesce(var.branch_protections_v3, var.branch_protections, []) : merge({
branch = null
enforce_admins = null
require_conversation_resolution = null
require_signed_commits = null
required_status_checks = {}
required_pull_request_reviews = {}
restrictions = {}
}, b)
]

issue_labels_create_computed = local.has_issues || length(var.issue_labels) > 0

Expand All @@ -41,20 +51,8 @@ locals {
}

locals {
branch_protections = try([
for b in local.branch_protections_v3 : merge({
branch = null
enforce_admins = null
require_conversation_resolution = null
require_signed_commits = null
required_status_checks = {}
required_pull_request_reviews = {}
restrictions = {}
}, b)
], [])

required_status_checks = [
for b in local.branch_protections :
for b in local.branch_protections_v3 :
length(keys(b.required_status_checks)) > 0 ? [
merge({
strict = null
Expand All @@ -63,7 +61,7 @@ locals {
]

required_pull_request_reviews = [
for b in local.branch_protections :
for b in local.branch_protections_v3 :
length(keys(b.required_pull_request_reviews)) > 0 ? [
merge({
dismiss_stale_reviews = true
Expand All @@ -75,7 +73,7 @@ locals {
]

restrictions = [
for b in local.branch_protections :
for b in local.branch_protections_v3 :
length(keys(b.restrictions)) > 0 ? [
merge({
users = []
Expand Down Expand Up @@ -137,6 +135,7 @@ resource "github_repository" "repository" {
lifecycle {
ignore_changes = [
auto_init,
branches,
license_template,
gitignore_template,
template,
Expand Down Expand Up @@ -177,12 +176,63 @@ resource "github_branch_default" "default" {
}

# ---------------------------------------------------------------------------------------------------------------------
# Branch Protection
# v4 Branch Protection
# https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_protection
# ---------------------------------------------------------------------------------------------------------------------

resource "github_branch_protection" "this" {
for_each = var.branch_protections_v4

# ensure we have all members and collaborators added before applying
# any configuration for them
depends_on = [
github_repository_collaborator.collaborator,
github_team_repository.team_repository,
github_team_repository.team_repository_by_slug,
github_branch.branch,
]

repository_id = github_repository.repository.node_id
pattern = each.key
allows_deletions = coalesce(each.value.allows_deletions, false)
allows_force_pushes = coalesce(each.value.allows_force_pushes, false)
blocks_creations = coalesce(each.value.blocks_creations, false)
enforce_admins = coalesce(each.value.enforce_admins, false)
push_restrictions = coalesce(each.value.push_restrictions, [])
require_conversation_resolution = coalesce(each.value.require_conversation_resolution, false)
require_signed_commits = coalesce(each.value.require_signed_commits, false)
required_linear_history = coalesce(each.value.required_linear_history, false)

dynamic "required_pull_request_reviews" {
for_each = each.value.required_pull_request_reviews != null ? [true] : []

content {
dismiss_stale_reviews = coalesce(each.value.required_pull_request_reviews.dismiss_stale_reviews, false)
dismissal_restrictions = coalesce(each.value.required_pull_request_reviews.dismissal_restrictions, [])
pull_request_bypassers = coalesce(each.value.required_pull_request_reviews.pull_request_bypassers, [])
require_code_owner_reviews = coalesce(each.value.required_pull_request_reviews.require_code_owner_reviews, false)
required_approving_review_count = coalesce(each.value.required_pull_request_reviews.required_approving_review_count, 0)
restrict_dismissals = length(coalesce(each.value.required_pull_request_reviews.dismissal_restrictions, [])) > 0
}
}

dynamic "required_status_checks" {
for_each = each.value.required_status_checks != null ? [true] : []

content {
strict = coalesce(each.value.required_status_checks.strict, false)
contexts = coalesce(each.value.required_status_checks.contexts, [])
}
}
}

# ---------------------------------------------------------------------------------------------------------------------
# v3 Branch Protection
# https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_protection_v3
# ---------------------------------------------------------------------------------------------------------------------

resource "github_branch_protection_v3" "branch_protection" {
count = length(local.branch_protections)
count = var.branch_protections_v4 == null ? length(local.branch_protections_v3) : 0

# ensure we have all members and collaborators added before applying
# any configuration for them
Expand All @@ -194,10 +244,10 @@ resource "github_branch_protection_v3" "branch_protection" {
]

repository = github_repository.repository.name
branch = local.branch_protections[count.index].branch
enforce_admins = local.branch_protections[count.index].enforce_admins
require_conversation_resolution = local.branch_protections[count.index].require_conversation_resolution
require_signed_commits = local.branch_protections[count.index].require_signed_commits
branch = local.branch_protections_v3[count.index].branch
enforce_admins = local.branch_protections_v3[count.index].enforce_admins
require_conversation_resolution = local.branch_protections_v3[count.index].require_conversation_resolution
require_signed_commits = local.branch_protections_v3[count.index].require_signed_commits

dynamic "required_status_checks" {
for_each = local.required_status_checks[count.index]
Expand Down
47 changes: 47 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,53 @@ variable "branch_protections_v3" {
# ]
}

variable "branch_protections_v4" {
description = "(Optional) A list of v4 branch protections to apply to the repository. Default is {}."
type = map(
object(
{
allows_deletions = optional(bool)
allows_force_pushes = optional(bool)
blocks_creations = optional(bool)
enforce_admins = optional(bool)
push_restrictions = optional(list(string))
require_conversation_resolution = optional(bool)
require_signed_commits = optional(bool)
required_linear_history = optional(bool)
required_pull_request_reviews = optional(object(
{
dismiss_stale_reviews = optional(bool)
dismissal_restrictions = optional(list(string))
pull_request_bypassers = optional(list(string))
require_code_owner_reviews = optional(bool)
required_approving_review_count = optional(number)
}
))
required_status_checks = optional(object(
{
strict = optional(bool)
contexts = optional(list(string))
}
))
}
)
)
default = null

validation {
condition = alltrue(
[
for cfg in coalesce(var.branch_protections_v4, {}) : try(
cfg.required_pull_request_reviews.required_approving_review_count >= 0
&& cfg.required_pull_request_reviews.required_approving_review_count <= 6,
true
)
]
)
error_message = "The value for branch_protections_v4.required_pull_request_reviews.required_approving_review_count must be between 0 and 6, inclusively."
}
}

variable "issue_labels_merge_with_github_labels" {
description = "(Optional) Specify if you want to merge and control githubs default set of issue labels."
type = bool
Expand Down
1 change: 1 addition & 0 deletions versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# ---------------------------------------------------------------------------------------------------------------------

terraform {
experiments = [module_variable_optional_attrs]
required_version = "~> 1.0"

# 4.7.0 to 4.9.1 has a security regression: new repositories created via a
Expand Down

0 comments on commit 4a001f6

Please sign in to comment.