diff --git a/github/resource_github_organization_ruleset.go b/github/resource_github_organization_ruleset.go index 014b28ef65..e8eaae8cba 100644 --- a/github/resource_github_organization_ruleset.go +++ b/github/resource_github_organization_ruleset.go @@ -428,6 +428,11 @@ func resourceGithubOrganizationRuleset() *schema.Resource { Description: "Choose which Actions workflows must pass before branches can be merged into a branch that matches this rule.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "do_not_enforce_on_create": { + Type: schema.TypeBool, + Optional: true, + Description: "Allow repositories and branches to be created if a check would otherwise prohibit it.", + }, "required_workflow": { Type: schema.TypeSet, MinItems: 1, diff --git a/github/resource_github_organization_ruleset_test.go b/github/resource_github_organization_ruleset_test.go index 9aae9f35b9..d6d9b6e64a 100644 --- a/github/resource_github_organization_ruleset_test.go +++ b/github/resource_github_organization_ruleset_test.go @@ -63,6 +63,7 @@ func TestGithubOrganizationRulesets(t *testing.T) { } required_workflows { + do_not_enforce_on_create = true required_workflow { path = "path/to/workflow.yaml" repository_id = 1234 @@ -91,13 +92,45 @@ func TestGithubOrganizationRulesets(t *testing.T) { check := resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( - "github_organization_ruleset.test", "name", + "github_organization_ruleset.test", + "name", "test", ), resource.TestCheckResourceAttr( - "github_organization_ruleset.test", "enforcement", + "github_organization_ruleset.test", + "enforcement", "active", ), + resource.TestCheckResourceAttr( + "github_organization_ruleset.test", + "rules.0.required_workflows.0.do_not_enforce_on_create", + "true", + ), + resource.TestCheckResourceAttr( + "github_organization_ruleset.test", + "rules.0.required_workflows.0.required_workflow.0.path", + "path/to/workflow.yaml", + ), + resource.TestCheckResourceAttr( + "github_organization_ruleset.test", + "rules.0.required_workflows.0.required_workflow.0.repository_id", + "1234", + ), + resource.TestCheckResourceAttr( + "github_repository_ruleset.test", + "rules.0.required_code_scanning.0.required_code_scanning_tool.0.alerts_threshold", + "errors", + ), + resource.TestCheckResourceAttr( + "github_repository_ruleset.test", + "rules.0.required_code_scanning.0.required_code_scanning_tool.0.security_alerts_threshold", + "high_or_higher", + ), + resource.TestCheckResourceAttr( + "github_repository_ruleset.test", + "rules.0.required_code_scanning.0.required_code_scanning_tool.0.tool", + "CodeQL", + ), ) testCase := func(t *testing.T, mode string) { diff --git a/github/resource_github_repository_ruleset_test.go b/github/resource_github_repository_ruleset_test.go index 0f40b26687..01c61f91a4 100644 --- a/github/resource_github_repository_ruleset_test.go +++ b/github/resource_github_repository_ruleset_test.go @@ -22,6 +22,7 @@ func TestGithubRepositoryRulesets(t *testing.T) { name = "tf-acc-test-%s" auto_init = true default_branch = "main" + vulnerability_alerts = true } resource "github_repository_environment" "example" { @@ -84,6 +85,14 @@ func TestGithubRepositoryRulesets(t *testing.T) { do_not_enforce_on_create = true } + required_code_scanning { + required_code_scanning_tool { + alerts_threshold = "errors" + security_alerts_threshold = "high_or_higher" + tool = "CodeQL" + } + } + non_fast_forward = true } } @@ -91,13 +100,30 @@ func TestGithubRepositoryRulesets(t *testing.T) { check := resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( - "github_repository_ruleset.test", "name", + "github_repository_ruleset.test", + "name", "test", ), resource.TestCheckResourceAttr( - "github_repository_ruleset.test", "enforcement", + "github_repository_ruleset.test", + "enforcement", "active", ), + resource.TestCheckResourceAttr( + "github_repository_ruleset.test", + "rules.0.required_code_scanning.0.required_code_scanning_tool.0.alerts_threshold", + "errors", + ), + resource.TestCheckResourceAttr( + "github_repository_ruleset.test", + "rules.0.required_code_scanning.0.required_code_scanning_tool.0.security_alerts_threshold", + "high_or_higher", + ), + resource.TestCheckResourceAttr( + "github_repository_ruleset.test", + "rules.0.required_code_scanning.0.required_code_scanning_tool.0.tool", + "CodeQL", + ), ) testCase := func(t *testing.T, mode string) { @@ -140,6 +166,7 @@ func TestGithubRepositoryRulesets(t *testing.T) { resource "github_repository" "test" { name = "tf-acc-test-%s" auto_init = false + vulnerability_alerts = true } resource "github_repository_environment" "example" { @@ -211,6 +238,7 @@ func TestGithubRepositoryRulesets(t *testing.T) { resource "github_repository" "test" { name = "%[1]s" description = "Terraform acceptance tests %[2]s" + vulnerability_alerts = true } resource "github_repository_ruleset" "test" { @@ -283,6 +311,7 @@ func TestGithubRepositoryRulesets(t *testing.T) { description = "Terraform acceptance tests %[1]s" auto_init = true default_branch = "main" + vulnerability_alerts = true } resource "github_repository_environment" "example" { diff --git a/github/respository_rules_utils.go b/github/respository_rules_utils.go index 44ccb27de1..ec6e3e58ab 100644 --- a/github/respository_rules_utils.go +++ b/github/respository_rules_utils.go @@ -375,7 +375,8 @@ func expandRules(input []interface{}, org bool) []*github.RepositoryRule { } params := &github.RequiredWorkflowsRuleParameters{ - RequiredWorkflows: requiredWorkflows, + DoNotEnforceOnCreate: requiredWorkflowsMap["do_not_enforce_on_create"].(bool), + RequiredWorkflows: requiredWorkflows, } rulesSlice = append(rulesSlice, github.NewRequiredWorkflowsRule(params)) } @@ -524,6 +525,51 @@ func flattenRules(rules []*github.RepositoryRule, org bool) []interface{} { rule["do_not_enforce_on_create"] = params.DoNotEnforceOnCreate rulesMap[v.Type] = []map[string]interface{}{rule} + case "workflows": + var params github.RequiredWorkflowsRuleParameters + + err := json.Unmarshal(*v.Parameters, ¶ms) + if err != nil { + log.Printf("[INFO] Unexpected error unmarshalling rule %s with parameters: %v", + v.Type, v.Parameters) + } + + requiredWorkflowsSlice := make([]map[string]interface{}, 0) + for _, check := range params.RequiredWorkflows { + requiredWorkflowsSlice = append(requiredWorkflowsSlice, map[string]interface{}{ + "repository_id": check.RepositoryID, + "path": check.Path, + "ref": check.Ref, + }) + } + + rule := make(map[string]interface{}) + rule["do_not_enforce_on_create"] = params.DoNotEnforceOnCreate + rule["required_workflow"] = requiredWorkflowsSlice + rulesMap["required_workflows"] = []map[string]interface{}{rule} + + case "code_scanning": + var params github.RequiredCodeScanningRuleParameters + + err := json.Unmarshal(*v.Parameters, ¶ms) + if err != nil { + log.Printf("[INFO] Unexpected error unmarshalling rule %s with parameters: %v", + v.Type, v.Parameters) + } + + requiredCodeScanningSlice := make([]map[string]interface{}, 0) + for _, check := range params.RequiredCodeScanningTools { + requiredCodeScanningSlice = append(requiredCodeScanningSlice, map[string]interface{}{ + "alerts_threshold": check.AlertsThreshold, + "security_alerts_threshold": check.SecurityAlertsThreshold, + "tool": check.Tool, + }) + } + + rule := make(map[string]interface{}) + rule["required_code_scanning_tool"] = requiredCodeScanningSlice + rulesMap["required_code_scanning"] = []map[string]interface{}{rule} + case "merge_queue": var params github.MergeQueueRuleParameters