diff --git a/CHANGELOG.md b/CHANGELOG.md
index cf18247..dc85945 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+### Added
+
+- Add support for `github_branches`
+
## [0.14.0]
### Added
diff --git a/README.md b/README.md
index ee0dbb4..586a839 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 35ab785..7487d47 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..9ca5320 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 : lookup(b, "id", b.name) => b
+ }
+}
+
+resource "github_branch" "branch" {
+ for_each = { for branch in local.branches : branch.name => branch }
+
+ 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