Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
8 changes: 8 additions & 0 deletions github/github-accessors.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions github/github-accessors_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 36 additions & 2 deletions github/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const (
RulesetRuleTypeTagNamePattern RepositoryRuleType = "tag_name_pattern"
RulesetRuleTypeUpdate RepositoryRuleType = "update"
RulesetRuleTypeWorkflows RepositoryRuleType = "workflows"
RulesetRuleTypeCopilotCodeReview RepositoryRuleType = "copilot_code_review"

// Push target rules.
RulesetRuleTypeFileExtensionRestriction RepositoryRuleType = "file_extension_restriction"
Expand Down Expand Up @@ -306,6 +307,7 @@ type RepositoryRulesetRules struct {
TagNamePattern *PatternRuleParameters
Workflows *WorkflowsRuleParameters
CodeScanning *CodeScanningRuleParameters
CopilotCodeReview *CopilotCodeReviewRuleParameters

// Push target rules.
FileExtensionRestriction *FileExtensionRestrictionRuleParameters
Expand Down Expand Up @@ -539,6 +541,12 @@ type CodeScanningRuleParameters struct {
CodeScanningTools []*RuleCodeScanningTool `json:"code_scanning_tools"`
}

// CopilotCodeReviewRuleParameters represents the copilot_code_review rule parameters.
type CopilotCodeReviewRuleParameters struct {
ReviewNewPushes bool `json:"review_new_pushes"`
ReviewDraftPullRequests bool `json:"review_draft_pull_requests"`
}

// RuleCodeScanningTool represents a single code scanning tool for the code scanning parameters.
type RuleCodeScanningTool struct {
AlertsThreshold CodeScanningAlertsThreshold `json:"alerts_threshold"`
Expand Down Expand Up @@ -566,9 +574,9 @@ type repositoryRulesetRuleWrapper struct {

// MarshalJSON is a custom JSON marshaler for RulesetRules.
func (r *RepositoryRulesetRules) MarshalJSON() ([]byte, error) {
// The RepositoryRulesetRules type marshals to between 1 and 21 rules.
// The RepositoryRulesetRules type marshals to between 1 and 22 rules.
// If new rules are added to RepositoryRulesetRules the capacity below needs increasing
rawRules := make([]json.RawMessage, 0, 21)
rawRules := make([]json.RawMessage, 0, 22)

if r.Creation != nil {
bytes, err := marshalRepositoryRulesetRule(RulesetRuleTypeCreation, r.Creation)
Expand Down Expand Up @@ -738,6 +746,14 @@ func (r *RepositoryRulesetRules) MarshalJSON() ([]byte, error) {
rawRules = append(rawRules, json.RawMessage(bytes))
}

if r.CopilotCodeReview != nil {
bytes, err := marshalRepositoryRulesetRule(RulesetRuleTypeCopilotCodeReview, r.CopilotCodeReview)
if err != nil {
return nil, err
}
rawRules = append(rawRules, json.RawMessage(bytes))
}

if r.RepositoryCreate != nil {
bytes, err := marshalRepositoryRulesetRule(RulesetRuleTypeRepositoryCreate, r.RepositoryCreate)
if err != nil {
Expand Down Expand Up @@ -965,6 +981,14 @@ func (r *RepositoryRulesetRules) UnmarshalJSON(data []byte) error {
return err
}
}
case RulesetRuleTypeCopilotCodeReview:
r.CopilotCodeReview = &CopilotCodeReviewRuleParameters{}

if w.Parameters != nil {
if err := json.Unmarshal(w.Parameters, r.CopilotCodeReview); err != nil {
return err
}
}
case RulesetRuleTypeRepositoryCreate:
r.RepositoryCreate = &EmptyRuleParameters{}
case RulesetRuleTypeRepositoryDelete:
Expand Down Expand Up @@ -1366,6 +1390,16 @@ func (r *RepositoryRule) UnmarshalJSON(data []byte) error {
}
}

r.Parameters = p
case RulesetRuleTypeCopilotCodeReview:
p := &CopilotCodeReviewRuleParameters{}

if w.Parameters != nil {
if err := json.Unmarshal(w.Parameters, p); err != nil {
return err
}
}

r.Parameters = p
case RulesetRuleTypeRepositoryCreate:
r.Parameters = nil
Expand Down
23 changes: 21 additions & 2 deletions github/rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,17 @@ func TestRulesetRules(t *testing.T) {
},
},
},
CopilotCodeReview: &CopilotCodeReviewRuleParameters{
ReviewNewPushes: true,
ReviewDraftPullRequests: false,
},
RepositoryCreate: &EmptyRuleParameters{},
RepositoryDelete: &EmptyRuleParameters{},
RepositoryName: &SimplePatternRuleParameters{Pattern: "^test-.+", Negate: false},
RepositoryTransfer: &EmptyRuleParameters{},
RepositoryVisibility: &RepositoryVisibilityRuleParameters{Internal: false, Private: false},
},
`[{"type":"creation"},{"type":"update"},{"type":"deletion"},{"type":"required_linear_history"},{"type":"merge_queue","parameters":{"check_response_timeout_minutes":5,"grouping_strategy":"ALLGREEN","max_entries_to_build":10,"max_entries_to_merge":20,"merge_method":"SQUASH","min_entries_to_merge":1,"min_entries_to_merge_wait_minutes":15}},{"type":"required_deployments","parameters":{"required_deployment_environments":["test1","test2"]}},{"type":"required_signatures"},{"type":"pull_request","parameters":{"allowed_merge_methods":["squash","rebase"],"dismiss_stale_reviews_on_push":true,"require_code_owner_review":true,"require_last_push_approval":true,"required_approving_review_count":2,"required_review_thread_resolution":true}},{"type":"required_status_checks","parameters":{"required_status_checks":[{"context":"test1"},{"context":"test2"}],"strict_required_status_checks_policy":true}},{"type":"non_fast_forward"},{"type":"commit_message_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"commit_author_email_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"committer_email_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"branch_name_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"tag_name_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"file_path_restriction","parameters":{"restricted_file_paths":["test1","test2"]}},{"type":"max_file_path_length","parameters":{"max_file_path_length":512}},{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":[".exe",".pkg"]}},{"type":"max_file_size","parameters":{"max_file_size":1024}},{"type":"workflows","parameters":{"workflows":[{"path":".github/workflows/test1.yaml"},{"path":".github/workflows/test2.yaml"}]}},{"type":"code_scanning","parameters":{"code_scanning_tools":[{"alerts_threshold":"all","security_alerts_threshold":"all","tool":"test"},{"alerts_threshold":"none","security_alerts_threshold":"none","tool":"test"}]}},{"type":"repository_create"},{"type":"repository_delete"},{"type":"repository_name","parameters":{"negate":false,"pattern":"^test-.+"}},{"type":"repository_transfer"},{"type":"repository_visibility","parameters":{"internal":false,"private":false}}]`,
`[{"type":"creation"},{"type":"update"},{"type":"deletion"},{"type":"required_linear_history"},{"type":"merge_queue","parameters":{"check_response_timeout_minutes":5,"grouping_strategy":"ALLGREEN","max_entries_to_build":10,"max_entries_to_merge":20,"merge_method":"SQUASH","min_entries_to_merge":1,"min_entries_to_merge_wait_minutes":15}},{"type":"required_deployments","parameters":{"required_deployment_environments":["test1","test2"]}},{"type":"required_signatures"},{"type":"pull_request","parameters":{"allowed_merge_methods":["squash","rebase"],"dismiss_stale_reviews_on_push":true,"require_code_owner_review":true,"require_last_push_approval":true,"required_approving_review_count":2,"required_review_thread_resolution":true}},{"type":"required_status_checks","parameters":{"required_status_checks":[{"context":"test1"},{"context":"test2"}],"strict_required_status_checks_policy":true}},{"type":"non_fast_forward"},{"type":"commit_message_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"commit_author_email_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"committer_email_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"branch_name_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"tag_name_pattern","parameters":{"operator":"starts_with","pattern":"test"}},{"type":"file_path_restriction","parameters":{"restricted_file_paths":["test1","test2"]}},{"type":"max_file_path_length","parameters":{"max_file_path_length":512}},{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":[".exe",".pkg"]}},{"type":"max_file_size","parameters":{"max_file_size":1024}},{"type":"workflows","parameters":{"workflows":[{"path":".github/workflows/test1.yaml"},{"path":".github/workflows/test2.yaml"}]}},{"type":"code_scanning","parameters":{"code_scanning_tools":[{"alerts_threshold":"all","security_alerts_threshold":"all","tool":"test"},{"alerts_threshold":"none","security_alerts_threshold":"none","tool":"test"}]}},{"type":"copilot_code_review","parameters":{"review_new_pushes":true,"review_draft_pull_requests":false}},{"type":"repository_create"},{"type":"repository_delete"},{"type":"repository_name","parameters":{"negate":false,"pattern":"^test-.+"}},{"type":"repository_transfer"},{"type":"repository_visibility","parameters":{"internal":false,"private":false}}]`,
},
{
"all_rules_with_all_params",
Expand Down Expand Up @@ -240,13 +244,17 @@ func TestRulesetRules(t *testing.T) {
},
},
},
CopilotCodeReview: &CopilotCodeReviewRuleParameters{
ReviewNewPushes: true,
ReviewDraftPullRequests: false,
},
RepositoryCreate: &EmptyRuleParameters{},
RepositoryDelete: &EmptyRuleParameters{},
RepositoryName: &SimplePatternRuleParameters{Pattern: "^test-.+", Negate: false},
RepositoryTransfer: &EmptyRuleParameters{},
RepositoryVisibility: &RepositoryVisibilityRuleParameters{Internal: false, Private: false},
},
`[{"type":"creation"},{"type":"update","parameters":{"update_allows_fetch_and_merge":true}},{"type":"deletion"},{"type":"required_linear_history"},{"type":"merge_queue","parameters":{"check_response_timeout_minutes":5,"grouping_strategy":"ALLGREEN","max_entries_to_build":10,"max_entries_to_merge":20,"merge_method":"SQUASH","min_entries_to_merge":1,"min_entries_to_merge_wait_minutes":15}},{"type":"required_deployments","parameters":{"required_deployment_environments":["test1","test2"]}},{"type":"required_signatures"},{"type":"pull_request","parameters":{"allowed_merge_methods":["squash","rebase"],"automatic_copilot_code_review_enabled":false,"dismiss_stale_reviews_on_push":true,"require_code_owner_review":true,"require_last_push_approval":true,"required_approving_review_count":2,"required_review_thread_resolution":true}},{"type":"required_status_checks","parameters":{"do_not_enforce_on_create":true,"required_status_checks":[{"context":"test1","integration_id":1},{"context":"test2","integration_id":2}],"strict_required_status_checks_policy":true}},{"type":"non_fast_forward"},{"type":"commit_message_pattern","parameters":{"name":"cmp","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"commit_author_email_pattern","parameters":{"name":"caep","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"committer_email_pattern","parameters":{"name":"cep","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"branch_name_pattern","parameters":{"name":"bp","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"tag_name_pattern","parameters":{"name":"tp","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"file_path_restriction","parameters":{"restricted_file_paths":["test1","test2"]}},{"type":"max_file_path_length","parameters":{"max_file_path_length":512}},{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":[".exe",".pkg"]}},{"type":"max_file_size","parameters":{"max_file_size":1024}},{"type":"workflows","parameters":{"do_not_enforce_on_create":true,"workflows":[{"path":".github/workflows/test1.yaml","ref":"main","repository_id":1,"sha":"aaaa"},{"path":".github/workflows/test2.yaml","ref":"main","repository_id":2,"sha":"bbbb"}]}},{"type":"code_scanning","parameters":{"code_scanning_tools":[{"alerts_threshold":"all","security_alerts_threshold":"all","tool":"test"},{"alerts_threshold":"none","security_alerts_threshold":"none","tool":"test"}]}},{"type":"repository_create"},{"type":"repository_delete"},{"type":"repository_name","parameters":{"negate":false,"pattern":"^test-.+"}},{"type":"repository_transfer"},{"type":"repository_visibility","parameters":{"internal":false,"private":false}}]`,
`[{"type":"creation"},{"type":"update","parameters":{"update_allows_fetch_and_merge":true}},{"type":"deletion"},{"type":"required_linear_history"},{"type":"merge_queue","parameters":{"check_response_timeout_minutes":5,"grouping_strategy":"ALLGREEN","max_entries_to_build":10,"max_entries_to_merge":20,"merge_method":"SQUASH","min_entries_to_merge":1,"min_entries_to_merge_wait_minutes":15}},{"type":"required_deployments","parameters":{"required_deployment_environments":["test1","test2"]}},{"type":"required_signatures"},{"type":"pull_request","parameters":{"allowed_merge_methods":["squash","rebase"],"automatic_copilot_code_review_enabled":false,"dismiss_stale_reviews_on_push":true,"require_code_owner_review":true,"require_last_push_approval":true,"required_approving_review_count":2,"required_review_thread_resolution":true}},{"type":"required_status_checks","parameters":{"do_not_enforce_on_create":true,"required_status_checks":[{"context":"test1","integration_id":1},{"context":"test2","integration_id":2}],"strict_required_status_checks_policy":true}},{"type":"non_fast_forward"},{"type":"commit_message_pattern","parameters":{"name":"cmp","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"commit_author_email_pattern","parameters":{"name":"caep","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"committer_email_pattern","parameters":{"name":"cep","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"branch_name_pattern","parameters":{"name":"bp","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"tag_name_pattern","parameters":{"name":"tp","negate":false,"operator":"starts_with","pattern":"test"}},{"type":"file_path_restriction","parameters":{"restricted_file_paths":["test1","test2"]}},{"type":"max_file_path_length","parameters":{"max_file_path_length":512}},{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":[".exe",".pkg"]}},{"type":"max_file_size","parameters":{"max_file_size":1024}},{"type":"workflows","parameters":{"do_not_enforce_on_create":true,"workflows":[{"path":".github/workflows/test1.yaml","ref":"main","repository_id":1,"sha":"aaaa"},{"path":".github/workflows/test2.yaml","ref":"main","repository_id":2,"sha":"bbbb"}]}},{"type":"code_scanning","parameters":{"code_scanning_tools":[{"alerts_threshold":"all","security_alerts_threshold":"all","tool":"test"},{"alerts_threshold":"none","security_alerts_threshold":"none","tool":"test"}]}},{"type":"copilot_code_review","parameters":{"review_new_pushes":true,"review_draft_pull_requests":false}},{"type":"repository_create"},{"type":"repository_delete"},{"type":"repository_name","parameters":{"negate":false,"pattern":"^test-.+"}},{"type":"repository_transfer"},{"type":"repository_visibility","parameters":{"internal":false,"private":false}}]`,
},
}

Expand Down Expand Up @@ -929,6 +937,17 @@ func TestRepositoryRule(t *testing.T) {
},
`{"type":"code_scanning","parameters":{"code_scanning_tools":[{"alerts_threshold":"all","security_alerts_threshold":"all","tool":"test"},{"alerts_threshold":"none","security_alerts_threshold":"none","tool":"test"}]}}`,
},
{
"copilot_code_review",
&RepositoryRule{
Type: RulesetRuleTypeCopilotCodeReview,
Parameters: &CopilotCodeReviewRuleParameters{
ReviewNewPushes: true,
ReviewDraftPullRequests: false,
},
},
`{"type":"copilot_code_review","parameters":{"review_new_pushes":true,"review_draft_pull_requests":false}}`,
},
{
"repository_create",
&RepositoryRule{Type: RulesetRuleTypeRepositoryCreate, Parameters: nil},
Expand Down
Loading