diff --git a/github/resource_github_organization_ruleset.go b/github/resource_github_organization_ruleset.go index c210e80b25..2ef7b07f33 100644 --- a/github/resource_github_organization_ruleset.go +++ b/github/resource_github_organization_ruleset.go @@ -420,6 +420,42 @@ func resourceGithubOrganizationRuleset() *schema.Resource { }, }, }, + "required_workflows": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + 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{ + "required_workflow": { + Type: schema.TypeSet, + MinItems: 1, + Required: true, + Description: "Actions workflows that are required. Several can be defined.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "repository_id": { + Type: schema.TypeInt, + Required: true, + Description: "The repository in which the workflow is defined.", + }, + "path": { + Type: schema.TypeString, + Required: true, + Description: "The path to the workflow YAML definition file.", + }, + "ref": { + Type: schema.TypeString, + Optional: true, + Default: "master", + Description: "The ref (branch or tag) of the workflow file to use.", + }, + }, + }, + }, + }, + }, + }, }, }, }, diff --git a/github/resource_github_organization_ruleset_test.go b/github/resource_github_organization_ruleset_test.go index b9bd83fffb..ed83473ffe 100644 --- a/github/resource_github_organization_ruleset_test.go +++ b/github/resource_github_organization_ruleset_test.go @@ -54,14 +54,21 @@ func TestGithubOrganizationRulesets(t *testing.T) { } required_status_checks { - + required_check { context = "ci" } - + strict_required_status_checks_policy = true } + required_workflows { + required_workflow { + path = "path/to/workflow.yaml" + repository_id = 1234 + } + } + branch_name_pattern { name = "test" negate = false @@ -197,11 +204,11 @@ func TestGithubOrganizationRulesets(t *testing.T) { } required_status_checks { - + required_check { context = "ci" } - + strict_required_status_checks_policy = true } diff --git a/github/respository_rules_utils.go b/github/respository_rules_utils.go index e86cd8a93a..1b77a5e541 100644 --- a/github/respository_rules_utils.go +++ b/github/respository_rules_utils.go @@ -334,6 +334,37 @@ func expandRules(input []interface{}, org bool) []*github.RepositoryRule { rulesSlice = append(rulesSlice, github.NewRequiredStatusChecksRule(params)) } + // Required workflows to pass before merging rule + if v, ok := rulesMap["required_workflows"].([]interface{}); ok && len(v) != 0 { + requiredWorkflowsMap := v[0].(map[string]interface{}) + requiredWorkflows := make([]*github.RuleRequiredWorkflow, 0) + + if requiredWorkflowsInput, ok := requiredWorkflowsMap["required_workflow"]; ok { + + requiredWorkflowsSet := requiredWorkflowsInput.(*schema.Set) + for _, workflowMap := range requiredWorkflowsSet.List() { + workflow := workflowMap.(map[string]interface{}) + + // Get all parameters + repositoryID := github.Int64(int64(workflow["repository_id"].(int))) + ref := github.String(workflow["ref"].(string)) + + params := &github.RuleRequiredWorkflow{ + RepositoryID: repositoryID, + Path: workflow["path"].(string), + Ref: ref, + } + + requiredWorkflows = append(requiredWorkflows, params) + } + } + + params := &github.RequiredWorkflowsRuleParameters{ + RequiredWorkflows: requiredWorkflows, + } + rulesSlice = append(rulesSlice, github.NewRequiredWorkflowsRule(params)) + } + return rulesSlice } diff --git a/website/docs/r/organization_ruleset.html.markdown b/website/docs/r/organization_ruleset.html.markdown index 13c182e290..a02bb0fcc4 100644 --- a/website/docs/r/organization_ruleset.html.markdown +++ b/website/docs/r/organization_ruleset.html.markdown @@ -67,7 +67,6 @@ resource "github_organization_ruleset" "example" { The `rules` block supports the following: - * `branch_name_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the branch_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `tag_name_pattern` as it only applies to rulesets with target `branch`. (see [below for nested schema](#rules.branch_name_pattern)) * `commit_author_email_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the commit_author_email_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. (see [below for nested schema](#rules.commit_author_email_pattern)) @@ -90,6 +89,8 @@ The `rules` block supports the following: * `required_status_checks` - (Optional) (Block List, Max: 1) Choose which status checks must pass before branches can be merged into a branch that matches this rule. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. (see [below for nested schema](#rules.required_status_checks)) +* `required_workflows` - (Optional) (Block List, Max: 1) Define which Actions workflows must pass before changes can be merged into a branch matching the rule. Multiple workflows can be specified. (see [below for nested schema](#rules.required_workflows)) + * `tag_name_pattern` - (Optional) (Block List, Max: 1) Parameters to be used for the tag_name_pattern rule. This rule only applies to repositories within an enterprise, it cannot be applied to repositories owned by individuals or regular organizations. Conflicts with `branch_name_pattern` as it only applies to rulesets with target `tag`. (see [below for nested schema](#rules.tag_name_pattern)) * `update` - (Optional) (Boolean) Only allow users with bypass permission to update matching refs. @@ -104,7 +105,6 @@ The `rules` block supports the following: * `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. - #### rules.commit_author_email_pattern #### * `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. @@ -115,7 +115,6 @@ The `rules` block supports the following: * `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. - #### rules.commit_message_pattern #### * `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. @@ -126,7 +125,6 @@ The `rules` block supports the following: * `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. - #### rules.committer_email_pattern #### * `operator` - (Required) (String) The operator to use for matching. Can be one of: `starts_with`, `ends_with`, `contains`, `regex`. @@ -137,7 +135,6 @@ The `rules` block supports the following: * `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. - #### rules.pull_request #### * `dismiss_stale_reviews_on_push` - (Optional) (Boolean) New, reviewable commits pushed will dismiss previous pull request review approvals. Defaults to `false`. @@ -162,7 +159,17 @@ The `rules` block supports the following: * `integration_id` - (Optional) (Number) The optional integration ID that this status check must originate from. +#### rules.required_workflows #### + +* `required_workflow` - (Required) (Block Set, Min: 1) Actions workflows that are required. Multiple can be defined. (see [below for nested schema](#rules.required_workflows.required_workflow)) + +#### rules.required_workflows.required_workflow #### +* `repository_id` - (Required) (Number) The ID of the repository. Names, full names and repository URLs are not supported. + +* `path` - (Required) (String) The path to the YAML definition file of the workflow. + +* `ref` - (Optional) (String) The optional ref from which to fetch the workflow. Defaults to `master`. #### rules.tag_name_pattern #### @@ -174,8 +181,6 @@ The `rules` block supports the following: * `negate` - (Optional) (Boolean) If true, the rule will fail if the pattern matches. - - #### bypass_actors #### * `actor_id` - (Required) (Number) The ID of the actor that can bypass a ruleset. @@ -185,6 +190,7 @@ The `rules` block supports the following: * `bypass_mode` - (Optional) (String) When the specified actor can bypass the ruleset. pull_request means that an actor can only bypass rules on pull requests. Can be one of: `always`, `pull_request`. ~>Note: at the time of writing this, the following actor types correspond to the following actor IDs: + * `OrganizationAdmin` -> `1` * `RepositoryRole` (This is the actor type, the following are the base repository roles and their associated IDs.) * `maintain` -> `2` @@ -208,21 +214,19 @@ One of `repository_id` and `repository_name` must be set for the rule to target #### conditions.repository_name #### * `exclude` - (Required) (List of String) Array of repository names or patterns to exclude. The condition will not pass if any of these patterns match. - + * `include` - (Required) (List of String) Array of repository names or patterns to include. One of these patterns must match for the condition to pass. Also accepts `~ALL` to include all repositories. ## Attributes Reference The following additional attributes are exported: - * `etag` (String) * `node_id` (String) GraphQL global node id for use with v4 API. * `ruleset_id` (Number) GitHub ID for the ruleset. - ## Import GitHub Organization Rulesets can be imported using the GitHub ruleset ID e.g.