From 686f6c7d2497869b2cd883b8ca537da043179a39 Mon Sep 17 00:00:00 2001 From: vedantthapa Date: Mon, 10 Mar 2025 16:00:54 -0300 Subject: [PATCH 1/7] feat: add module for internal repo --- modules/internal_repository/README.md | 59 ++++ modules/internal_repository/outputs.tf | 4 + modules/internal_repository/repository.tf | 48 ++++ .../internal_repository/repository.tftest.hcl | 65 +++++ modules/internal_repository/variables.tf | 269 ++++++++++++++++++ modules/internal_repository/versions.tf | 9 + 6 files changed, 454 insertions(+) create mode 100644 modules/internal_repository/README.md create mode 100644 modules/internal_repository/outputs.tf create mode 100644 modules/internal_repository/repository.tf create mode 100644 modules/internal_repository/repository.tftest.hcl create mode 100644 modules/internal_repository/variables.tf create mode 100644 modules/internal_repository/versions.tf diff --git a/modules/internal_repository/README.md b/modules/internal_repository/README.md new file mode 100644 index 0000000..5fc5ef1 --- /dev/null +++ b/modules/internal_repository/README.md @@ -0,0 +1,59 @@ +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.6 | +| [github](#requirement\_github) | ~> 6.0 | + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [repository\_base](#module\_repository\_base) | ../repository_base | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [action\_secrets](#input\_action\_secrets) | An (Optional) map of GitHub Actions secrets to create for this repository. The key is the name of the secret and the value is the encrypted value. | `map(string)` | `{}` | no | +| [advance\_security](#input\_advance\_security) | Enables advance security for the repository. If repository is public `advance_security` is enabled by default and cannot be changed. | `bool` | `true` | no | +| [allow\_auto\_merge](#input\_allow\_auto\_merge) | Allow auto-merging pull requests on the repository | `bool` | `true` | no | +| [allow\_merge\_commit](#input\_allow\_merge\_commit) | (Optional) Set to `false` to disable merge commits on the repository. | `bool` | `true` | no | +| [allow\_rebase\_merge](#input\_allow\_rebase\_merge) | (Optional) Set to `false` to disable rebase merges on the repository. | `bool` | `true` | no | +| [allow\_squash\_merge](#input\_allow\_squash\_merge) | (Optional) Set to `false` to disable squash merges on the repository. | `bool` | `true` | no | +| [codespace\_secrets](#input\_codespace\_secrets) | An (Optional) map of GitHub Codespace secrets to create for this repository. The key is the name of the secret and the value is the encrypted value. | `map(string)` | `{}` | no | +| [default\_branch](#input\_default\_branch) | The branch to set as the default branch for this repository. Defaults to "main" | `string` | `"main"` | no | +| [delete\_head\_on\_merge](#input\_delete\_head\_on\_merge) | Sets the delete head on merge option for the repository. If true it will delete pull request branches automatically on merge. Defaults to true | `bool` | `true` | no | +| [dependabot\_secrets](#input\_dependabot\_secrets) | An (Optional) map of Dependabot secrets to create for this repository. The key is the name of the secret and the value is the encrypted value. | `map(string)` | `{}` | no | +| [dependabot\_security\_updates](#input\_dependabot\_security\_updates) | Enables dependabot security updates. Only works when `has_vulnerability_alerts` is set because that is required to enable dependabot for the repository. | `bool` | `true` | no | +| [description](#input\_description) | The description to give to the repository. Defaults to `""` | `string` | `""` | no | +| [environments](#input\_environments) | Environments to create for the repository. |
map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
}))
| `{}` | no | +| [homepage](#input\_homepage) | The homepage for the repository | `string` | `""` | no | +| [license\_template](#input\_license\_template) | The (Optional) license template to apply to the repository | `string` | `null` | no | +| [merge\_commit\_message](#input\_merge\_commit\_message) | (Optional) Can be `PR_BODY`, `PR_TITLE`, or `BLANK` for a default merge commit message. Applicable only if allow\_merge\_commit is `true`. | `string` | `"PR_TITLE"` | no | +| [merge\_commit\_title](#input\_merge\_commit\_title) | (Optional) Can be `PR_TITLE` or `MERGE_MESSAGE` for a default merge commit title. Applicable only if allow\_merge\_commit is `true`. | `string` | `"MERGE_MESSAGE"` | no | +| [name](#input\_name) | The name of the repository to create/import. | `string` | n/a | yes | +| [pages](#input\_pages) | The (Optional) configuration for GitHub Pages for the repository |
object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
})
| `null` | no | +| [protected\_branches](#input\_protected\_branches) | A list of ref names or patterns that should be protected. Defaults `["main"]` | `list(string)` |
[
"main"
]
| no | +| [repository\_team\_permissions](#input\_repository\_team\_permissions) | A map where the keys are github team slugs and the value is the permissions the team should have in the repository | `map(string)` | n/a | yes | +| [repository\_user\_permissions](#input\_repository\_user\_permissions) | A map where the keys are github usernames and the value is the permissions the user should have in the repository | `map(string)` | n/a | yes | +| [requires\_web\_commit\_signing](#input\_requires\_web\_commit\_signing) | If set commit signatures are required for commits to the organization. Defaults to `false`. | `bool` | `false` | no | +| [rulesets](#input\_rulesets) | n/a |
map(object({
bypass_actors = optional(object({
repository_roles = optional(list(object({
role = string
always_bypass = optional(bool)
})))
teams = optional(list(object({
team = string
always_bypass = optional(bool)
})))
integrations = optional(list(object({
installation_id = number
always_bypass = optional(bool)
})))
organization_admins = optional(list(object({
user = string
always_bypass = optional(bool)
})))
}))
conditions = optional(object({
ref_name = object({
include = list(string)
exclude = list(string)
})
}))
rules = object({
branch_name_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
tag_name_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
commit_author_email_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
commit_message_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
committer_email_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
creation = optional(bool)
deletion = optional(bool)
update = optional(bool)
non_fast_forward = optional(bool)
required_linear_history = optional(bool)
required_signatures = optional(bool)
update_allows_fetch_and_merge = optional(bool)
pull_request = optional(object({
dismiss_stale_reviews_on_push = optional(bool)
require_code_owner_review = optional(bool)
require_last_push_approval = optional(bool)
required_approving_review_count = optional(number)
required_review_thread_resolution = optional(bool)
}))
required_status_checks = optional(object({
required_check = list(object({
context = string
integration_id = optional(number)
}))
strict_required_status_check_policy = optional(bool)
}))
required_deployment_environments = optional(list(string))
})
target = string
enforcement = string
}))
| `{}` | no | +| [squash\_merge\_commit\_message](#input\_squash\_merge\_commit\_message) | (Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. Applicable only if allow\_squash\_merge is `true`. | `string` | `"PR_BODY"` | no | +| [squash\_merge\_commit\_title](#input\_squash\_merge\_commit\_title) | (Optional) Can be `PR_TITLE` or `COMMIT_OR_PR_TITLE` for a default squash merge commit title. Applicable only if allow\_squash\_merge is `true`. | `string` | `"PR_TITLE"` | no | +| [template\_repository](#input\_template\_repository) | A (Optional) list of template repositories to use for the repository |
object({
owner = string
repository = string
include_all_branches = bool
})
| `null` | no | +| [topics](#input\_topics) | The topics to apply to the repository | `list(string)` | `[]` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [id](#output\_id) | The ID of the repository | \ No newline at end of file diff --git a/modules/internal_repository/outputs.tf b/modules/internal_repository/outputs.tf new file mode 100644 index 0000000..b34f827 --- /dev/null +++ b/modules/internal_repository/outputs.tf @@ -0,0 +1,4 @@ +output "id" { + value = module.repository_base.id + description = "The ID of the repository" +} diff --git a/modules/internal_repository/repository.tf b/modules/internal_repository/repository.tf new file mode 100644 index 0000000..c90795c --- /dev/null +++ b/modules/internal_repository/repository.tf @@ -0,0 +1,48 @@ +module "repository_base" { + source = "../repository_base" + + name = var.name + description = var.description + homepage = var.homepage + topics = var.topics + visibility = "internal" + has_downloads = false + has_issues = true + has_projects = true + has_wiki = true + has_discussions = true + + repository_team_permissions = var.repository_team_permissions + repository_user_permissions = var.repository_user_permissions + + default_branch = var.default_branch + protected_branches = var.protected_branches + delete_head_on_merge = var.delete_head_on_merge + allow_auto_merge = var.allow_auto_merge + allow_merge_commit = var.allow_merge_commit + allow_rebase_merge = var.allow_rebase_merge + allow_squash_merge = var.allow_squash_merge + squash_merge_commit_message = var.squash_merge_commit_message + squash_merge_commit_title = var.squash_merge_commit_title + merge_commit_message = var.merge_commit_message + merge_commit_title = var.merge_commit_title + requires_web_commit_signing = var.requires_web_commit_signing + pages = var.pages + + secret_scanning = true + secret_scanning_on_push = true + has_vulnerability_alerts = true + advance_security = var.advance_security + dependabot_security_updates = var.dependabot_security_updates + + codespace_secrets = var.codespace_secrets + dependabot_secrets = var.dependabot_secrets + action_secrets = var.action_secrets + + environments = var.environments + + template_repository = var.template_repository + license_template = var.license_template + + rulesets = var.rulesets +} diff --git a/modules/internal_repository/repository.tftest.hcl b/modules/internal_repository/repository.tftest.hcl new file mode 100644 index 0000000..5605865 --- /dev/null +++ b/modules/internal_repository/repository.tftest.hcl @@ -0,0 +1,65 @@ +mock_provider "github" {} + +variables { + name = "github-foundations-modules" + description = "A collection of terraform modules used in the Github Foundations framework." + visibility = "internal" + has_downloads = true + has_issues = true + has_projects = true + has_wiki = true + has_discussions = true + has_vulnerability_alerts = true + topics = ["terraform", "github", "foundations"] + homepage = "myhomepage" + delete_head_on_merge = false + allow_auto_merge = true + allow_squash_merge = false + squash_merge_commit_message = "COMMIT_MESSAGES" + squash_merge_commit_title = "COMMIT_OR_PR_TITLE" + allow_merge_commit = false + merge_commit_message = "PR_BODY" + merge_commit_title = "PR_TITLE" + allow_rebase_merge = true + requires_web_commit_signing = false + license_template = "mit" + dependabot_security_updates = true + advance_security = true + secret_scanning = true + secret_scanning_on_push = true + + default_branch = "main" + protected_branches = ["main", "develop"] + + template_repository = { + owner = "owner" + repository = "template_repository" + include_all_branches = true + } + + pages = { + source = { + branch = "main" + path = "path" + } + cname = "cname" + } + + repository_team_permissions = { + "repo_team1" = "push" + "repo_team2" = "admin" + } + repository_user_permissions = { + "user1" = "push" + "user2" = "admin" + } +} + +run "create_test" { + command = apply + + assert { + condition = module.repository_base.id != null + error_message = "The repository was not created" + } +} diff --git a/modules/internal_repository/variables.tf b/modules/internal_repository/variables.tf new file mode 100644 index 0000000..7d5cf79 --- /dev/null +++ b/modules/internal_repository/variables.tf @@ -0,0 +1,269 @@ +variable "name" { + type = string + description = "The name of the repository to create/import." +} + +variable "description" { + type = string + description = "The description to give to the repository. Defaults to `\"\"`" + default = "" +} + +variable "default_branch" { + type = string + description = "The branch to set as the default branch for this repository. Defaults to \"main\"" + default = "main" +} + +variable "repository_team_permissions" { + type = map(string) + description = "A map where the keys are github team slugs and the value is the permissions the team should have in the repository" +} + +variable "repository_user_permissions" { + type = map(string) + description = "A map where the keys are github usernames and the value is the permissions the user should have in the repository" +} + +variable "protected_branches" { + type = list(string) + description = "A list of ref names or patterns that should be protected. Defaults `[\"main\"]`" + default = ["main"] +} + +variable "topics" { + description = "The topics to apply to the repository" + type = list(string) + default = [] +} + +variable "homepage" { + description = "The homepage for the repository" + type = string + default = "" +} + +variable "delete_head_on_merge" { + description = "Sets the delete head on merge option for the repository. If true it will delete pull request branches automatically on merge. Defaults to true" + type = bool + default = true +} + +variable "allow_auto_merge" { + description = "Allow auto-merging pull requests on the repository" + type = bool + default = true +} + +variable "requires_web_commit_signing" { + description = "If set commit signatures are required for commits to the organization. Defaults to `false`." + type = bool + default = false +} + +variable "dependabot_security_updates" { + description = "Enables dependabot security updates. Only works when `has_vulnerability_alerts` is set because that is required to enable dependabot for the repository." + type = bool + default = true +} + +variable "advance_security" { + description = "Enables advance security for the repository. If repository is public `advance_security` is enabled by default and cannot be changed." + type = bool + default = true +} + +variable "action_secrets" { + description = "An (Optional) map of GitHub Actions secrets to create for this repository. The key is the name of the secret and the value is the encrypted value." + type = map(string) + default = {} +} + +variable "codespace_secrets" { + description = "An (Optional) map of GitHub Codespace secrets to create for this repository. The key is the name of the secret and the value is the encrypted value." + type = map(string) + default = {} +} + +variable "dependabot_secrets" { + description = "An (Optional) map of Dependabot secrets to create for this repository. The key is the name of the secret and the value is the encrypted value." + type = map(string) + default = {} +} + +variable "environments" { + description = "Environments to create for the repository." + type = map(object({ + wait_timer = optional(number) + can_admins_bypass = optional(bool) + prevent_self_review = optional(bool) + action_secrets = optional(map(string)) + reviewers = optional(object({ + teams = optional(list(string)) + users = optional(list(string)) + })) + deployment_branch_policy = optional(object({ + protected_branches = bool + custom_branch_policies = bool + branch_patterns = list(string) + })) + })) + default = {} +} + +variable "template_repository" { + description = "A (Optional) list of template repositories to use for the repository" + type = object({ + owner = string + repository = string + include_all_branches = bool + }) + default = null +} + +variable "license_template" { + description = "The (Optional) license template to apply to the repository" + type = string + default = null +} + +variable "pages" { + description = "The (Optional) configuration for GitHub Pages for the repository" + type = object({ + source = optional(object({ + branch = string + path = optional(string) + })) + build_type = optional(string) + cname = optional(string) + }) + default = null +} + +variable "allow_squash_merge" { + description = "(Optional) Set to `false` to disable squash merges on the repository." + type = bool + default = true +} + +variable "allow_rebase_merge" { + description = "(Optional) Set to `false` to disable rebase merges on the repository." + type = bool + default = true +} + +variable "allow_merge_commit" { + description = " (Optional) Set to `false` to disable merge commits on the repository." + type = bool + default = true +} + +variable "squash_merge_commit_title" { + description = " (Optional) Can be `PR_TITLE` or `COMMIT_OR_PR_TITLE` for a default squash merge commit title. Applicable only if allow_squash_merge is `true`." + type = string + default = "PR_TITLE" +} + +variable "squash_merge_commit_message" { + description = "(Optional) Can be `PR_BODY`, `COMMIT_MESSAGES`, or `BLANK` for a default squash merge commit message. Applicable only if allow_squash_merge is `true`." + type = string + default = "PR_BODY" +} + +variable "merge_commit_title" { + description = "(Optional) Can be `PR_TITLE` or `MERGE_MESSAGE` for a default merge commit title. Applicable only if allow_merge_commit is `true`." + type = string + default = "MERGE_MESSAGE" +} + +variable "merge_commit_message" { + description = "(Optional) Can be `PR_BODY`, `PR_TITLE`, or `BLANK` for a default merge commit message. Applicable only if allow_merge_commit is `true`." + type = string + default = "PR_TITLE" +} + +variable "rulesets" { + type = map(object({ + bypass_actors = optional(object({ + repository_roles = optional(list(object({ + role = string + always_bypass = optional(bool) + }))) + teams = optional(list(object({ + team = string + always_bypass = optional(bool) + }))) + integrations = optional(list(object({ + installation_id = number + always_bypass = optional(bool) + }))) + organization_admins = optional(list(object({ + user = string + always_bypass = optional(bool) + }))) + })) + conditions = optional(object({ + ref_name = object({ + include = list(string) + exclude = list(string) + }) + })) + rules = object({ + branch_name_pattern = optional(object({ + operator = string + pattern = string + name = optional(string) + negate = optional(bool) + })) + tag_name_pattern = optional(object({ + operator = string + pattern = string + name = optional(string) + negate = optional(bool) + })) + commit_author_email_pattern = optional(object({ + operator = string + pattern = string + name = optional(string) + negate = optional(bool) + })) + commit_message_pattern = optional(object({ + operator = string + pattern = string + name = optional(string) + negate = optional(bool) + })) + committer_email_pattern = optional(object({ + operator = string + pattern = string + name = optional(string) + negate = optional(bool) + })) + creation = optional(bool) + deletion = optional(bool) + update = optional(bool) + non_fast_forward = optional(bool) + required_linear_history = optional(bool) + required_signatures = optional(bool) + update_allows_fetch_and_merge = optional(bool) + pull_request = optional(object({ + dismiss_stale_reviews_on_push = optional(bool) + require_code_owner_review = optional(bool) + require_last_push_approval = optional(bool) + required_approving_review_count = optional(number) + required_review_thread_resolution = optional(bool) + })) + required_status_checks = optional(object({ + required_check = list(object({ + context = string + integration_id = optional(number) + })) + strict_required_status_check_policy = optional(bool) + })) + required_deployment_environments = optional(list(string)) + }) + target = string + enforcement = string + })) + default = {} +} diff --git a/modules/internal_repository/versions.tf b/modules/internal_repository/versions.tf new file mode 100644 index 0000000..1957e13 --- /dev/null +++ b/modules/internal_repository/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.6" + required_providers { + github = { + source = "integrations/github" + version = "~> 6.0" + } + } +} From 3777dd6c02869e4bd22e6b62bfbac1d3128fd685 Mon Sep 17 00:00:00 2001 From: vedantthapa Date: Mon, 10 Mar 2025 16:39:54 -0300 Subject: [PATCH 2/7] feat: add internal repositories to repository_set --- .../repository_set/organization-secrets.tf | 19 ++-- .../organization_secrets.tftest.hcl | 2 + modules/repository_set/repositories.tf | 40 +++++++++ .../repository_set/repositories.tftest.hcl | 89 +++++++++++++++++++ modules/repository_set/variables.tf | 61 +++++++++++++ 5 files changed, 205 insertions(+), 6 deletions(-) diff --git a/modules/repository_set/organization-secrets.tf b/modules/repository_set/organization-secrets.tf index ab5f84d..8c6f42f 100644 --- a/modules/repository_set/organization-secrets.tf +++ b/modules/repository_set/organization-secrets.tf @@ -1,40 +1,47 @@ locals { coalesced_public_repositories = coalesce(var.public_repositories, {}) coalesced_private_repositories = coalesce(var.private_repositories, {}) + coalesced_internal_repositories = coalesce(var.internal_repositories, {}) organization_action_secrets = distinct(flatten(concat( [for _, repo in local.coalesced_public_repositories : repo.organization_action_secrets if repo.organization_action_secrets != null], - [for _, repo in local.coalesced_private_repositories : repo.organization_action_secrets if repo.organization_action_secrets != null] + [for _, repo in local.coalesced_private_repositories : repo.organization_action_secrets if repo.organization_action_secrets != null], + [for _, repo in local.coalesced_internal_repositories : repo.organization_action_secrets if repo.organization_action_secrets != null] ))) organization_action_secrets_repository_id_list = { for secret in local.organization_action_secrets : secret => toset(distinct(concat( [for repo_name, repo in local.coalesced_public_repositories : module.public_repositories[repo_name].id if contains(coalesce(repo.organization_action_secrets, []), secret)], - [for repo_name, repo in local.coalesced_private_repositories : module.private_repositories[repo_name].id if contains(coalesce(repo.organization_action_secrets, []), secret)] + [for repo_name, repo in local.coalesced_private_repositories : module.private_repositories[repo_name].id if contains(coalesce(repo.organization_action_secrets, []), secret)], + [for repo_name, repo in local.coalesced_internal_repositories : module.internal_repositories[repo_name].id if contains(coalesce(repo.organization_action_secrets, []), secret)] ))) } codespace_secrets = distinct(flatten(concat( [for _, repo in local.coalesced_public_repositories : repo.organization_codespace_secrets if repo.organization_codespace_secrets != null], - [for _, repo in local.coalesced_private_repositories : repo.organization_codespace_secrets if repo.organization_codespace_secrets != null] + [for _, repo in local.coalesced_private_repositories : repo.organization_codespace_secrets if repo.organization_codespace_secrets != null], + [for _, repo in local.coalesced_internal_repositories : repo.organization_codespace_secrets if repo.organization_codespace_secrets != null] ))) codespace_secrets_repository_id_list = { for secret in local.codespace_secrets : secret => toset(distinct(concat( [for repo_name, repo in local.coalesced_public_repositories : module.public_repositories[repo_name].id if contains(coalesce(repo.organization_codespace_secrets, []), secret)], - [for repo_name, repo in local.coalesced_private_repositories : module.private_repositories[repo_name].id if contains(coalesce(repo.organization_codespace_secrets, []), secret)] + [for repo_name, repo in local.coalesced_private_repositories : module.private_repositories[repo_name].id if contains(coalesce(repo.organization_codespace_secrets, []), secret)], + [for repo_name, repo in local.coalesced_internal_repositories : module.internal_repositories[repo_name].id if contains(coalesce(repo.organization_codespace_secrets, []), secret)] ))) } dependabot_secrets = distinct(flatten(concat( [for _, repo in local.coalesced_public_repositories : repo.organization_dependabot_secrets if repo.organization_dependabot_secrets != null], - [for _, repo in local.coalesced_private_repositories : repo.organization_dependabot_secrets if repo.organization_dependabot_secrets != null] + [for _, repo in local.coalesced_private_repositories : repo.organization_dependabot_secrets if repo.organization_dependabot_secrets != null], + [for _, repo in local.coalesced_internal_repositories : repo.organization_dependabot_secrets if repo.organization_dependabot_secrets != null] ))) dependabot_secrets_id_list = { for secret in local.dependabot_secrets : secret => toset(distinct(concat( [for repo_name, repo in local.coalesced_public_repositories : module.public_repositories[repo_name].id if contains(coalesce(repo.organization_dependabot_secrets, []), secret)], - [for repo_name, repo in local.coalesced_private_repositories : module.private_repositories[repo_name].id if contains(coalesce(repo.organization_dependabot_secrets, []), secret)] + [for repo_name, repo in local.coalesced_private_repositories : module.private_repositories[repo_name].id if contains(coalesce(repo.organization_dependabot_secrets, []), secret)], + [for repo_name, repo in local.coalesced_internal_repositories : module.internal_repositories[repo_name].id if contains(coalesce(repo.organization_dependabot_secrets, []), secret)] ))) } } diff --git a/modules/repository_set/organization_secrets.tftest.hcl b/modules/repository_set/organization_secrets.tftest.hcl index f9d8495..bc707d4 100644 --- a/modules/repository_set/organization_secrets.tftest.hcl +++ b/modules/repository_set/organization_secrets.tftest.hcl @@ -25,6 +25,8 @@ variables { } private_repositories = {} + + internal_repositories = {} } run "organization_actions_secrets_test" { diff --git a/modules/repository_set/repositories.tf b/modules/repository_set/repositories.tf index d507dad..fe148e8 100644 --- a/modules/repository_set/repositories.tf +++ b/modules/repository_set/repositories.tf @@ -9,6 +9,11 @@ locals { for ruleset_name, ruleset_config in var.rulesets : ruleset_name => ruleset_config if contains(ruleset_config.repositories, repo_name) } } + rulesets_by_internal_repository = { + for repo_name, repo_config in var.internal_repositories : repo_name => { + for ruleset_name, ruleset_config in var.rulesets : ruleset_name => ruleset_config if contains(ruleset_config.repositories, repo_name) + } + } } module "public_repositories" { @@ -81,3 +86,38 @@ module "private_repositories" { rulesets = lookup(local.rulesets_by_private_repository, each.key, {}) pages = each.value.pages } + +module "internal_repositories" { + source = "../internal_repository" + + for_each = var.internal_repositories + + name = each.key + repository_team_permissions = merge(var.default_repository_team_permissions, coalesce(each.value.repository_team_permissions_override, {})) + repository_user_permissions = coalesce(each.value.user_permissions, {}) + description = each.value.description + default_branch = each.value.default_branch + protected_branches = each.value.protected_branches + advance_security = each.value.advance_security + topics = each.value.topics + homepage = each.value.homepage + delete_head_on_merge = each.value.delete_head_on_merge + allow_auto_merge = each.value.allow_auto_merge + allow_merge_commit = each.value.allow_merge_commit + allow_rebase_merge = each.value.allow_rebase_merge + allow_squash_merge = each.value.allow_squash_merge + merge_commit_title = each.value.merge_commit_title + merge_commit_message = each.value.merge_commit_message + squash_merge_commit_title = each.value.squash_merge_commit_title + squash_merge_commit_message = each.value.squash_merge_commit_message + dependabot_security_updates = each.value.dependabot_security_updates + action_secrets = each.value.action_secrets + codespace_secrets = each.value.codespace_secrets + dependabot_secrets = each.value.dependabot_secrets + environments = each.value.environments + template_repository = each.value.template_repository + license_template = each.value.license_template + requires_web_commit_signing = each.value.requires_web_commit_signing + rulesets = lookup(local.rulesets_by_internal_repository, each.key, {}) + pages = each.value.pages +} diff --git a/modules/repository_set/repositories.tftest.hcl b/modules/repository_set/repositories.tftest.hcl index d0ff2de..de777a2 100644 --- a/modules/repository_set/repositories.tftest.hcl +++ b/modules/repository_set/repositories.tftest.hcl @@ -169,6 +169,88 @@ variables { GhFoundationsAdmins = "admin" GhFoundationsDevelopers = "push" } + + internal_repositories = { + + "internal-github-foundations-modules" = { + description = "A collection of terraform modules used in the Github Foundations framework." + default_branch = "main" + protected_branches = ["main"] + advance_security = false + has_vulnerability_alerts = true + topics = ["terraform", "github", "foundations"] + homepage = "myhomepage" + delete_head_on_merge = false + dependabot_security_updates = true + requires_web_commit_signing = false + allow_auto_merge = true + allow_squash_merge = false + allow_rebase_merge = true + allow_merge_commit = false + squash_merge_commit_title = "COMMIT_OR_PR_TITLE" + squash_merge_commit_message = "COMMIT_MESSAGES" + merge_commit_title = "PR_TITLE" + merge_commit_message = "PR_BODY" + repository_team_permissions_override = { + "repo_team1" = "push" + "repo_team2" = "admin" + } + user_permissions = { + "user1" = "push" + "user2" = "admin" + } + + + action_secrets = { + "action_secret1" = "value1" + } + + codespace_secrets = { + "codespace_secret1" = "value1" + } + + dependabot_secrets = { + "dependabot_secret1" = "value1" + } + + environments = { + "env1" = { + wait_timer = 10 + can_admins_bypass = true + prevent_self_review = false + action_secrets = { + "action_secret1" = "dmFsdWUxCg==" # base64 encoded + } + reviewers = { + teams = [111, 222] + users = [55, 66] + } + deployment_branch_policy = { + protected_branches = true + custom_branch_policies = false + branch_patterns = ["main"] + } + } + } + + template_repository = { + owner = "owner" + repository = "template_repository" + include_all_branches = true + } + + license_template = "mit" + + pages = { + source = { + branch = "main" + path = "path" + } + # build_type = "build_type" + cname = "cname" + } + } + } } run "apply" { @@ -188,3 +270,10 @@ run "private_repository_test" { error_message = "The repository id value is incorrect. Expected not null, got ${module.private_repositories["private-github-foundations-modules"].id}" } } + +run "internal_repository_test" { + assert { + condition = module.internal_repositories["internal-github-foundations-modules"].id != null + error_message = "The repository id value is incorrect. Expected not null, got ${module.internal_repositories["internal-github-foundations-modules"].id}" + } +} diff --git a/modules/repository_set/variables.tf b/modules/repository_set/variables.tf index 9288cb9..09eb587 100644 --- a/modules/repository_set/variables.tf +++ b/modules/repository_set/variables.tf @@ -119,6 +119,66 @@ variable "public_repositories" { description = "A map of public repositories where the key is the repository name and the value is the configuration" } +variable "internal_repositories" { + type = map(object({ + description = string + default_branch = string + protected_branches = list(string) + advance_security = bool + topics = list(string) + homepage = string + delete_head_on_merge = bool + dependabot_security_updates = bool + requires_web_commit_signing = bool + allow_auto_merge = optional(bool) + allow_squash_merge = optional(bool) + allow_rebase_merge = optional(bool) + allow_merge_commit = optional(bool) + squash_merge_commit_title = optional(string) + squash_merge_commit_message = optional(string) + merge_commit_title = optional(string) + merge_commit_message = optional(string) + repository_team_permissions_override = optional(map(string)) + user_permissions = optional(map(string)) + organization_action_secrets = optional(list(string)) + organization_codespace_secrets = optional(list(string)) + organization_dependabot_secrets = optional(list(string)) + action_secrets = optional(map(string)) + codespace_secrets = optional(map(string)) + dependabot_secrets = optional(map(string)) + environments = optional(map(object({ + wait_timer = optional(number) + can_admins_bypass = optional(bool) + prevent_self_review = optional(bool) + action_secrets = optional(map(string)) + reviewers = optional(object({ + teams = optional(list(string)) + users = optional(list(string)) + })) + deployment_branch_policy = optional(object({ + protected_branches = bool + custom_branch_policies = bool + branch_patterns = list(string) + })) + }))) + template_repository = optional(object({ + owner = string + repository = string + include_all_branches = bool + })) + license_template = optional(string) + pages = optional(object({ + source = optional(object({ + branch = string + path = optional(string) + })) + build_type = optional(string) + cname = optional(string) + })) + })) + description = "A map of internal repositories where the key is the repository name and the value is the configuration" +} + variable "has_ghas_license" { type = bool description = "If the organization owning the repositories has a GitHub Advanced Security license or not. Defaults to false." @@ -217,3 +277,4 @@ variable "rulesets" { })) default = {} } + From a88293f39fa82dd47738d26f775890692771dc77 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 10 Mar 2025 19:41:28 +0000 Subject: [PATCH 3/7] terraform-docs: automated action --- modules/repository_set/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/repository_set/README.md b/modules/repository_set/README.md index 13eacbe..6cbc84c 100644 --- a/modules/repository_set/README.md +++ b/modules/repository_set/README.md @@ -15,6 +15,7 @@ | Name | Source | Version | |------|--------|---------| +| [internal\_repositories](#module\_internal\_repositories) | ../internal_repository | n/a | | [private\_repositories](#module\_private\_repositories) | ../private_repository | n/a | | [public\_repositories](#module\_public\_repositories) | ../public_repository | n/a | @@ -32,6 +33,7 @@ |------|-------------|------|---------|:--------:| | [default\_repository\_team\_permissions](#input\_default\_repository\_team\_permissions) | A map where the keys are github team slugs and the value is the permissions the team should have by default for every repository. If an entry exists in `repository_team_permissions_override` for a repository then that will take precedence over this default. Defaults to `{}` giving no team access to the repositories. | `map(string)` | `{}` | no | | [has\_ghas\_license](#input\_has\_ghas\_license) | If the organization owning the repositories has a GitHub Advanced Security license or not. Defaults to false. | `bool` | `false` | no | +| [internal\_repositories](#input\_internal\_repositories) | A map of internal repositories where the key is the repository name and the value is the configuration |
map(object({
description = string
default_branch = string
protected_branches = list(string)
advance_security = bool
topics = list(string)
homepage = string
delete_head_on_merge = bool
dependabot_security_updates = bool
requires_web_commit_signing = bool
allow_auto_merge = optional(bool)
allow_squash_merge = optional(bool)
allow_rebase_merge = optional(bool)
allow_merge_commit = optional(bool)
squash_merge_commit_title = optional(string)
squash_merge_commit_message = optional(string)
merge_commit_title = optional(string)
merge_commit_message = optional(string)
repository_team_permissions_override = optional(map(string))
user_permissions = optional(map(string))
organization_action_secrets = optional(list(string))
organization_codespace_secrets = optional(list(string))
organization_dependabot_secrets = optional(list(string))
action_secrets = optional(map(string))
codespace_secrets = optional(map(string))
dependabot_secrets = optional(map(string))
environments = optional(map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
})))
template_repository = optional(object({
owner = string
repository = string
include_all_branches = bool
}))
license_template = optional(string)
pages = optional(object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
}))
}))
| n/a | yes | | [private\_repositories](#input\_private\_repositories) | A map of private repositories where the key is the repository name and the value is the configuration |
map(object({
description = string
default_branch = string
protected_branches = list(string)
advance_security = bool
has_vulnerability_alerts = bool
topics = list(string)
homepage = string
delete_head_on_merge = bool
requires_web_commit_signing = bool
dependabot_security_updates = bool
allow_auto_merge = optional(bool)
allow_squash_merge = optional(bool)
allow_rebase_merge = optional(bool)
allow_merge_commit = optional(bool)
squash_merge_commit_title = optional(string)
squash_merge_commit_message = optional(string)
merge_commit_title = optional(string)
merge_commit_message = optional(string)
repository_team_permissions_override = optional(map(string))
user_permissions = optional(map(string))
organization_action_secrets = optional(list(string))
organization_codespace_secrets = optional(list(string))
organization_dependabot_secrets = optional(list(string))
action_secrets = optional(map(string))
codespace_secrets = optional(map(string))
dependabot_secrets = optional(map(string))
environments = optional(map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
})))
template_repository = optional(object({
owner = string
repository = string
include_all_branches = bool
}))
license_template = optional(string)
pages = optional(object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
}))
}))
| n/a | yes | | [public\_repositories](#input\_public\_repositories) | A map of public repositories where the key is the repository name and the value is the configuration |
map(object({
description = string
default_branch = string
protected_branches = list(string)
advance_security = bool
topics = list(string)
homepage = string
delete_head_on_merge = bool
dependabot_security_updates = bool
requires_web_commit_signing = bool
allow_auto_merge = optional(bool)
allow_squash_merge = optional(bool)
allow_rebase_merge = optional(bool)
allow_merge_commit = optional(bool)
squash_merge_commit_title = optional(string)
squash_merge_commit_message = optional(string)
merge_commit_title = optional(string)
merge_commit_message = optional(string)
repository_team_permissions_override = optional(map(string))
user_permissions = optional(map(string))
organization_action_secrets = optional(list(string))
organization_codespace_secrets = optional(list(string))
organization_dependabot_secrets = optional(list(string))
action_secrets = optional(map(string))
codespace_secrets = optional(map(string))
dependabot_secrets = optional(map(string))
environments = optional(map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
})))
template_repository = optional(object({
owner = string
repository = string
include_all_branches = bool
}))
license_template = optional(string)
pages = optional(object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
}))
}))
| n/a | yes | | [rulesets](#input\_rulesets) | n/a |
map(object({
bypass_actors = optional(object({
repository_roles = optional(list(object({
role = string
always_bypass = optional(bool)
})))
teams = optional(list(object({
team = string
always_bypass = optional(bool)
})))
integrations = optional(list(object({
installation_id = number
always_bypass = optional(bool)
})))
organization_admins = optional(list(object({
user = string
always_bypass = optional(bool)
})))
}))
conditions = optional(object({
ref_name = object({
include = list(string)
exclude = list(string)
})
}))
rules = object({
branch_name_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
tag_name_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
commit_author_email_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
commit_message_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
committer_email_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
creation = optional(bool)
deletion = optional(bool)
update = optional(bool)
non_fast_forward = optional(bool)
required_linear_history = optional(bool)
required_signatures = optional(bool)
update_allows_fetch_and_merge = optional(bool)
pull_request = optional(object({
dismiss_stale_reviews_on_push = optional(bool)
require_code_owner_review = optional(bool)
require_last_push_approval = optional(bool)
required_approving_review_count = optional(number)
required_review_thread_resolution = optional(bool)
}))
required_status_checks = optional(object({
required_check = list(object({
context = string
integration_id = optional(number)
}))
strict_required_status_check_policy = optional(bool)
}))
required_deployment_environments = optional(list(string))
})
target = string
enforcement = string
repositories = list(string)
}))
| `{}` | no | From e781bb059eff173fbe4107361541eec624e6d234 Mon Sep 17 00:00:00 2001 From: vedantthapa Date: Mon, 10 Mar 2025 17:14:39 -0300 Subject: [PATCH 4/7] feat: set a default value of {} for internal_repositories --- modules/repository_set/organization_secrets.tftest.hcl | 1 - modules/repository_set/variables.tf | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/repository_set/organization_secrets.tftest.hcl b/modules/repository_set/organization_secrets.tftest.hcl index bc707d4..3f77184 100644 --- a/modules/repository_set/organization_secrets.tftest.hcl +++ b/modules/repository_set/organization_secrets.tftest.hcl @@ -26,7 +26,6 @@ variables { private_repositories = {} - internal_repositories = {} } run "organization_actions_secrets_test" { diff --git a/modules/repository_set/variables.tf b/modules/repository_set/variables.tf index 09eb587..0c9b883 100644 --- a/modules/repository_set/variables.tf +++ b/modules/repository_set/variables.tf @@ -177,6 +177,7 @@ variable "internal_repositories" { })) })) description = "A map of internal repositories where the key is the repository name and the value is the configuration" + default = {} } variable "has_ghas_license" { From 0bd55e1ec6c08b4d98fcd572bdc6f60823fb7282 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 10 Mar 2025 20:15:45 +0000 Subject: [PATCH 5/7] terraform-docs: automated action --- modules/repository_set/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/repository_set/README.md b/modules/repository_set/README.md index 6cbc84c..5b41b63 100644 --- a/modules/repository_set/README.md +++ b/modules/repository_set/README.md @@ -33,7 +33,7 @@ |------|-------------|------|---------|:--------:| | [default\_repository\_team\_permissions](#input\_default\_repository\_team\_permissions) | A map where the keys are github team slugs and the value is the permissions the team should have by default for every repository. If an entry exists in `repository_team_permissions_override` for a repository then that will take precedence over this default. Defaults to `{}` giving no team access to the repositories. | `map(string)` | `{}` | no | | [has\_ghas\_license](#input\_has\_ghas\_license) | If the organization owning the repositories has a GitHub Advanced Security license or not. Defaults to false. | `bool` | `false` | no | -| [internal\_repositories](#input\_internal\_repositories) | A map of internal repositories where the key is the repository name and the value is the configuration |
map(object({
description = string
default_branch = string
protected_branches = list(string)
advance_security = bool
topics = list(string)
homepage = string
delete_head_on_merge = bool
dependabot_security_updates = bool
requires_web_commit_signing = bool
allow_auto_merge = optional(bool)
allow_squash_merge = optional(bool)
allow_rebase_merge = optional(bool)
allow_merge_commit = optional(bool)
squash_merge_commit_title = optional(string)
squash_merge_commit_message = optional(string)
merge_commit_title = optional(string)
merge_commit_message = optional(string)
repository_team_permissions_override = optional(map(string))
user_permissions = optional(map(string))
organization_action_secrets = optional(list(string))
organization_codespace_secrets = optional(list(string))
organization_dependabot_secrets = optional(list(string))
action_secrets = optional(map(string))
codespace_secrets = optional(map(string))
dependabot_secrets = optional(map(string))
environments = optional(map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
})))
template_repository = optional(object({
owner = string
repository = string
include_all_branches = bool
}))
license_template = optional(string)
pages = optional(object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
}))
}))
| n/a | yes | +| [internal\_repositories](#input\_internal\_repositories) | A map of internal repositories where the key is the repository name and the value is the configuration |
map(object({
description = string
default_branch = string
protected_branches = list(string)
advance_security = bool
topics = list(string)
homepage = string
delete_head_on_merge = bool
dependabot_security_updates = bool
requires_web_commit_signing = bool
allow_auto_merge = optional(bool)
allow_squash_merge = optional(bool)
allow_rebase_merge = optional(bool)
allow_merge_commit = optional(bool)
squash_merge_commit_title = optional(string)
squash_merge_commit_message = optional(string)
merge_commit_title = optional(string)
merge_commit_message = optional(string)
repository_team_permissions_override = optional(map(string))
user_permissions = optional(map(string))
organization_action_secrets = optional(list(string))
organization_codespace_secrets = optional(list(string))
organization_dependabot_secrets = optional(list(string))
action_secrets = optional(map(string))
codespace_secrets = optional(map(string))
dependabot_secrets = optional(map(string))
environments = optional(map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
})))
template_repository = optional(object({
owner = string
repository = string
include_all_branches = bool
}))
license_template = optional(string)
pages = optional(object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
}))
}))
| `{}` | no | | [private\_repositories](#input\_private\_repositories) | A map of private repositories where the key is the repository name and the value is the configuration |
map(object({
description = string
default_branch = string
protected_branches = list(string)
advance_security = bool
has_vulnerability_alerts = bool
topics = list(string)
homepage = string
delete_head_on_merge = bool
requires_web_commit_signing = bool
dependabot_security_updates = bool
allow_auto_merge = optional(bool)
allow_squash_merge = optional(bool)
allow_rebase_merge = optional(bool)
allow_merge_commit = optional(bool)
squash_merge_commit_title = optional(string)
squash_merge_commit_message = optional(string)
merge_commit_title = optional(string)
merge_commit_message = optional(string)
repository_team_permissions_override = optional(map(string))
user_permissions = optional(map(string))
organization_action_secrets = optional(list(string))
organization_codespace_secrets = optional(list(string))
organization_dependabot_secrets = optional(list(string))
action_secrets = optional(map(string))
codespace_secrets = optional(map(string))
dependabot_secrets = optional(map(string))
environments = optional(map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
})))
template_repository = optional(object({
owner = string
repository = string
include_all_branches = bool
}))
license_template = optional(string)
pages = optional(object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
}))
}))
| n/a | yes | | [public\_repositories](#input\_public\_repositories) | A map of public repositories where the key is the repository name and the value is the configuration |
map(object({
description = string
default_branch = string
protected_branches = list(string)
advance_security = bool
topics = list(string)
homepage = string
delete_head_on_merge = bool
dependabot_security_updates = bool
requires_web_commit_signing = bool
allow_auto_merge = optional(bool)
allow_squash_merge = optional(bool)
allow_rebase_merge = optional(bool)
allow_merge_commit = optional(bool)
squash_merge_commit_title = optional(string)
squash_merge_commit_message = optional(string)
merge_commit_title = optional(string)
merge_commit_message = optional(string)
repository_team_permissions_override = optional(map(string))
user_permissions = optional(map(string))
organization_action_secrets = optional(list(string))
organization_codespace_secrets = optional(list(string))
organization_dependabot_secrets = optional(list(string))
action_secrets = optional(map(string))
codespace_secrets = optional(map(string))
dependabot_secrets = optional(map(string))
environments = optional(map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
})))
template_repository = optional(object({
owner = string
repository = string
include_all_branches = bool
}))
license_template = optional(string)
pages = optional(object({
source = optional(object({
branch = string
path = optional(string)
}))
build_type = optional(string)
cname = optional(string)
}))
}))
| n/a | yes | | [rulesets](#input\_rulesets) | n/a |
map(object({
bypass_actors = optional(object({
repository_roles = optional(list(object({
role = string
always_bypass = optional(bool)
})))
teams = optional(list(object({
team = string
always_bypass = optional(bool)
})))
integrations = optional(list(object({
installation_id = number
always_bypass = optional(bool)
})))
organization_admins = optional(list(object({
user = string
always_bypass = optional(bool)
})))
}))
conditions = optional(object({
ref_name = object({
include = list(string)
exclude = list(string)
})
}))
rules = object({
branch_name_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
tag_name_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
commit_author_email_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
commit_message_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
committer_email_pattern = optional(object({
operator = string
pattern = string
name = optional(string)
negate = optional(bool)
}))
creation = optional(bool)
deletion = optional(bool)
update = optional(bool)
non_fast_forward = optional(bool)
required_linear_history = optional(bool)
required_signatures = optional(bool)
update_allows_fetch_and_merge = optional(bool)
pull_request = optional(object({
dismiss_stale_reviews_on_push = optional(bool)
require_code_owner_review = optional(bool)
require_last_push_approval = optional(bool)
required_approving_review_count = optional(number)
required_review_thread_resolution = optional(bool)
}))
required_status_checks = optional(object({
required_check = list(object({
context = string
integration_id = optional(number)
}))
strict_required_status_check_policy = optional(bool)
}))
required_deployment_environments = optional(list(string))
})
target = string
enforcement = string
repositories = list(string)
}))
| `{}` | no | From a18cbca4f8041b122ce9dfda8e8b50818be1f22e Mon Sep 17 00:00:00 2001 From: vedantthapa Date: Tue, 11 Mar 2025 15:18:49 -0300 Subject: [PATCH 6/7] fix: disable secret scanning by default as it requires exisitng ghas license --- modules/internal_repository/repository.tf | 8 ++++++-- modules/internal_repository/variables.tf | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/internal_repository/repository.tf b/modules/internal_repository/repository.tf index c90795c..1ca7122 100644 --- a/modules/internal_repository/repository.tf +++ b/modules/internal_repository/repository.tf @@ -1,3 +1,7 @@ +locals { + enable_secret_scanning = var.has_ghas_license +} + module "repository_base" { source = "../repository_base" @@ -29,8 +33,8 @@ module "repository_base" { requires_web_commit_signing = var.requires_web_commit_signing pages = var.pages - secret_scanning = true - secret_scanning_on_push = true + secret_scanning = local.enable_secret_scanning + secret_scanning_on_push = local.enable_secret_scanning has_vulnerability_alerts = true advance_security = var.advance_security dependabot_security_updates = var.dependabot_security_updates diff --git a/modules/internal_repository/variables.tf b/modules/internal_repository/variables.tf index 7d5cf79..2019a8e 100644 --- a/modules/internal_repository/variables.tf +++ b/modules/internal_repository/variables.tf @@ -73,6 +73,12 @@ variable "advance_security" { default = true } +variable "has_ghas_license" { + description = "If the organization owning the repository has a GitHub Advanced Security license or not. Defaults to false." + type = bool + default = false +} + variable "action_secrets" { description = "An (Optional) map of GitHub Actions secrets to create for this repository. The key is the name of the secret and the value is the encrypted value." type = map(string) From 1e517c98496cdd1c49cf96d6f62bc7fb3a06fa9c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 11 Mar 2025 18:23:45 +0000 Subject: [PATCH 7/7] terraform-docs: automated action --- modules/internal_repository/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/internal_repository/README.md b/modules/internal_repository/README.md index 5fc5ef1..cd2bda2 100644 --- a/modules/internal_repository/README.md +++ b/modules/internal_repository/README.md @@ -36,6 +36,7 @@ No resources. | [dependabot\_security\_updates](#input\_dependabot\_security\_updates) | Enables dependabot security updates. Only works when `has_vulnerability_alerts` is set because that is required to enable dependabot for the repository. | `bool` | `true` | no | | [description](#input\_description) | The description to give to the repository. Defaults to `""` | `string` | `""` | no | | [environments](#input\_environments) | Environments to create for the repository. |
map(object({
wait_timer = optional(number)
can_admins_bypass = optional(bool)
prevent_self_review = optional(bool)
action_secrets = optional(map(string))
reviewers = optional(object({
teams = optional(list(string))
users = optional(list(string))
}))
deployment_branch_policy = optional(object({
protected_branches = bool
custom_branch_policies = bool
branch_patterns = list(string)
}))
}))
| `{}` | no | +| [has\_ghas\_license](#input\_has\_ghas\_license) | If the organization owning the repository has a GitHub Advanced Security license or not. Defaults to false. | `bool` | `false` | no | | [homepage](#input\_homepage) | The homepage for the repository | `string` | `""` | no | | [license\_template](#input\_license\_template) | The (Optional) license template to apply to the repository | `string` | `null` | no | | [merge\_commit\_message](#input\_merge\_commit\_message) | (Optional) Can be `PR_BODY`, `PR_TITLE`, or `BLANK` for a default merge commit message. Applicable only if allow\_merge\_commit is `true`. | `string` | `"PR_TITLE"` | no |