From 7e0400f6a9b70ce099f04e95b089ec3f930d7542 Mon Sep 17 00:00:00 2001 From: Soren Martius Date: Sat, 5 Mar 2022 06:42:45 +0100 Subject: [PATCH] feat: add support for github_branches --- CHANGELOG.md | 4 +++ README.md | 41 +++++++++++++++++++++++++++-- README.tfdoc.hcl | 54 ++++++++++++++++++++++++++++++++++++-- main.tf | 26 ++++++++++++++++++ outputs.tf | 25 +++++++++++++++--- test/unit-complete/main.tf | 22 +++++++++++++--- variables.tf | 11 ++++++++ 7 files changed, 171 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a612e86..1b37f6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Set correct alternative type for `deploy_keys` in README +### Added + +- Add support for `github_branches` + ## [0.14.0] ### Added diff --git a/README.md b/README.md index bdd77b5..370135b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ _Security related notice: Versions 4.7.0, 4.8.0, 4.9.0 and 4.9.1 of the Terrafor - [Repository Creation Configuration](#repository-creation-configuration) - [Teams Configuration](#teams-configuration) - [Collaborator Configuration](#collaborator-configuration) + - [Branches Configuration](#branches-configuration) - [Deploy Keys Configuration](#deploy-keys-configuration) - [Branch Protections Configuration](#branch-protections-configuration) - [Issue Labels Configuration](#issue-labels-configuration) @@ -62,6 +63,7 @@ features like Branch Protection or Collaborator Management. Template Repository - **Extended Repository Features**: + Branches, Branch Protection, Issue Labels, Handle Github Default Issue Labels, @@ -259,8 +261,10 @@ See [variables.tf] and [examples/] for details and use-cases. - [**`default_branch`**](#var-default_branch): *(Optional `string`)* The name of the default branch of the repository. - NOTE: This can only be set after a repository has already been created, and after a correct reference has been created for the target branch inside the repository. - This means a user will have to omit this parameter from the initial repository creation and create the target branch inside of the repository prior to setting this attribute. + NOTE: The configured default branch must exist in the repository. + If the branch doesn't exist yet, or if you are creating a new + repository, please add the desired default branch to the `branches` + variable, which will cause Terraform to create it for you. Default is `""`. @@ -416,6 +420,32 @@ This is due to some terraform limitation and we will update the module once terr Default is `[]`. +#### Branches Configuration + +- [**`branches`**](#var-branches): *(Optional `list(branch)`)* + + Can also be type `list(string)`. Create and manage branches within your repository. + Additional constraints can be applied to ensure your branch is created from another branch or commit. + Every `string` in the list will be converted internally into the `object` representation with the `key` argument being set to the `string`. `object` details are explained below. + + Default is `[]`. + + Each `branch` object in the list accepts the following attributes: + + - [**`name`**](#attr-branches-name): *(**Required** `string`)* + + The name of the branch to create. + + - [**`source_branch`**](#attr-branches-source_branch): *(Optional `string`)* + + The branch name to start from. Uses the configured default branch per default. + + - [**`source_sha`**](#attr-branches-source_sha): *(Optional `bool`)* + + The commit hash to start from. Defaults to the tip of `source_branch`. If provided, `source_branch` is ignored. + + Default is `true`. + #### Deploy Keys Configuration - [**`deploy_keys`**](#var-deploy_keys): *(Optional `list(deploy_key)`)* @@ -800,6 +830,12 @@ The following attributes are exported by the module: resource containing all arguments as specified above and the other attributes as specified below. +- [**`branches`**](#output-branches): *(`object(branches)`)* + + All repository attributes as returned by the [`github_branch`] + resource containing all arguments as specified above and the other + attributes as specified below. + - [**`full_name`**](#output-full_name): *(`string`)* A string of the form "orgname/reponame". @@ -856,6 +892,7 @@ The following attributes are exported by the module: ### Terraform Github Provider Documentation - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository +- https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_collaborator - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_deploy_key - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_project diff --git a/README.tfdoc.hcl b/README.tfdoc.hcl index 5f0a2e2..bac8c0b 100644 --- a/README.tfdoc.hcl +++ b/README.tfdoc.hcl @@ -65,6 +65,7 @@ section { Template Repository - **Extended Repository Features**: + Branches, Branch Protection, Issue Labels, Handle Github Default Issue Labels, @@ -317,8 +318,10 @@ section { default = "" description = <<-END The name of the default branch of the repository. - NOTE: This can only be set after a repository has already been created, and after a correct reference has been created for the target branch inside the repository. - This means a user will have to omit this parameter from the initial repository creation and create the target branch inside of the repository prior to setting this attribute. + NOTE: The configured default branch must exist in the repository. + If the branch doesn't exist yet, or if you are creating a new + repository, please add the desired default branch to the `branches` + variable, which will cause Terraform to create it for you. END } @@ -529,6 +532,43 @@ section { } } + section { + title = "Branches Configuration" + + variable "branches" { + type = list(branch) + default = [] + description = <<-END + Can also be type `list(string)`. Create and manage branches within your repository. + Additional constraints can be applied to ensure your branch is created from another branch or commit. + Every `string` in the list will be converted internally into the `object` representation with the `key` argument being set to the `string`. `object` details are explained below. + END + + attribute "name" { + required = true + type = string + description = <<-END + The name of the branch to create. + END + } + + attribute "source_branch" { + type = string + description = <<-END + The branch name to start from. Uses the configured default branch per default. + END + } + + attribute "source_sha" { + type = bool + default = true + description = <<-END + The commit hash to start from. Defaults to the tip of `source_branch`. If provided, `source_branch` is ignored. + END + } + } + } + section { title = "Deploy Keys Configuration" @@ -1046,6 +1086,15 @@ section { END } + output "branches" { + type = object(branches) + description = <<-END + All repository attributes as returned by the [`github_branch`] + resource containing all arguments as specified above and the other + attributes as specified below. + END + } + output "full_name" { type = string description = <<-END @@ -1138,6 +1187,7 @@ section { title = "Terraform Github Provider Documentation" content = <<-END - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository + - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_collaborator - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_deploy_key - https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_project diff --git a/main.tf b/main.tf index bb0aa54..1c414cf 100644 --- a/main.tf +++ b/main.tf @@ -144,6 +144,30 @@ resource "github_repository" "repository" { } } +# --------------------------------------------------------------------------------------------------------------------- +# Manage branches +# https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch +# --------------------------------------------------------------------------------------------------------------------- + +locals { + branches_temp = [ + for b in var.branches : try({ name = tostring(b) }, b) + ] + + branches = { + for b in local.branches_temp : b.name => b + } +} + +resource "github_branch" "branch" { + for_each = local.branches + + repository = github_repository.repository.name + branch = each.value.name + source_branch = try(each.value.source_branch, null) + source_sha = try(each.value.source_sha, null) +} + # --------------------------------------------------------------------------------------------------------------------- # Set default branch # https://registry.terraform.io/providers/integrations/github/latest/docs/resources/branch_default @@ -154,6 +178,8 @@ resource "github_branch_default" "default" { repository = github_repository.repository.name branch = local.default_branch + + depends_on = [github_branch.branch] } # --------------------------------------------------------------------------------------------------------------------- diff --git a/outputs.tf b/outputs.tf index 76918c6..e42cac5 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,7 +1,6 @@ -output "repository" { - value = github_repository.repository - description = "All attributes and arguments as returned by the github_repository resource." -} +# ---------------------------------------------------------------------------------------------------------------------- +# OUTPUT CALCULATED VARIABLES (prefer full objects) +# ---------------------------------------------------------------------------------------------------------------------- output "full_name" { value = github_repository.repository.full_name @@ -28,6 +27,20 @@ output "git_clone_url" { description = "URL that can be provided to git clone to clone the repository anonymously via the git protocol." } +# ---------------------------------------------------------------------------------------------------------------------- +# OUTPUT ALL RESOURCES AS FULL OBJECTS +# ---------------------------------------------------------------------------------------------------------------------- + +output "repository" { + value = github_repository.repository + description = "All attributes and arguments as returned by the github_repository resource." +} + +output "branches" { + value = github_branch.branch + description = "A map of branch objects keyed by branch name." +} + output "collaborators" { value = github_repository_collaborator.collaborator description = "A map of collaborator objects keyed by collaborator.name." @@ -65,3 +78,7 @@ output "secrets" { value = [for secret in github_actions_secret.repository_secret : secret.secret_name] description = "List of secrets available." } + +# ---------------------------------------------------------------------------------------------------------------------- +# OUTPUT MODULE CONFIGURATION +# ---------------------------------------------------------------------------------------------------------------------- diff --git a/test/unit-complete/main.tf b/test/unit-complete/main.tf index b436ed6..bd661e4 100644 --- a/test/unit-complete/main.tf +++ b/test/unit-complete/main.tf @@ -49,8 +49,16 @@ module "repository" { archived = false topics = var.topics - admin_collaborators = ["terraform-test-user-1"] + branches = [ + { + name = "develop" + }, + { + name = "staging" + }, + ] + admin_collaborators = ["terraform-test-user-1"] admin_team_ids = [ github_team.team.id @@ -140,9 +148,15 @@ resource "github_branch" "development" { module "repository-with-defaults" { source = "../.." - name = var.repository_with_defaults_name - description = var.repository_with_defaults_description - defaults = var.repository_defaults + name = var.repository_with_defaults_name + description = var.repository_with_defaults_description + defaults = var.repository_defaults + default_branch = "development" + + branches = [ + "development", + "prod", + ] } # --------------------------------------------------------------------------------------------------------------------- diff --git a/variables.tf b/variables.tf index 3c8728d..674855a 100644 --- a/variables.tf +++ b/variables.tf @@ -13,6 +13,17 @@ variable "name" { # These variables have defaults, but may be overridden. # --------------------------------------------------------------------------------------------------------------------- +variable "branches" { + description = "(Optional) A list of branches to be created in this repository." + type = any + # type = list(object({ + # name = string + # source_branch = optional(string) + # source_sha = optional(string) + # })) + default = [] +} + variable "defaults" { description = "(Optional) Overwrite defaults for various repository settings" type = any