From 3f49baca054906c477d0e558c4861c394b24f4a0 Mon Sep 17 00:00:00 2001 From: Oleksandr Kuzminskyi Date: Tue, 26 May 2026 15:08:50 -0700 Subject: [PATCH] Decouple environment approvals from deploy_order; add make smoke contract Closes #34 Co-Authored-By: Claude Opus 4.6 --- modules/service-repo/environments.tf | 9 ++++++-- modules/service-repo/templates/makefile.mk | 8 +++++++ .../templates/terraform-CD.yml.tftpl | 5 +++++ modules/service-repo/variables.tf | 21 +++++++++++++++---- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/modules/service-repo/environments.tf b/modules/service-repo/environments.tf index f7b3c61..cdf95a2 100644 --- a/modules/service-repo/environments.tf +++ b/modules/service-repo/environments.tf @@ -1,3 +1,8 @@ +data "github_team" "approval" { + count = var.approval_team_slug != null ? 1 : 0 + slug = var.approval_team_slug +} + resource "github_repository_environment" "ci" { for_each = var.environments environment = "continuous-integration-${each.key}" @@ -10,9 +15,9 @@ resource "github_repository_environment" "cd" { repository = github_repository.this.name dynamic "reviewers" { - for_each = each.value.deploy_order > 0 ? [1] : [] + for_each = var.approval_team_slug != null && each.value.deploy_order > 0 ? [1] : [] content { - teams = [data.github_team.release_managers.id] + teams = [data.github_team.approval[0].id] } } } diff --git a/modules/service-repo/templates/makefile.mk b/modules/service-repo/templates/makefile.mk index a3c777c..ad9de8d 100644 --- a/modules/service-repo/templates/makefile.mk +++ b/modules/service-repo/templates/makefile.mk @@ -43,6 +43,14 @@ plan: init ## Run terraform plan apply: ## Run terraform apply terraform apply -auto-approve -input=false tf.plan +.PHONY: smoke +smoke: ## Run post-deploy smoke test if scripts/smoke.sh exists + @if [ -x scripts/smoke.sh ]; then \ + scripts/smoke.sh "$(ENV)"; \ + else \ + echo "smoke[$(ENV)]: no scripts/smoke.sh, skipping"; \ + fi + .PHONY: clean clean: ## Remove generated files rm -fr .terraform diff --git a/modules/service-repo/templates/terraform-CD.yml.tftpl b/modules/service-repo/templates/terraform-CD.yml.tftpl index 0970fa2..c94b4d1 100644 --- a/modules/service-repo/templates/terraform-CD.yml.tftpl +++ b/modules/service-repo/templates/terraform-CD.yml.tftpl @@ -114,4 +114,9 @@ jobs: $${{ steps.extract_vars.outputs.ROLE_STATE_MANAGER }} \ remove \ plans/$${{ matrix.env }}/$${{ github.event.pull_request.number }}.plan + + - name: "Smoke Test" + working-directory: "environments/$${{ matrix.env }}" + run: | + make smoke ENV=$${{ matrix.env }} %{ endfor ~} diff --git a/modules/service-repo/variables.tf b/modules/service-repo/variables.tf index 483b4bb..12104b9 100644 --- a/modules/service-repo/variables.tf +++ b/modules/service-repo/variables.tf @@ -43,10 +43,12 @@ variable "environments" { deploy_order controls the CD workflow sequence. Environments with the same order deploy in parallel; higher numbers wait for lower ones to - finish (chained via needs:). Environments with deploy_order > 0 are - gated by a GitHub environment protection rule — var.release_managers - must approve before the deployment proceeds. Order 0 (default) deploys - automatically after PR merge. + finish (chained via needs:). Order 0 (default) deploys automatically + after PR merge. + + Set var.approval_team_slug to gate environments with deploy_order > 0 + behind a required-reviewer protection rule. Required reviewers on + private repos need GitHub Enterprise Cloud. EOT type = map(object({ region = string @@ -185,6 +187,17 @@ variable "release_managers" { type = string } +variable "approval_team_slug" { + description = <<-EOT + GitHub team slug whose members can approve deployments to environments + with deploy_order > 0. When null (default), no environments get + required reviewers. Required reviewers on private repos need GitHub + Enterprise Cloud. + EOT + type = string + default = null +} + variable "extra_codeowners" { description = <<-EOT Additional CODEOWNERS entries beyond the three standard functions