Skip to content

Commit c0bddc7

Browse files
committed
feat(repository-environment): support reviewers and deployment policy
1 parent d7f3045 commit c0bddc7

File tree

7 files changed

+173
-1
lines changed

7 files changed

+173
-1
lines changed

modules/repository-environment/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ No modules.
3232
| [github_actions_environment_secret.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_environment_secret) | resource |
3333
| [github_actions_environment_variable.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_environment_variable) | resource |
3434
| [github_repository_environment.this](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_environment) | resource |
35+
| [github_repository_environment_deployment_policy.branch](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_environment_deployment_policy) | resource |
36+
| [github_repository_environment_deployment_policy.tag](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_environment_deployment_policy) | resource |
37+
| [github_team.this](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/team) | data source |
38+
| [github_user.this](https://registry.terraform.io/providers/integrations/github/latest/docs/data-sources/user) | data source |
3539

3640
## Inputs
3741

@@ -41,6 +45,8 @@ No modules.
4145
| <a name="input_repository"></a> [repository](#input\_repository) | (Required) The repository name which the environment belongs to. | `string` | n/a | yes |
4246
| <a name="input_allow_admin_to_bypass"></a> [allow\_admin\_to\_bypass](#input\_allow\_admin\_to\_bypass) | (Optional) Whether to allow admins to bypass the wait timer and deployment review. The default value is `true`. | `bool` | `true` | no |
4347
| <a name="input_allows_self_approval"></a> [allows\_self\_approval](#input\_allows\_self\_approval) | (Optional) Whether to allow users to approve their own deployment. The default value is `false`. | `bool` | `false` | no |
48+
| <a name="input_deployment_policy"></a> [deployment\_policy](#input\_deployment\_policy) | (Optional) A configuration for deployment policy. `deployment_policy` block as defined below.<br/> (Optional) `restriction` - The type of deployment restriction. Valid values are `NONE`, `PROTECTED_BRANCH`, or `CUSTOM`. Defaults to `NONE`.<br/> (Optional) `branches` - A set of branch name patterns to restrict deployments to when the restriction type is `CUSTOM`.<br/> (Optional) `tags` - A set of tag name patterns to restrict deployments to when the restriction type is `CUSTOM`. | <pre>object({<br/> restriction = optional(string, "NONE")<br/> branches = optional(set(string), [])<br/> tags = optional(set(string), [])<br/> })</pre> | `{}` | no |
49+
| <a name="input_reviewers"></a> [reviewers](#input\_reviewers) | (Optional) A list of reviewers who may review jobs that reference the environment. Up to 6 reviewers can be added to an environment. Each item of `reviewers` block as defined below.<br/> (Required) `type` - The type of the reviewer. Valid values are `USER` or `TEAM`.<br/> (Required) `name` - The username of the reviewer if the type is `USER`, or the team slug if the type is `TEAM`. | <pre>list(object({<br/> type = string<br/> name = string<br/> }))</pre> | `[]` | no |
4450
| <a name="input_secrets"></a> [secrets](#input\_secrets) | (Optional) A map of GitHub Actions secrets to set for the environment. Currently, all values will be ignored and treated as placeholders. You should mange the secrets manually in GitHub after the environment is created. Defaults to `{}`. | `map(string)` | `{}` | no |
4551
| <a name="input_variables"></a> [variables](#input\_variables) | (Optional) A map of GitHub Actions variables to set for the environment. Defaults to `{}`. | `map(string)` | `{}` | no |
4652
| <a name="input_wait_timer"></a> [wait\_timer](#input\_wait\_timer) | (Optional) The amount of time in minutes to wait before allowing deployments to proceed. The default value is `0`. | `number` | `0` | no |
@@ -51,8 +57,10 @@ No modules.
5157
|------|-------------|
5258
| <a name="output_allow_admin_to_bypass"></a> [allow\_admin\_to\_bypass](#output\_allow\_admin\_to\_bypass) | Whether to allow admins to bypass the wait timer and deployment review. |
5359
| <a name="output_allows_self_approval"></a> [allows\_self\_approval](#output\_allows\_self\_approval) | Whether to allow users to approve their own deployment. |
60+
| <a name="output_deployment_policy"></a> [deployment\_policy](#output\_deployment\_policy) | The configuration for deployment policy of the environment. |
5461
| <a name="output_name"></a> [name](#output\_name) | The name of the environment. |
5562
| <a name="output_repository"></a> [repository](#output\_repository) | The repository name which the environment belongs to. |
63+
| <a name="output_reviewers"></a> [reviewers](#output\_reviewers) | A list of reviewers who may review jobs that reference the environment. |
5664
| <a name="output_secrets"></a> [secrets](#output\_secrets) | A map of GitHub Actions secrets set for the environment. Currently, all values will be placeholders and you should manage the secrets manually in GitHub after the environment is created. |
5765
| <a name="output_variables"></a> [variables](#output\_variables) | A map of GitHub Actions variables set for the environment. |
5866
| <a name="output_wait_timer"></a> [wait\_timer](#output\_wait\_timer) | The amount of time in minutes to wait before allowing deployments to proceed. |

modules/repository-environment/main.tf

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
data "github_team" "this" {
2+
for_each = toset([
3+
for reviewer in var.reviewers :
4+
reviewer.name
5+
if reviewer.type == "TEAM"
6+
])
7+
8+
slug = each.value
9+
}
10+
11+
data "github_user" "this" {
12+
for_each = toset([
13+
for reviewer in var.reviewers :
14+
reviewer.name
15+
if reviewer.type == "USER"
16+
])
17+
18+
username = each.value
19+
}
20+
21+
122
###################################################
223
# Environment of GitHub Repository
324
###################################################
@@ -10,6 +31,45 @@ resource "github_repository_environment" "this" {
1031
wait_timer = var.wait_timer
1132
can_admins_bypass = var.allow_admin_to_bypass
1233
prevent_self_review = !var.allows_self_approval
34+
35+
reviewers {
36+
teams = values(data.github_team.this)[*].id
37+
users = values(data.github_user.this)[*].id
38+
}
39+
40+
deployment_branch_policy {
41+
protected_branches = var.deployment_policy.restriction == "PROTECTED_BRANCHES"
42+
custom_branch_policies = var.deployment_policy.restriction == "CUSTOM"
43+
}
44+
}
45+
46+
47+
###################################################
48+
# Deployment Policy for Repository Environment
49+
###################################################
50+
51+
resource "github_repository_environment_deployment_policy" "branch" {
52+
for_each = (var.deployment_policy.restriction == "CUSTOM"
53+
? var.deployment_policy.branches
54+
: []
55+
)
56+
57+
repository = var.repository
58+
environment = github_repository_environment.this.environment
59+
60+
branch_pattern = each.value
61+
}
62+
63+
resource "github_repository_environment_deployment_policy" "tag" {
64+
for_each = (var.deployment_policy.restriction == "CUSTOM"
65+
? var.deployment_policy.tags
66+
: []
67+
)
68+
69+
repository = var.repository
70+
environment = github_repository_environment.this.environment
71+
72+
tag_pattern = each.value
1373
}
1474

1575

modules/repository-environment/outputs.tf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,33 @@ output "allows_self_approval" {
2323
value = !github_repository_environment.this.prevent_self_review
2424
}
2525

26+
output "reviewers" {
27+
description = "A list of reviewers who may review jobs that reference the environment."
28+
value = concat(
29+
[
30+
for team in data.github_team.this :
31+
{
32+
type = "TEAM"
33+
id = team.id
34+
name = team.slug
35+
}
36+
],
37+
[
38+
for user in data.github_user.this :
39+
{
40+
type = "USER"
41+
id = user.id
42+
name = user.username
43+
}
44+
]
45+
)
46+
}
47+
48+
output "deployment_policy" {
49+
description = "The configuration for deployment policy of the environment."
50+
value = var.deployment_policy
51+
}
52+
2653
output "variables" {
2754
description = "A map of GitHub Actions variables set for the environment."
2855
value = {

modules/repository-environment/variables.tf

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,53 @@ variable "allows_self_approval" {
3131
nullable = false
3232
}
3333

34+
variable "reviewers" {
35+
description = <<EOF
36+
(Optional) A list of reviewers who may review jobs that reference the environment. Up to 6 reviewers can be added to an environment. Each item of `reviewers` block as defined below.
37+
(Required) `type` - The type of the reviewer. Valid values are `USER` or `TEAM`.
38+
(Required) `name` - The username of the reviewer if the type is `USER`, or the team slug if the type is `TEAM`.
39+
EOF
40+
type = list(object({
41+
type = string
42+
name = string
43+
}))
44+
default = []
45+
nullable = false
46+
47+
validation {
48+
condition = alltrue([
49+
for reviewer in var.reviewers :
50+
contains(["USER", "TEAM"], reviewer.type)
51+
])
52+
error_message = "Valid values for `type` are `USER` or `TEAM`."
53+
}
54+
validation {
55+
condition = length(var.reviewers) <= 6
56+
error_message = "Up to 6 reviewers can be added to an environment."
57+
}
58+
}
59+
60+
variable "deployment_policy" {
61+
description = <<EOF
62+
(Optional) A configuration for deployment policy. `deployment_policy` block as defined below.
63+
(Optional) `restriction` - The type of deployment restriction. Valid values are `NONE`, `PROTECTED_BRANCH`, or `CUSTOM`. Defaults to `NONE`.
64+
(Optional) `branches` - A set of branch name patterns to restrict deployments to when the restriction type is `CUSTOM`.
65+
(Optional) `tags` - A set of tag name patterns to restrict deployments to when the restriction type is `CUSTOM`.
66+
EOF
67+
type = object({
68+
restriction = optional(string, "NONE")
69+
branches = optional(set(string), [])
70+
tags = optional(set(string), [])
71+
})
72+
default = {}
73+
nullable = false
74+
75+
validation {
76+
condition = contains(["NONE", "PROTECTED_BRANCH", "CUSTOM"], var.deployment_policy.restriction)
77+
error_message = "Valid values for `restriction` are `NONE`, `PROTECTED_BRANCH`, or `CUSTOM`."
78+
}
79+
}
80+
3481
variable "variables" {
3582
description = "(Optional) A map of GitHub Actions variables to set for the environment. Defaults to `{}`."
3683
type = map(string)

modules/repository/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ This module creates following resources.
6464
| <a name="input_delete_branch_on_merge"></a> [delete\_branch\_on\_merge](#input\_delete\_branch\_on\_merge) | (Optional) Automatically delete head branch after a pull request is merged. Defaults to `true`. | `bool` | `true` | no |
6565
| <a name="input_deploy_keys"></a> [deploy\_keys](#input\_deploy\_keys) | (Optional) A list of deploy keys to grant access to the repository. A deploy key is a SSH key. Each item of `deploy_keys` block as defined below.<br/> (Optional) `name` - A name of deploy key.<br/> (Required) `key` - A SSH key. Begins with 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519', 'sk-ecdsa-sha2-nistp256@openssh.com', or 'sk-ssh-ed25519@openssh.com'.<br/> (Optional) `writable` - Whether to allow write access to the repository. The key can be used to push to the repository if enabled. Defaults to `false`. | <pre>list(object({<br/> name = optional(string)<br/> key = string<br/> writable = optional(bool, false)<br/> }))</pre> | `[]` | no |
6666
| <a name="input_description"></a> [description](#input\_description) | (Optional) A description of the repository. | `string` | `"Managed by Terraform."` | no |
67-
| <a name="input_environments"></a> [environments](#input\_environments) | (Optional) A list of environments for the repository. Each item of `environments` block as defined below.<br/> (Required) `name` - The name of the environment.<br/> (Optional) `wait_timer` - The amount of time in minutes to wait before allowing deployments to proceed. The default value is `0`.<br/> (Optional) `allow_admin_to_bypass` - Whether to allow admins to bypass the wait timer and deployment review. The default value is `true`.<br/> (Optional) `allows_self_approval` - Whether to allow users to approve their own deployment. The default value is `false`.<br/> (Optional) `variables` - A map of GitHub Actions variables to set for the environment. Defaults to `{}`.<br/> (Optional) `secrets` - A map of GitHub Actions secrets to set for the environment. Defaults to `{}`. | <pre>list(object({<br/> name = string<br/> wait_timer = optional(number, 0)<br/> allow_admin_to_bypass = optional(bool, true)<br/> allows_self_approval = optional(bool, false)<br/><br/> variables = optional(map(string), {})<br/> secrets = optional(map(string), {})<br/> }))</pre> | `[]` | no |
67+
| <a name="input_environments"></a> [environments](#input\_environments) | (Optional) A list of environments for the repository. Each item of `environments` block as defined below.<br/> (Required) `name` - The name of the environment.<br/> (Optional) `wait_timer` - The amount of time in minutes to wait before allowing deployments to proceed. The default value is `0`.<br/> (Optional) `allow_admin_to_bypass` - Whether to allow admins to bypass the wait timer and deployment review. The default value is `true`.<br/> (Optional) `allows_self_approval` - Whether to allow users to approve their own deployment. The default value is `false`.<br/> (Optional) `reviewers` - A list of reviewers who may review jobs that reference the environment. Each item of `reviewers` block as defined below.<br/> (Required) `type` - The type of the reviewer. Valid values are `USER` or `TEAM`.<br/> (Required) `name` - The name of the reviewer. For a user reviewer, the value should be the user's username. For a team reviewer, the value should be the team's slug.<br/> (Optional) `deployment_policy` - A configuration for deployment policy of the environment. `deployment_policy` block as defined below.<br/> (Optional) `restriction` - The type of deployment restriction. Valid values are `NONE`, `PROTECTED_BRANCH`, or `CUSTOM`. Defaults to `NONE`.<br/> (Optional) `branches` - A set of branch name patterns to restrict deployments to when the restriction type is `CUSTOM`.<br/> (Optional) `tags` - A set of tag name patterns to restrict deployments to when the restriction type is `CUSTOM`.<br/> (Optional) `variables` - A map of GitHub Actions variables to set for the environment. Defaults to `{}`.<br/> (Optional) `secrets` - A map of GitHub Actions secrets to set for the environment. Defaults to `{}`. | <pre>list(object({<br/> name = string<br/> wait_timer = optional(number, 0)<br/> allow_admin_to_bypass = optional(bool, true)<br/> allows_self_approval = optional(bool, false)<br/><br/> reviewers = optional(list(object({<br/> type = string<br/> name = string<br/> })), [])<br/> deployment_policy = optional(object({<br/> restriction = optional(string, "NONE")<br/> branches = optional(set(string), [])<br/> tags = optional(set(string), [])<br/> }), {})<br/><br/> variables = optional(map(string), {})<br/> secrets = optional(map(string), {})<br/> }))</pre> | `[]` | no |
6868
| <a name="input_features"></a> [features](#input\_features) | (Optional) A list of enabled features on the repository. Available features: `DISCUSSIONS`, `ISSUES`, `PROJECTS`, `WIKI`. Defaults to `["ISSUES"]` | `set(string)` | <pre>[<br/> "ISSUES"<br/>]</pre> | no |
6969
| <a name="input_files"></a> [files](#input\_files) | (Optional) A list of files to create and manage within the repository. Each item of `files` block as defined below.<br/> (Required) `file` - A `file` block as defined below.<br/> (Required) `path` - The path of the file to manage.<br/> (Required) `content` - The file content.<br/> (Optional) `commit` - A `commit` block as defined below.<br/> (Optional) `author` - Committer author name to use. NOTE: GitHub app users may omit author and email information so GitHub can verify commits as the GitHub App. This maybe useful when a branch protection rule requires signed commits.<br/> (Optional) `email` - Committer email address to use. NOTE: GitHub app users may omit author and email information so GitHub can verify commits as the GitHub App. This may be useful when a branch protection rule requires signed commits.<br/> (Optional) `message` - The commit message when creating, updating or deleting the managed file. Defaults to `chore: managed by Terraform.`.<br/> (Optional) `overwrite_on_create` - Enable overwriting existing files. If set to true it will overwrite an existing file with the same name. If set to false it will fail if there is an existing file with the same name. Defaults to `true`. | <pre>list(object({<br/> file = object({<br/> path = string<br/> content = string<br/> })<br/> commit = optional(object({<br/> author = optional(string)<br/> email = optional(string)<br/> message = optional(string, "chore: managed by Terraform.")<br/> }), {})<br/> overwrite_on_create = optional(bool, true)<br/> }))</pre> | `[]` | no |
7070
| <a name="input_homepage"></a> [homepage](#input\_homepage) | (Optional) A URL of website describing the repository. | `string` | `""` | no |

modules/repository/actions.tf

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@ module "environment" {
1818
allow_admin_to_bypass = each.value.allow_admin_to_bypass
1919
allows_self_approval = each.value.allows_self_approval
2020

21+
reviewers = [
22+
for reviewer in each.value.reviewers :
23+
{
24+
type = reviewer.type
25+
name = reviewer.name
26+
}
27+
]
28+
deployment_policy = {
29+
restriction = each.value.deployment_policy.restriction
30+
branches = each.value.deployment_policy.branches
31+
tags = each.value.deployment_policy.tags
32+
}
33+
2134

2235
## Variables & Secrets
2336
variables = each.value.variables

modules/repository/variables.tf

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,13 @@ variable "environments" {
271271
(Optional) `wait_timer` - The amount of time in minutes to wait before allowing deployments to proceed. The default value is `0`.
272272
(Optional) `allow_admin_to_bypass` - Whether to allow admins to bypass the wait timer and deployment review. The default value is `true`.
273273
(Optional) `allows_self_approval` - Whether to allow users to approve their own deployment. The default value is `false`.
274+
(Optional) `reviewers` - A list of reviewers who may review jobs that reference the environment. Each item of `reviewers` block as defined below.
275+
(Required) `type` - The type of the reviewer. Valid values are `USER` or `TEAM`.
276+
(Required) `name` - The name of the reviewer. For a user reviewer, the value should be the user's username. For a team reviewer, the value should be the team's slug.
277+
(Optional) `deployment_policy` - A configuration for deployment policy of the environment. `deployment_policy` block as defined below.
278+
(Optional) `restriction` - The type of deployment restriction. Valid values are `NONE`, `PROTECTED_BRANCH`, or `CUSTOM`. Defaults to `NONE`.
279+
(Optional) `branches` - A set of branch name patterns to restrict deployments to when the restriction type is `CUSTOM`.
280+
(Optional) `tags` - A set of tag name patterns to restrict deployments to when the restriction type is `CUSTOM`.
274281
(Optional) `variables` - A map of GitHub Actions variables to set for the environment. Defaults to `{}`.
275282
(Optional) `secrets` - A map of GitHub Actions secrets to set for the environment. Defaults to `{}`.
276283
EOF
@@ -280,6 +287,16 @@ variable "environments" {
280287
allow_admin_to_bypass = optional(bool, true)
281288
allows_self_approval = optional(bool, false)
282289

290+
reviewers = optional(list(object({
291+
type = string
292+
name = string
293+
})), [])
294+
deployment_policy = optional(object({
295+
restriction = optional(string, "NONE")
296+
branches = optional(set(string), [])
297+
tags = optional(set(string), [])
298+
}), {})
299+
283300
variables = optional(map(string), {})
284301
secrets = optional(map(string), {})
285302
}))

0 commit comments

Comments
 (0)