Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions github/resource_github_organization_ruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,28 @@ func resourceGithubOrganizationRuleset() *schema.Resource {
},
},
},
"copilot_code_review": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Automatically request Copilot code review for new pull requests if the author has access to Copilot code review and their premium requests quota has not reached the limit.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"review_on_push": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Copilot automatically reviews each new push to the pull request. Defaults to `false`.",
},
"review_draft_pull_requests": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Copilot automatically reviews draft pull requests before they are marked as ready for review. Defaults to `false`.",
},
},
},
},
"required_status_checks": {
Type: schema.TypeList,
MaxItems: 1,
Expand Down
7 changes: 7 additions & 0 deletions github/resource_github_organization_ruleset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ resource "github_organization_ruleset" "test" {
require_last_push_approval = true
}
copilot_code_review {
review_on_push = true
review_draft_pull_requests = false
}
required_status_checks {
required_check {
Expand Down Expand Up @@ -166,6 +171,8 @@ resource "github_organization_ruleset" "test" {
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.required_code_scanning.0.required_code_scanning_tool.0.alerts_threshold", "errors"),
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.required_code_scanning.0.required_code_scanning_tool.0.security_alerts_threshold", "high_or_higher"),
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.required_code_scanning.0.required_code_scanning_tool.0.tool", "CodeQL"),
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.copilot_code_review.0.review_on_push", "true"),
resource.TestCheckResourceAttr("github_organization_ruleset.test", "rules.0.copilot_code_review.0.review_draft_pull_requests", "false"),
),
},
},
Expand Down
22 changes: 22 additions & 0 deletions github/resource_github_repository_ruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,28 @@ func resourceGithubRepositoryRuleset() *schema.Resource {
},
},
},
"copilot_code_review": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Automatically request Copilot code review for new pull requests if the author has access to Copilot code review and their premium requests quota has not reached the limit.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"review_on_push": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Copilot automatically reviews each new push to the pull request. Defaults to `false`.",
},
"review_draft_pull_requests": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Copilot automatically reviews draft pull requests before they are marked as ready for review. Defaults to `false`.",
},
},
},
},
},
},
},
Expand Down
7 changes: 7 additions & 0 deletions github/resource_github_repository_ruleset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ resource "github_repository_ruleset" "test" {
min_entries_to_merge_wait_minutes = 60
}
copilot_code_review {
review_on_push = true
review_draft_pull_requests = false
}
required_deployments {
required_deployment_environments = [github_repository_environment.example.environment]
}
Expand Down Expand Up @@ -128,6 +133,8 @@ resource "github_repository_ruleset" "test" {
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"),
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.copilot_code_review.0.review_on_push", "true"),
resource.TestCheckResourceAttr("github_repository_ruleset.test", "rules.0.copilot_code_review.0.review_draft_pull_requests", "false"),
),
},
},
Expand Down
20 changes: 20 additions & 0 deletions github/util_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,16 @@ func expandRules(input []any, org bool) *github.RepositoryRulesetRules {
rulesetRules.FileExtensionRestriction = params
}

// Copilot code review rule
if v, ok := rulesMap["copilot_code_review"].([]any); ok && len(v) != 0 {
copilotCodeReviewMap := v[0].(map[string]any)
params := &github.CopilotCodeReviewRuleParameters{
ReviewOnPush: copilotCodeReviewMap["review_on_push"].(bool),
ReviewDraftPullRequests: copilotCodeReviewMap["review_draft_pull_requests"].(bool),
}
rulesetRules.CopilotCodeReview = params
}

return rulesetRules
}

Expand Down Expand Up @@ -734,6 +744,16 @@ func flattenRules(rules *github.RepositoryRulesetRules, org bool) []any {
rulesMap["file_extension_restriction"] = fileExtensionRestrictionSlice
}

// Copilot code review rule
if rules.CopilotCodeReview != nil {
copilotCodeReviewSlice := make([]map[string]any, 0)
copilotCodeReviewSlice = append(copilotCodeReviewSlice, map[string]any{
"review_on_push": rules.CopilotCodeReview.ReviewOnPush,
"review_draft_pull_requests": rules.CopilotCodeReview.ReviewDraftPullRequests,
})
rulesMap["copilot_code_review"] = copilotCodeReviewSlice
}

return []any{rulesMap}
}

Expand Down
55 changes: 55 additions & 0 deletions github/util_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,58 @@ func TestCompletePushRulesetSupport(t *testing.T) {
t.Errorf("Expected 3 restricted file extensions, got %d", len(restrictedExts))
}
}

