diff --git a/main.tf b/main.tf index 8da87eb..e2072ea 100644 --- a/main.tf +++ b/main.tf @@ -25,3 +25,6 @@ module "teams" { teams = var.teams } +module "repositories" { + source = "./modules/repositories" +} diff --git a/modules/repositories/config.example.yaml b/modules/repositories/config.example.yaml new file mode 100644 index 0000000..593e2ad --- /dev/null +++ b/modules/repositories/config.example.yaml @@ -0,0 +1,19 @@ +description: "リポジトリの説明文" +visibility: private # private / internal / public + +topics: + - backend + - example + +has_issues: true +has_projects: false +has_wiki: false + +allow_merge_commit: false +allow_squash_merge: true +allow_rebase_merge: false + +required_approving_review_count: 1 +require_code_owner_review: false +required_status_checks: + - "ci" # GitHub Actionsのjob名 or ステータスチェック名 diff --git a/modules/repositories/github-terraform/config.yaml b/modules/repositories/github-terraform/config.yaml new file mode 100644 index 0000000..14d47be --- /dev/null +++ b/modules/repositories/github-terraform/config.yaml @@ -0,0 +1,5 @@ +description: "This organization's manage" +visibility: public + +required_status_checks: + - "Terraform Plan" diff --git a/modules/repositories/main.tf b/modules/repositories/main.tf new file mode 100644 index 0000000..3702f1c --- /dev/null +++ b/modules/repositories/main.tf @@ -0,0 +1,101 @@ +locals { + repo_config_files = fileset(path.module, "*/config.yaml") + + repositories = { + for f in local.repo_config_files : + dirname(f) => yamldecode(file("${path.module}/${f}")) + } + + effective_status_checks = { + for name, cfg in local.repositories : + name => coalesce(lookup(cfg, "required_status_checks", null), []) + } +} + +resource "github_repository" "this" { + for_each = local.repositories + + name = each.key + description = try(each.value.description, "") + visibility = try(each.value.visibility, "private") + topics = try(each.value.topics, []) + + has_issues = try(each.value.has_issues, true) + has_projects = try(each.value.has_projects, false) + has_wiki = try(each.value.has_wiki, false) + + allow_merge_commit = try(each.value.allow_merge_commit, false) + allow_squash_merge = try(each.value.allow_squash_merge, true) + allow_rebase_merge = try(each.value.allow_rebase_merge, false) + delete_branch_on_merge = true + squash_merge_commit_title = "PR_TITLE" + + auto_init = true + + lifecycle { + # 誤ってterraform destroy/apply時にリポジトリごと消えるのを防ぐ + prevent_destroy = true + ignore_changes = [ + # README等をauto_init後に手動編集しても差分検知しない + auto_init, + ] + } +} + +resource "github_repository_vulnerability_alerts" "this" { + for_each = local.repositories + repository = github_repository.this[each.key].name + enabled = true +} + +resource "github_branch_default" "this" { + for_each = local.repositories + repository = github_repository.this[each.key].name + branch = "main" +} + +resource "github_repository_ruleset" "main_protection" { + for_each = local.repositories + + name = "main-protection" + repository = github_repository.this[each.key].name + target = "branch" + enforcement = "active" + + conditions { + ref_name { + include = ["~DEFAULT_BRANCH"] + exclude = [] + } + } + + rules { + deletion = true + non_fast_forward = true + + pull_request { + required_approving_review_count = try(each.value.required_approving_review_count, 1) + dismiss_stale_reviews_on_push = try(each.value.dismiss_stale_reviews_on_push, true) + require_code_owner_review = try(each.value.require_code_owner_review, false) + require_last_push_approval = try(each.value.require_last_push_approval, false) + required_review_thread_resolution = try(each.value.required_review_thread_resolution, true) + } + + dynamic "required_status_checks" { + for_each = length(local.effective_status_checks[each.key]) > 0 ? [local.effective_status_checks[each.key]] : [] + + content { + strict_required_status_checks_policy = try(each.value.strict_status_checks, true) + + dynamic "required_check" { + for_each = required_status_checks.value + content { + context = required_check.value + } + } + } + } + } + + depends_on = [github_branch_default.this] +} diff --git a/modules/repositories/setup-cloudflare-tunnel/config.yaml b/modules/repositories/setup-cloudflare-tunnel/config.yaml new file mode 100644 index 0000000..8e929ca --- /dev/null +++ b/modules/repositories/setup-cloudflare-tunnel/config.yaml @@ -0,0 +1,4 @@ +description: "GitHub Actions Setup Cloudflare Tunnel" +visibility: public + +strict_status_checks: false \ No newline at end of file