-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix!: Refactor the repository ruleset code #3430
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3430 +/- ##
==========================================
- Coverage 92.26% 90.98% -1.29%
==========================================
Files 174 175 +1
Lines 15023 15282 +259
==========================================
+ Hits 13861 13904 +43
- Misses 1068 1211 +143
- Partials 94 167 +73 ☔ View full report in Codecov by Sentry. |
Thank you, @stevehipwell ! |
@gmlewis sorry I thought I had run it, but I was making change while reviewing the PR diff so I guess I missed running it for one of the changes. Should be right now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for doing this, @stevehipwell - this cleanup is looking really nice!
Please remember to not force-push, as that will save me a huge amount of time after you address my comments... thanks again!
@gmlewis I've pushed the changes you requested, and remembered to not force push! 🥳 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @stevehipwell !
Just a few more minor concerns, please, if you don't mind.
@gmlewis is there a reason why we're not making the update functions (e.g. |
I'm betting that the original endpoints were poorly named and I didn't catch it. Since this is a fairly significant breaking change, I would say that now is the time in this PR to make the method names actually describe what they are doing. So feel free to make them consistent in your renaming. |
Would this be better as a separate but linked PR? I expect to change the behaviour of the update functions and add patch functions. The standard struct would lose the |
Absolutely, if you don't mind... that sounds great. Thank you, @stevehipwell ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @stevehipwell and thanks also for your patience with my requests for changes... I really appreciate it!
LGTM.
Awaiting second LGTM+Approval from any other contributor to this repo before merging.
@gmlewis and suggestions for who to ask to give this a second review? |
I currently don't have any suggestions for volunteers and I try not to ping people unless it is really important. |
@gmlewis unfortunately I don't have any access to Go devs. I'll wait until I review a PR and ask for the author to return the favour. |
example/verifyartifact/main.go
Outdated
@@ -109,7 +109,6 @@ func main() { | |||
} | |||
|
|||
err := runVerification(sev, pb, b) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please be so kind as to revert this unrelated change? It makes the review process more difficult.
You can use these commands:
git restore --source=master example/verifyartifact/main.go
git commit -a -m "Revert unrelated changes"
Thank you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
github/code_scanning.go
Outdated
@@ -391,7 +391,7 @@ func (s *CodeScanningService) UploadSarif(ctx context.Context, owner, repo strin | |||
return nil, nil, err | |||
} | |||
|
|||
// This will always return an error without unmarshalling the data | |||
// This will always return an error without unmarshaling the data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert unrelated change. It's better to create a separate PR that fixes all unmarshalling
words altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change was explicitly requested by @gmlewis.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And AFAIK it does fix all of the related typos.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a PR to address this #3441
Would you mind a review?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I approved your PR.
github/enterprise_rules.go
Outdated
@@ -76,14 +76,14 @@ func (s *EnterpriseService) UpdateEnterpriseRuleset(ctx context.Context, enterpr | |||
return rs, resp, nil | |||
} | |||
|
|||
// UpdateEnterpriseRulesetClearBypassActor clears the ruleset bypass actors for a ruleset for the specified repository. | |||
// UpdateRepositoryRulesetClearBypassActor clears the bypass actors for a repository ruleset for the specified enterprise. | |||
// | |||
// This function is necessary as the UpdateEnterpriseRuleset function does not marshal ByPassActor if passed as an empty array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should change the comment after renaming:
// This function is necessary as the UpdateEnterpriseRuleset function does not marshal ByPassActor if passed as an empty array. | |
// This function is necessary as the UpdateRepositoryRuleset function does not marshal ByPassActor if passed as an empty array. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot, fixed.
github/event_types_test.go
Outdated
event *RepositoryRulesetEvent | ||
}{ | ||
{"empty", `{}`, &RepositoryRulesetEvent{}}, | ||
{"created", fmt.Sprintf(`{"action":"created","repository_ruleset":{"id":1,"name":"r","target":"branch","source_type":"Repository","source":"o/r","enforcement":"active","conditions":{"ref_name":{"exclude":[],"include":["~ALL"]}},"rules":[{"type":"deletion"},{"type":"creation"},{"type":"update"},{"type":"required_linear_history"},{"type":"pull_request","parameters":{"required_approving_review_count":2,"dismiss_stale_reviews_on_push":false,"require_code_owner_review":false,"require_last_push_approval":false,"required_review_thread_resolution":false,"automatic_copilot_code_review_enabled":false,"allowed_merge_methods":["squash","rebase","merge"]}},{"type":"code_scanning","parameters":{"code_scanning_tools":[{"tool":"CodeQL","security_alerts_threshold":"high_or_higher","alerts_threshold":"errors"}]}}],"node_id":"n","created_at":%[1]s,"updated_at":%[1]s,"_links":{"self":{"href":"a"},"html":{"href":"a"}}},"repository":{"id":1,"node_id":"n","name":"r","full_name":"o/r"},"organization":{"id":1,"node_id":"n","name":"o"},"enterprise":{"id":1,"node_id":"n","slug":"e","name":"e"},"installation":{"id":1,"node_id":"n","app_id":1,"app_slug":"a"},"sender":{"id":1,"node_id":"n","login":"l"}}`, referenceTimeStr), &RepositoryRulesetEvent{Action: Ptr("created"), RepositoryRuleset: &RepositoryRuleset{ID: Ptr(int64(1)), Name: "r", Target: Ptr(RulesetTargetBranch), SourceType: Ptr(RulesetSourceTypeRepository), Source: "o/r", Enforcement: RulesetEnforcementActive, Conditions: &RepositoryRulesetConditions{RefName: &RepositoryRulesetRefConditionParameters{Include: []string{"~ALL"}, Exclude: []string{}}}, Rules: &RepositoryRulesetRules{Creation: &EmptyRuleParameters{}, Update: &UpdateRuleParameters{}, Deletion: &EmptyRuleParameters{}, RequiredLinearHistory: &EmptyRuleParameters{}, PullRequest: &PullRequestRuleParameters{AllowedMergeMethods: []MergeMethod{MergeMethodSquash, MergeMethodRebase, MergeMethodMerge}, DismissStaleReviewsOnPush: false, RequireCodeOwnerReview: false, RequireLastPushApproval: false, RequiredApprovingReviewCount: 2, RequiredReviewThreadResolution: false}, CodeScanning: &CodeScanningRuleParameters{CodeScanningTools: []*RuleCodeScanningTool{{AlertsThreshold: CodeScanningAlertsThresholdErrors, SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdHighOrHigher, Tool: "CodeQL"}}}}, NodeID: Ptr("n"), CreatedAt: &Timestamp{referenceTime}, UpdatedAt: &Timestamp{referenceTime}, Links: &RepositoryRulesetLinks{Self: &RepositoryRulesetLink{HRef: Ptr("a")}, HTML: &RepositoryRulesetLink{HRef: Ptr("a")}}}, Repository: repository, Organization: organization, Enterprise: enterprise, Installation: installation, Sender: sender}}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line contains 2668 characters, which may make it difficult to edit in the future as fields change. Could you please format the JSON as it is done in the other tests in this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexandear I'm going to have to disagree with you on this. As the tests should be tightly coupled with the JSON string it makes the most sense to make the JSON format as clear and unambiguous as possible. Therefore the compact representation is the obvious choice. If you want to edit the JSON it's going to be much easier to do so by copying the string and working on it as actual JSON (jq -c '.'
will then format the JSON to be pasted back).
Please note that this test doesn't use testJSONMarshal
like the other tests; that helper function can (and does) mask incorrect JSON by depending on the very marshaling code that's under test to format the JSON string.
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
efa2b7d
to
6971bef
Compare
github/rules_test.go
Outdated
{"empty", &RepositoryRulesetRules{}, `[]`}, | ||
{"single_rule_with_empty_params", &RepositoryRulesetRules{Creation: &EmptyRuleParameters{}}, `[{"type":"creation"}]`}, | ||
{"single_rule_with_required_params", &RepositoryRulesetRules{RequiredDeployments: &RequiredDeploymentsRuleParameters{RequiredDeploymentEnvironments: []string{"test"}}}, `[{"type":"required_deployments","parameters":{"required_deployment_environments":["test"]}}]`}, | ||
{"all_rules_with_required_params", &RepositoryRulesetRules{Creation: &EmptyRuleParameters{}, Update: &UpdateRuleParameters{}, Deletion: &EmptyRuleParameters{}, RequiredLinearHistory: &EmptyRuleParameters{}, MergeQueue: &MergeQueueRuleParameters{CheckResponseTimeoutMinutes: 5, GroupingStrategy: MergeGroupingStrategyAllGreen, MaxEntriesToBuild: 10, MaxEntriesToMerge: 20, MergeMethod: MergeMethodSquash, MinEntriesToMerge: 1, MinEntriesToMergeWaitMinutes: 15}, RequiredDeployments: &RequiredDeploymentsRuleParameters{RequiredDeploymentEnvironments: []string{"test1", "test2"}}, RequiredSignatures: &EmptyRuleParameters{}, PullRequest: &PullRequestRuleParameters{AllowedMergeMethods: []MergeMethod{MergeMethodSquash, MergeMethodRebase}, DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 2, RequiredReviewThreadResolution: true}, RequiredStatusChecks: &RequiredStatusChecksRuleParameters{RequiredStatusChecks: []*RuleStatusCheck{{Context: "test1"}, {Context: "test2"}}, StrictRequiredStatusChecksPolicy: true}, NonFastForward: &EmptyRuleParameters{}, CommitMessagePattern: &PatternRuleParameters{Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, CommitAuthorEmailPattern: &PatternRuleParameters{Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, CommitterEmailPattern: &PatternRuleParameters{Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, BranchNamePattern: &PatternRuleParameters{Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, TagNamePattern: &PatternRuleParameters{Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, FilePathRestriction: &FilePathRestrictionRuleParameters{RestrictedFilePaths: []string{"test1", "test2"}}, MaxFilePathLength: &MaxFilePathLengthRuleParameters{MaxFilePathLength: 512}, FileExtensionRestriction: &FileExtensionRestrictionRuleParameters{RestrictedFileExtensions: []string{".exe", ".pkg"}}, MaxFileSize: &MaxFileSizeRuleParameters{MaxFileSize: 1024}, Workflows: &WorkflowsRuleParameters{Workflows: []*RuleWorkflow{{Path: ".github/workflows/test1.yaml"}, {Path: ".github/workflows/test2.yaml"}}}, CodeScanning: &CodeScanningRuleParameters{CodeScanningTools: []*RuleCodeScanningTool{{AlertsThreshold: CodeScanningAlertsThresholdAll, SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdAll, Tool: "test"}, {AlertsThreshold: CodeScanningAlertsThresholdNone, SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdNone, Tool: "test"}}}}, `[{"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"}]}}]`}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it's a good idea to put everything into one line.
Compare your variant:
{"all_rules_with_all_params", &RepositoryRulesetRules{Creation: &EmptyRuleParameters{}, Update: &UpdateRuleParameters{UpdateAllowsFetchAndMerge: true}, Deletion: &EmptyRuleParameters{}, RequiredLinearHistory: &EmptyRuleParameters{}, MergeQueue: &MergeQueueRuleParameters{CheckResponseTimeoutMinutes: 5, GroupingStrategy: MergeGroupingStrategyAllGreen, MaxEntriesToBuild: 10, MaxEntriesToMerge: 20, MergeMethod: MergeMethodSquash, MinEntriesToMerge: 1, MinEntriesToMergeWaitMinutes: 15}, RequiredDeployments: &RequiredDeploymentsRuleParameters{RequiredDeploymentEnvironments: []string{"test1", "test2"}}, RequiredSignatures: &EmptyRuleParameters{}, PullRequest: &PullRequestRuleParameters{AllowedMergeMethods: []MergeMethod{MergeMethodSquash, MergeMethodRebase}, DismissStaleReviewsOnPush: true, RequireCodeOwnerReview: true, RequireLastPushApproval: true, RequiredApprovingReviewCount: 2, RequiredReviewThreadResolution: true}, RequiredStatusChecks: &RequiredStatusChecksRuleParameters{DoNotEnforceOnCreate: Ptr(true), RequiredStatusChecks: []*RuleStatusCheck{{Context: "test1", IntegrationID: Ptr(int64(1))}, {Context: "test2", IntegrationID: Ptr(int64(2))}}, StrictRequiredStatusChecksPolicy: true}, NonFastForward: &EmptyRuleParameters{}, CommitMessagePattern: &PatternRuleParameters{Name: Ptr("cmp"), Negate: Ptr(false), Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, CommitAuthorEmailPattern: &PatternRuleParameters{Name: Ptr("caep"), Negate: Ptr(false), Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, CommitterEmailPattern: &PatternRuleParameters{Name: Ptr("cep"), Negate: Ptr(false), Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, BranchNamePattern: &PatternRuleParameters{Name: Ptr("bp"), Negate: Ptr(false), Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, TagNamePattern: &PatternRuleParameters{Name: Ptr("tp"), Negate: Ptr(false), Operator: PatternRuleOperatorStartsWith, Pattern: "test"}, FilePathRestriction: &FilePathRestrictionRuleParameters{RestrictedFilePaths: []string{"test1", "test2"}}, MaxFilePathLength: &MaxFilePathLengthRuleParameters{MaxFilePathLength: 512}, FileExtensionRestriction: &FileExtensionRestrictionRuleParameters{RestrictedFileExtensions: []string{".exe", ".pkg"}}, MaxFileSize: &MaxFileSizeRuleParameters{MaxFileSize: 1024}, Workflows: &WorkflowsRuleParameters{DoNotEnforceOnCreate: Ptr(true), Workflows: []*RuleWorkflow{{Path: ".github/workflows/test1.yaml", Ref: Ptr("main"), RepositoryID: Ptr(int64(1)), SHA: Ptr("aaaa")}, {Path: ".github/workflows/test2.yaml", Ref: Ptr("main"), RepositoryID: Ptr(int64(2)), SHA: Ptr("bbbb")}}}, CodeScanning: &CodeScanningRuleParameters{CodeScanningTools: []*RuleCodeScanningTool{{AlertsThreshold: CodeScanningAlertsThresholdAll, SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdAll, Tool: "test"}, {AlertsThreshold: CodeScanningAlertsThresholdNone, SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdNone, Tool: "test"}}}}, `[{"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"],"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"}]}}]`},
with mine:
{
"all_rules_with_all_params",
&RepositoryRulesetRules{
Creation: &EmptyRuleParameters{},
Update: &UpdateRuleParameters{UpdateAllowsFetchAndMerge: true},
Deletion: &EmptyRuleParameters{},
RequiredLinearHistory: &EmptyRuleParameters{},
MergeQueue: &MergeQueueRuleParameters{
CheckResponseTimeoutMinutes: 5,
GroupingStrategy: MergeGroupingStrategyAllGreen,
MaxEntriesToBuild: 10,
MaxEntriesToMerge: 20,
MergeMethod: MergeMethodSquash,
MinEntriesToMerge: 1,
MinEntriesToMergeWaitMinutes: 15,
},
RequiredDeployments: &RequiredDeploymentsRuleParameters{
RequiredDeploymentEnvironments: []string{"test1", "test2"},
},
RequiredSignatures: &EmptyRuleParameters{},
PullRequest: &PullRequestRuleParameters{
AllowedMergeMethods: []MergeMethod{
MergeMethodSquash,
MergeMethodRebase,
},
DismissStaleReviewsOnPush: true,
RequireCodeOwnerReview: true,
RequireLastPushApproval: true,
RequiredApprovingReviewCount: 2,
RequiredReviewThreadResolution: true,
},
RequiredStatusChecks: &RequiredStatusChecksRuleParameters{
DoNotEnforceOnCreate: Ptr(true),
RequiredStatusChecks: []*RuleStatusCheck{
{Context: "test1", IntegrationID: Ptr(int64(1))},
{Context: "test2", IntegrationID: Ptr(int64(2))},
},
StrictRequiredStatusChecksPolicy: true,
},
NonFastForward: &EmptyRuleParameters{},
CommitMessagePattern: &PatternRuleParameters{
Name: Ptr("cmp"),
Negate: Ptr(false),
Operator: PatternRuleOperatorStartsWith,
Pattern: "test",
},
CommitAuthorEmailPattern: &PatternRuleParameters{
Name: Ptr("caep"),
Negate: Ptr(false),
Operator: PatternRuleOperatorStartsWith,
Pattern: "test",
},
CommitterEmailPattern: &PatternRuleParameters{
Name: Ptr("cep"),
Negate: Ptr(false),
Operator: PatternRuleOperatorStartsWith,
Pattern: "test",
},
BranchNamePattern: &PatternRuleParameters{
Name: Ptr("bp"),
Negate: Ptr(false),
Operator: PatternRuleOperatorStartsWith,
Pattern: "test",
},
TagNamePattern: &PatternRuleParameters{
Name: Ptr("tp"),
Negate: Ptr(false),
Operator: PatternRuleOperatorStartsWith,
Pattern: "test",
},
FilePathRestriction: &FilePathRestrictionRuleParameters{
RestrictedFilePaths: []string{"test1", "test2"},
},
MaxFilePathLength: &MaxFilePathLengthRuleParameters{MaxFilePathLength: 512},
FileExtensionRestriction: &FileExtensionRestrictionRuleParameters{
RestrictedFileExtensions: []string{".exe", ".pkg"},
},
MaxFileSize: &MaxFileSizeRuleParameters{MaxFileSize: 1024},
Workflows: &WorkflowsRuleParameters{
DoNotEnforceOnCreate: Ptr(true),
Workflows: []*RuleWorkflow{
{
Path: ".github/workflows/test1.yaml",
Ref: Ptr("main"),
RepositoryID: Ptr(int64(1)),
SHA: Ptr("aaaa"),
},
{
Path: ".github/workflows/test2.yaml",
Ref: Ptr("main"),
RepositoryID: Ptr(int64(2)),
SHA: Ptr("bbbb"),
},
},
},
CodeScanning: &CodeScanningRuleParameters{
CodeScanningTools: []*RuleCodeScanningTool{
{
AlertsThreshold: CodeScanningAlertsThresholdAll,
SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdAll,
Tool: "test",
},
{
AlertsThreshold: CodeScanningAlertsThresholdNone,
SecurityAlertsThreshold: CodeScanningSecurityAlertsThresholdNone,
Tool: "test",
},
},
},
},
`[{"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"],"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"}]}}]`,
},
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use golines to automatically format long lines.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the objects I agree with you, I'll make these multi line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks for the pointer to golines
.
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @stevehipwell!
LGTM.
Awaiting second LGTM+Approval from any other contributor to this repo before merging.
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
@gmlewis I've added another test to try and improve the code coverage numbers. |
github/rules.go
Outdated
// If new rules are added to RulesetRules the capacity needs increasing | ||
arr := make([]repositoryRulesetRuleWrapper, 0, 21) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I propose to simplify:
// If new rules are added to RulesetRules the capacity needs increasing | |
arr := make([]repositoryRulesetRuleWrapper, 0, 21) | |
var arr []repositoryRulesetRuleWrapper |
I'm not sure if we get a significant performance improvement by preallocating the slice here.
The similar for RepositoryRulesetRules.MarshalJSON
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can rename arr
to wrappers
.
arr
suggests an array, but []repositoryRulesetRuleWrapper
is a slice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to rename arr
to wrappers
, and I will. However I can't see a benefit for removing the make()
, call but I can see a number of downsides including both performance and clarity.
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
@gmlewis what are your thoughts on the coverage here? The new untested lines are basically the error block for the JSON marshaling code and adding coverage for these would be very verbose but not impossible. |
Exactly right - that part of the code is marshaling and unmarshaling the JSON so the coverage tests would need to attempt to provide input to the functions with either bad structs (challenging) or bad JSON (e.g. |
@@ -480,177 +480,177 @@ type repositoryRulesetRuleWrapper struct { | |||
// MarshalJSON is a custom JSON marshaler for RulesetRules. | |||
func (r *RepositoryRulesetRules) MarshalJSON() ([]byte, error) { | |||
// If new rules are added to RulesetRules the capacity needs increasing | |||
arr := make([]json.RawMessage, 0, 21) | |||
rawRules := make([]json.RawMessage, 0, 21) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add a comment here as to why 21
was chosen for the capacity, for the benefit of the maintainers and developers?
If it is completely arbitrary, then please remove it entirely, as that is not idiomatic Go.
The Go team has gone to extensive lengths with benchmarking to make the defaults very reasonable, and if you don't have a good reason for the capacity, then it is not only distracting, but makes the code harder to read and understand, which also violates idiomatic Go, as one of the whole points of Go's design is that it should be super-easy to read and understand.
Therefore, if it is arbitrary, it is idiomatic Go to always take advantage of the zero-value of a type when its initial value is not the focus of the code. Therefore, this would simply be:
var rawRules []json.RawMessage
Short, sweet, and does not distract the reader into thinking there is something special going on here.
In fact, the comment on 482 is also distracting and reader-time-consuming, in my opinion, if there is nothing special going on here.
However, once again, if the 21
IS important (it is not obvious to me how it possibly could be), then change the comment on 482 to explain why 21
is important. Otherwise, this is just a magic number:
https://en.wikipedia.org/wiki/Magic_number_(programming)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add a comment, but basically there will always be between 1 and 21 items in the slice due to the GitHub data model. My understanding was that if you had prior knowledge on the size of a Go array/slice that you should explicitly set it? If I'm incorrectly informed in this case I'll happily remove the make()
call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, fine, then please change the comment. Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed 2 of the 3 cases as they were incorrect and improved the comment for the case where I think it's worth setting the capacity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Requesting change to remove magic number.
Thank you, @alexandear for your review! |
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
@gmlewis hopefully this is ready for final review now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why aren't your wrappers all slices of pointers to structs?
Unless you have a good reason, they should be.
github/rules.go
Outdated
|
||
// UnmarshalJSON is a custom JSON unmarshaler for BranchRules. | ||
func (r *BranchRules) UnmarshalJSON(data []byte) error { | ||
var wrappers []branchRuleWrapper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var wrappers []branchRuleWrapper | |
var wrappers []*branchRuleWrapper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed now.
github/rules.go
Outdated
|
||
// UnmarshalJSON is a custom JSON unmarshaler for RulesetRules. | ||
func (r *RepositoryRulesetRules) UnmarshalJSON(data []byte) error { | ||
var wrappers []repositoryRulesetRuleWrapper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
var wrappers []repositoryRulesetRuleWrapper | |
var wrappers []*repositoryRulesetRuleWrapper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed now.
Signed-off-by: Steve Hipwell <steve.hipwell@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @stevehipwell and @alexandear!
LGTM
Merging.
This PR refactors the repository ruleset functionality to make is consistent, the following items are the big picture changes.
RepositoryRuleset
type in both the REST API and eventsjson.RawMessage
field when the actual type is knownRepositoryRulesetRules
to represent the ruleset rules in a strongly typed way (this could be swapped to[]RepositoryRulesetRule
with the type data still present behind anany
)BranchRules
to represent the rules for a branch in a strongly typed way (this could be swapped to[]BranchRule
with the type data still present behind anany
)BREAKING CHANGES: The following types have been renamed:
Ruleset
->RepositoryRuleset
RulesetLink
->RepositoryRulesetLink
RulesetLinks
->RepositoryRulesetLinks
RulesetRefConditionParameters
->RepositoryRulesetRefConditionParameters
RulesetRepositoryNamesConditionParameters
->RepositoryRulesetRepositoryNamesConditionParameters
RulesetRepositoryIDsConditionParameters
->RepositoryRulesetRepositoryIDsConditionParameters
RulesetRepositoryPropertyTargetParameters
->Repository
RulesetRepositoryPropertyConditionParameters
->RepositoryRulesetRepositoryPropertyConditionParameters
RulesetOrganizationNamesConditionParameters
->RepositoryRulesetOrganizationNamesConditionParameters
RulesetOrganizationIDsConditionParameters
->RepositoryRulesetOrganizationIDsConditionParameters
RulesetConditions
->RepositoryRulesetConditions
RepositoryRulesetEditedChanges
->RepositoryRulesetChanges
RepositoryRulesetEditedSource
->RepositoryRulesetChangeSource
RepositoryRulesetEditedSources
->RepositoryRulesetChangeSources
RepositoryRulesetEditedConditions
->RepositoryRulesetUpdatedConditions
RepositoryRulesetUpdatedConditionsEdited
->RepositoryRulesetUpdatedCondition
RepositoryRulesetEditedRules
->RepositoryRulesetChangedRules
RepositoryRulesetUpdatedRules
->RepositoryRulesetUpdatedRules
RepositoryRulesetEditedRuleChanges
->RepositoryRulesetChangedRule
Fixes: #3429.
@gmlewis this PR adds the the breaking changes in #3417. The event changes have been tested with real world data. I'm happy to discuss any of the changes.