diff --git a/terraform/main.tf b/terraform/main.tf index 21e9c66..498edbc 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -1,9 +1,34 @@ locals { - config = yamldecode(file(var.path)) + config = yamldecode(file(var.path)) + + repositories = [ + for repository in try(local.config.repositories, []) : { + # Metadata + name = repository.name + description = try(repository.description, null) + homepage_url = try(repository.homepage_url, null) + topics = try(repository.topics, null) + # Properties + visibility = try(repository.visibility, local.config.organization.all-repositories.visibility, null) + is_template = try(repository.is_template, null) + # Features + has_issues = try(repository.has_issues, local.config.organization.all-repositories.has_issues, null) + has_discussions = try(repository.has_discussions, local.config.organization.all-repositories.has_discussions, null) + has_projects = try(repository.has_projects, local.config.organization.all-repositories.has_projects, null) + has_wiki = try(repository.has_wiki, local.config.organization.all-repositories.has_wiki, null) + # Settings + allow_merge_commit = try(repository.allow_merge_commit, local.config.organization.all-repositories.allow_merge_commit, null) + allow_squash_merge = try(repository.allow_squash_merge, local.config.organization.all-repositories.allow_squash_merge, null) + allow_rebase_merge = try(repository.allow_rebase_merge, local.config.organization.all-repositories.allow_rebase_merge, null) + allow_auto_merge = try(repository.allow_auto_merge, local.config.organization.all-repositories.allow_auto_merge, null) + delete_branch_on_merge = try(repository.delete_branch_on_merge, local.config.organization.all-repositories.delete_branch_on_merge, null) + } + ] + all_repositories = try(local.config.organization.all-repositories, []) - repositories = try(local.config.repositories, []) + repositories0 = try(local.config.repositories, []) all_repositories_rulesets = [ - for pair in try(setproduct(local.repositories, local.all_repositories.rulesets), []) : { + for pair in try(setproduct(local.repositories0, local.all_repositories.rulesets), []) : { repository = pair[0], ruleset = pair[1] } @@ -11,30 +36,30 @@ locals { } resource "github_repository" "repo" { - for_each = { for repo in local.repositories : repo.name => repo } + for_each = { for repository in local.repositories : repository.name => repository } # Metadata name = each.value.name - description = try(each.value.description, null) - homepage_url = try(each.value.homepage_url, null) - topics = try(each.value.topics, null) + description = each.value.description + homepage_url = each.value.homepage_url + topics = each.value.topics # Properties - visibility = try(each.value.visibility, local.all_repositories.visibility, null) - is_template = try(each.value.is_template, null) + visibility = each.value.visibility + is_template = each.value.is_template # Features - has_issues = try(each.value.has_issues, local.all_repositories.has_issues, null) - has_discussions = try(each.value.has_discussions, local.all_repositories.has_discussions, null) - has_projects = try(each.value.has_projects, local.all_repositories.has_projects, null) - has_wiki = try(each.value.has_wiki, local.all_repositories.has_wiki, null) + has_issues = each.value.has_issues + has_discussions = each.value.has_discussions + has_projects = each.value.has_projects + has_wiki = each.value.has_wiki # Settings - allow_merge_commit = try(each.value.allow_merge_commit, local.all_repositories.allow_merge_commit, null) - allow_squash_merge = try(each.value.allow_squash_merge, local.all_repositories.allow_squash_merge, null) - allow_rebase_merge = try(each.value.allow_rebase_merge, local.all_repositories.allow_rebase_merge, null) - allow_auto_merge = try(each.value.allow_auto_merge, local.all_repositories.allow_auto_merge, null) - delete_branch_on_merge = try(each.value.delete_branch_on_merge, local.all_repositories.delete_branch_on_merge, null) + allow_merge_commit = each.value.allow_merge_commit + allow_squash_merge = each.value.allow_squash_merge + allow_rebase_merge = each.value.allow_rebase_merge + allow_auto_merge = each.value.allow_auto_merge + delete_branch_on_merge = each.value.delete_branch_on_merge } resource "github_repository_ruleset" "all_repositories" { diff --git a/terraform/tests/defaults.tftest.hcl b/terraform/tests/defaults.tftest.hcl new file mode 100644 index 0000000..f9f7404 --- /dev/null +++ b/terraform/tests/defaults.tftest.hcl @@ -0,0 +1,51 @@ +run "defaults_file_repositories" { + command = plan + + variables { + path = "tests/fixtures/defaults.yaml" + } + + assert { + condition = local.config.repositories != [] + error_message = "Expected defaults config file to produce non-empty repositories local." + } + + assert { + condition = length(local.config.repositories) == 1 + error_message = "Expected defaults config file to produce exactly one repository." + } + + assert { + condition = local.config.repositories[0].name == "example" + error_message = "Expected defaults config file to produce the repository named 'example'." + } +} + +run "defaults_file_repositories_values" { + command = plan + + variables { + path = "tests/fixtures/defaults.yaml" + } + + assert { + condition = local.repositories == [{ + name = "example" + description = null + homepage_url = null + topics = null + visibility = null + is_template = null + has_issues = null + has_discussions = null + has_projects = null + has_wiki = null + allow_merge_commit = null + allow_squash_merge = null + allow_rebase_merge = null + allow_auto_merge = null + delete_branch_on_merge = null + }] + error_message = "The example repository defaults expected to be null." + } +} diff --git a/terraform/tests/empty.tftest.hcl b/terraform/tests/empty.tftest.hcl index f4352e0..1ab7834 100644 --- a/terraform/tests/empty.tftest.hcl +++ b/terraform/tests/empty.tftest.hcl @@ -7,6 +7,11 @@ run "empty_file" { assert { condition = local.config == null - error_message = "Expected empty file to produce empty result." + error_message = "Expected empty file to produce empty configuration." + } + + assert { + condition = local.repositories == [] + error_message = "Expected empty file to produce empty repositories." } } diff --git a/terraform/tests/fixtures/defaults.yaml b/terraform/tests/fixtures/defaults.yaml new file mode 100644 index 0000000..2c1660e --- /dev/null +++ b/terraform/tests/fixtures/defaults.yaml @@ -0,0 +1,3 @@ +--- +repositories: + - name: example diff --git a/terraform/tests/fixtures/organization-repository-values.yaml b/terraform/tests/fixtures/organization-repository-values.yaml new file mode 100644 index 0000000..b1f465f --- /dev/null +++ b/terraform/tests/fixtures/organization-repository-values.yaml @@ -0,0 +1,37 @@ +--- +organization: + all-repositories: + # Properties + visibility: public + # Features + has_issues: false + has_discussions: false + has_projects: false + has_wiki: false + # Settings + allow_merge_commit: false + allow_squash_merge: false + allow_rebase_merge: false + allow_auto_merge: false + delete_branch_on_merge: false +repositories: + - name: example + # Metadata + description: An example repository + homepage_url: https://example.com + topics: + - example-topic + # Properties + visibility: private + is_template: true + # Features + has_issues: true + has_discussions: true + has_projects: true + has_wiki: true + # Settings + allow_merge_commit: true + allow_squash_merge: true + allow_rebase_merge: true + allow_auto_merge: true + delete_branch_on_merge: true diff --git a/terraform/tests/fixtures/organization-values.yaml b/terraform/tests/fixtures/organization-values.yaml new file mode 100644 index 0000000..c2e1183 --- /dev/null +++ b/terraform/tests/fixtures/organization-values.yaml @@ -0,0 +1,18 @@ +--- +organization: + all-repositories: + # Properties + visibility: private + # Features + has_issues: true + has_discussions: true + has_projects: true + has_wiki: true + # Settings + allow_merge_commit: true + allow_squash_merge: true + allow_rebase_merge: true + allow_auto_merge: true + delete_branch_on_merge: true +repositories: + - name: example diff --git a/terraform/tests/fixtures/repository-values.yaml b/terraform/tests/fixtures/repository-values.yaml new file mode 100644 index 0000000..219acd5 --- /dev/null +++ b/terraform/tests/fixtures/repository-values.yaml @@ -0,0 +1,22 @@ +--- +repositories: + - name: example + # Metadata + description: An example repository + homepage_url: https://example.com + topics: + - example-topic + # Properties + visibility: private + is_template: true + # Features + has_issues: true + has_discussions: true + has_projects: true + has_wiki: true + # Settings + allow_merge_commit: true + allow_squash_merge: true + allow_rebase_merge: true + allow_auto_merge: true + delete_branch_on_merge: true diff --git a/terraform/tests/organization-repository-values.tftest.hcl b/terraform/tests/organization-repository-values.tftest.hcl new file mode 100644 index 0000000..9687dca --- /dev/null +++ b/terraform/tests/organization-repository-values.tftest.hcl @@ -0,0 +1,51 @@ +run "organization_repository_repositories" { + command = plan + + variables { + path = "tests/fixtures/organization-repository-values.yaml" + } + + assert { + condition = local.config.repositories != [] + error_message = "Expected defaults config file to produce non-empty repositories local." + } + + assert { + condition = length(local.config.repositories) == 1 + error_message = "Expected defaults config file to produce exactly one repository." + } + + assert { + condition = local.config.repositories[0].name == "example" + error_message = "Expected defaults config file to produce the repository named 'example'." + } +} + +run "organization_repository_repositories_values" { + command = plan + + variables { + path = "tests/fixtures/organization-repository-values.yaml" + } + + assert { + condition = local.repositories == [{ + name = "example" + description = "An example repository" + homepage_url = "https://example.com" + topics = ["example-topic"] + visibility = "private" + is_template = true + has_issues = true + has_discussions = true + has_projects = true + has_wiki = true + allow_merge_commit = true + allow_squash_merge = true + allow_rebase_merge = true + allow_auto_merge = true + delete_branch_on_merge = true + }] + error_message = "The example repository expected to be set to concrete values." + } +} diff --git a/terraform/tests/organization-values.tftest.hcl b/terraform/tests/organization-values.tftest.hcl new file mode 100644 index 0000000..e762588 --- /dev/null +++ b/terraform/tests/organization-values.tftest.hcl @@ -0,0 +1,51 @@ +run "organization_values_repositories" { + command = plan + + variables { + path = "tests/fixtures/organization-values.yaml" + } + + assert { + condition = local.config.repositories != [] + error_message = "Expected defaults config file to produce non-empty repositories local." + } + + assert { + condition = length(local.config.repositories) == 1 + error_message = "Expected defaults config file to produce exactly one repository." + } + + assert { + condition = local.config.repositories[0].name == "example" + error_message = "Expected defaults config file to produce the repository named 'example'." + } +} + +run "organization_values_repositories_values" { + command = plan + + variables { + path = "tests/fixtures/organization-values.yaml" + } + + assert { + condition = local.repositories == [{ + name = "example" + description = null + homepage_url = null + topics = null + visibility = "private" + is_template = null + has_issues = true + has_discussions = true + has_projects = true + has_wiki = true + allow_merge_commit = true + allow_squash_merge = true + allow_rebase_merge = true + allow_auto_merge = true + delete_branch_on_merge = true + }] + error_message = "The example repository expected to be set to concrete values." + } +} diff --git a/terraform/tests/repository-values.tftest.hcl b/terraform/tests/repository-values.tftest.hcl new file mode 100644 index 0000000..6fb32d0 --- /dev/null +++ b/terraform/tests/repository-values.tftest.hcl @@ -0,0 +1,51 @@ +run "repository_values_file_repositories" { + command = plan + + variables { + path = "tests/fixtures/repository-values.yaml" + } + + assert { + condition = local.config.repositories != [] + error_message = "Expected defaults config file to produce non-empty repositories local." + } + + assert { + condition = length(local.config.repositories) == 1 + error_message = "Expected defaults config file to produce exactly one repository." + } + + assert { + condition = local.config.repositories[0].name == "example" + error_message = "Expected defaults config file to produce the repository named 'example'." + } +} + +run "repository_values_file_repositories_values" { + command = plan + + variables { + path = "tests/fixtures/repository-values.yaml" + } + + assert { + condition = local.repositories == [{ + name = "example" + description = "An example repository" + homepage_url = "https://example.com" + topics = ["example-topic"] + visibility = "private" + is_template = true + has_issues = true + has_discussions = true + has_projects = true + has_wiki = true + allow_merge_commit = true + allow_squash_merge = true + allow_rebase_merge = true + allow_auto_merge = true + delete_branch_on_merge = true + }] + error_message = "The example repository expected to be set to concrete values." + } +}