func TestCopilotCodeReviewRoundTrip(t *testing.T) {
// Test that copilot_code_review rule survives expand -> flatten round trip
rulesMap := map[string]any{
"copilot_code_review": []any{
map[string]any{
"review_on_push": true,
"review_draft_pull_requests": false,
},
},
}

input := []any{rulesMap}

// Expand to GitHub API format
expandedRules := expandRules(input, false)

if expandedRules == nil {
t.Fatal("Expected expandedRules to not be nil")
}

if expandedRules.CopilotCodeReview == nil {
t.Fatal("Expected CopilotCodeReview rule to be set")
}

if expandedRules.CopilotCodeReview.ReviewOnPush != true {
t.Errorf("Expected ReviewOnPush to be true, got %v", expandedRules.CopilotCodeReview.ReviewOnPush)
}

if expandedRules.CopilotCodeReview.ReviewDraftPullRequests != false {
t.Errorf("Expected ReviewDraftPullRequests to be false, got %v", expandedRules.CopilotCodeReview.ReviewDraftPullRequests)
}

// Flatten back to terraform format
flattenedResult := flattenRules(expandedRules, false)

if len(flattenedResult) != 1 {
t.Fatalf("Expected 1 flattened result, got %d", len(flattenedResult))
}

flattenedRulesMap := flattenedResult[0].(map[string]any)
copilotRules := flattenedRulesMap["copilot_code_review"].([]map[string]any)

if len(copilotRules) != 1 {
t.Fatalf("Expected 1 copilot_code_review rule after round trip, got %d", len(copilotRules))
}

if copilotRules[0]["review_on_push"] != true {
t.Errorf("Expected review_on_push to be true, got %v", copilotRules[0]["review_on_push"])
}

if copilotRules[0]["review_draft_pull_requests"] != false {
t.Errorf("Expected review_draft_pull_requests to be false, got %v", copilotRules[0]["review_draft_pull_requests"])
}
}
8 changes: 8 additions & 0 deletions website/docs/r/organization_ruleset.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ The `rules` block supports the following:

* `pull_request` - (Optional) (Block List, Max: 1) Require all commits be made to a non-target branch and submitted via a pull request before they can be merged. (see [below for nested schema](#rules.pull_request))

* `copilot_code_review` - (Optional) (Block List, Max: 1) Automatically request Copilot code review for new pull requests if the author has access to Copilot code review and their premium requests quota has not reached the limit. (see [below for nested schema](#rulescopilot_code_review))

* `required_linear_history` - (Optional) (Boolean) Prevent merge commits from being pushed to matching branches.

* `required_signatures` - (Optional) (Boolean) Commits pushed to matching branches must have verified signatures.
Expand Down Expand Up @@ -210,6 +212,12 @@ The `rules` block supports the following:

* `required_review_thread_resolution` - (Optional) (Boolean) All conversations on code must be resolved before a pull request can be merged. Defaults to `false`.

#### rules.copilot_code_review ####

* `review_on_push` - (Optional) (Boolean) Copilot automatically reviews each new push to the pull request. Defaults to `false`.

* `review_draft_pull_requests` - (Optional) (Boolean) Copilot automatically reviews draft pull requests before they are marked as ready for review. Defaults to `false`.

#### rules.required_status_checks ####

* `required_check` - (Required) (Block Set, Min: 1) Status checks that are required. Several can be defined. (see [below for nested schema](#rules.required_status_checks.required_check))
Expand Down
8 changes: 8 additions & 0 deletions website/docs/r/repository_ruleset.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ The `rules` block supports the following:

* `pull_request` - (Optional) (Block List, Max: 1) Require all commits be made to a non-target branch and submitted via a pull request before they can be merged. (see [below for nested schema](#rulespull_request))

* `copilot_code_review` - (Optional) (Block List, Max: 1) Automatically request Copilot code review for new pull requests if the author has access to Copilot code review and their premium requests quota has not reached the limit. (see [below for nested schema](#rulescopilot_code_review))

* `required_deployments` - (Optional) (Block List, Max: 1) Choose which environments must be successfully deployed to before branches can be merged into a branch that matches this rule. (see [below for nested schema](#rulesrequired_deployments))

* `required_linear_history` - (Optional) (Boolean) Prevent merge commits from being pushed to matching branches.
Expand Down Expand Up @@ -215,6 +217,12 @@ The `rules` block supports the following:

* `required_review_thread_resolution` - (Optional) (Boolean) All conversations on code must be resolved before a pull request can be merged. Defaults to `false`.

#### rules.copilot_code_review ####

* `review_on_push` - (Optional) (Boolean) Copilot automatically reviews each new push to the pull request. Defaults to `false`.

* `review_draft_pull_requests` - (Optional) (Boolean) Copilot automatically reviews draft pull requests before they are marked as ready for review. Defaults to `false`.

#### rules.required_deployments ####

* `required_deployment_environments` - (Required) (List of String) The environments that must be successfully deployed to before branches can be merged.
Expand Down