From 41b1ad300496fc6c520e4ff0befa3e2f8f7e22a5 Mon Sep 17 00:00:00 2001 From: Jiayang Zhou Date: Thu, 4 Dec 2025 12:04:21 +0100 Subject: [PATCH 1/5] feat: Add support for Copilot code review in repository rulesets This change adds support for GitHub's Copilot code review feature in repository rulesets, allowing automatic code review requests for pull requests. Changes: - Add copilot_code_review rule to repository ruleset schema - Add CopilotCodeReviewRuleParameters and related types to go-github - Implement expand/flatten logic for copilot_code_review rules The copilot_code_review rule supports two configuration options: - review_new_pushes: Automatically review each new push to the PR - review_draft_pull_requests: Automatically review draft PRs Both options default to false, matching GitHub UI behavior. --- github/resource_github_repository_ruleset.go | 22 ++++++++++++++++++++ github/util_rules.go | 20 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/github/resource_github_repository_ruleset.go b/github/resource_github_repository_ruleset.go index ebb5400a75..24df346145 100644 --- a/github/resource_github_repository_ruleset.go +++ b/github/resource_github_repository_ruleset.go @@ -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`.", + }, + }, + }, + }, }, }, }, diff --git a/github/util_rules.go b/github/util_rules.go index 734801598f..016bba72c2 100644 --- a/github/util_rules.go +++ b/github/util_rules.go @@ -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 } @@ -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} } From 2de475ba6aa0284575edf0ae87ae1db241f76bf6 Mon Sep 17 00:00:00 2001 From: Jiayang Zhou Date: Thu, 4 Dec 2025 12:11:19 +0100 Subject: [PATCH 2/5] test: Add unit test for copilot_code_review rule --- github/util_rules_test.go | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/github/util_rules_test.go b/github/util_rules_test.go index 9c09fa03d4..2298fed112 100644 --- a/github/util_rules_test.go +++ b/github/util_rules_test.go @@ -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"]) + } +} From 927e59de3f6923e1dedf5aabf28c4a5362bd5733 Mon Sep 17 00:00:00 2001 From: Jiayang Zhou Date: Thu, 4 Dec 2025 12:13:37 +0100 Subject: [PATCH 3/5] test: Add copilot_code_review to acceptance test --- github/resource_github_repository_ruleset_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/github/resource_github_repository_ruleset_test.go b/github/resource_github_repository_ruleset_test.go index 54161a0af0..9dc58d599a 100644 --- a/github/resource_github_repository_ruleset_test.go +++ b/github/resource_github_repository_ruleset_test.go @@ -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] } @@ -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"), ), }, }, From 94f4104e803e1d9c9951192ac5f0ebe7801257f9 Mon Sep 17 00:00:00 2001 From: Jiayang Zhou Date: Thu, 4 Dec 2025 12:57:02 +0100 Subject: [PATCH 4/5] docs: Add copilot_code_review to repository_ruleset documentation --- website/docs/r/repository_ruleset.html.markdown | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/docs/r/repository_ruleset.html.markdown b/website/docs/r/repository_ruleset.html.markdown index 61c5c733cb..138555a03f 100644 --- a/website/docs/r/repository_ruleset.html.markdown +++ b/website/docs/r/repository_ruleset.html.markdown @@ -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. @@ -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. From 01c3e69f2253b6e9a72500a3e376f22ce7d36c09 Mon Sep 17 00:00:00 2001 From: Jiayang Zhou Date: Wed, 14 Jan 2026 20:58:06 +0100 Subject: [PATCH 5/5] feat: Add copilot_code_review support to organization ruleset This extends the copilot_code_review feature to github_organization_ruleset resource, matching the functionality already available in github_repository_ruleset. Changes: - Add copilot_code_review schema to organization ruleset resource - Update organization ruleset acceptance test with copilot_code_review - Add documentation for copilot_code_review in organization_ruleset.html.markdown --- .../resource_github_organization_ruleset.go | 22 +++++++++++++++++++ ...source_github_organization_ruleset_test.go | 7 ++++++ .../docs/r/organization_ruleset.html.markdown | 8 +++++++ 3 files changed, 37 insertions(+) diff --git a/github/resource_github_organization_ruleset.go b/github/resource_github_organization_ruleset.go index eea93ffc0a..c410148f61 100644 --- a/github/resource_github_organization_ruleset.go +++ b/github/resource_github_organization_ruleset.go @@ -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, diff --git a/github/resource_github_organization_ruleset_test.go b/github/resource_github_organization_ruleset_test.go index 774315e6db..cc8e056e81 100644 --- a/github/resource_github_organization_ruleset_test.go +++ b/github/resource_github_organization_ruleset_test.go @@ -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 { @@ -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"), ), }, }, diff --git a/website/docs/r/organization_ruleset.html.markdown b/website/docs/r/organization_ruleset.html.markdown index e04118f678..b55e0e0f2c 100644 --- a/website/docs/r/organization_ruleset.html.markdown +++ b/website/docs/r/organization_ruleset.html.markdown @@ -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. @@ -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))