Skip to content

Commit 0024ad2

Browse files
authored
feat: Implement missing push rules (#3294)
Fixes: #3274.
1 parent cd59fac commit 0024ad2

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed

github/repos_rules.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ type RuleFileParameters struct {
8585
RestrictedFilePaths *[]string `json:"restricted_file_paths"`
8686
}
8787

88+
// RuleMaxFilePathLengthParameters represents the max_file_path_length rule parameters.
89+
type RuleMaxFilePathLengthParameters struct {
90+
MaxFilePathLength int `json:"max_file_path_length"`
91+
}
92+
93+
// RuleFileExtensionRestrictionParameters represents the file_extension_restriction rule parameters.
94+
type RuleFileExtensionRestrictionParameters struct {
95+
RestrictedFileExtensions []string `json:"restricted_file_extensions"`
96+
}
97+
98+
// RuleMaxFileSizeParameters represents the max_file_size rule parameters.
99+
type RuleMaxFileSizeParameters struct {
100+
MaxFileSize int64 `json:"max_file_size"`
101+
}
102+
88103
// UpdateAllowsFetchAndMergeRuleParameters represents the update rule parameters.
89104
type UpdateAllowsFetchAndMergeRuleParameters struct {
90105
UpdateAllowsFetchAndMerge bool `json:"update_allows_fetch_and_merge"`
@@ -255,6 +270,33 @@ func (r *RepositoryRule) UnmarshalJSON(data []byte) error {
255270
bytes, _ := json.Marshal(params)
256271
rawParams := json.RawMessage(bytes)
257272

273+
r.Parameters = &rawParams
274+
case "max_file_path_length":
275+
params := RuleMaxFilePathLengthParameters{}
276+
if err := json.Unmarshal(*RepositoryRule.Parameters, &params); err != nil {
277+
return err
278+
}
279+
bytes, _ := json.Marshal(params)
280+
rawParams := json.RawMessage(bytes)
281+
282+
r.Parameters = &rawParams
283+
case "file_extension_restriction":
284+
params := RuleFileExtensionRestrictionParameters{}
285+
if err := json.Unmarshal(*RepositoryRule.Parameters, &params); err != nil {
286+
return err
287+
}
288+
bytes, _ := json.Marshal(params)
289+
rawParams := json.RawMessage(bytes)
290+
291+
r.Parameters = &rawParams
292+
case "max_file_size":
293+
params := RuleMaxFileSizeParameters{}
294+
if err := json.Unmarshal(*RepositoryRule.Parameters, &params); err != nil {
295+
return err
296+
}
297+
bytes, _ := json.Marshal(params)
298+
rawParams := json.RawMessage(bytes)
299+
258300
r.Parameters = &rawParams
259301
default:
260302
r.Type = ""
@@ -454,6 +496,42 @@ func NewFilePathRestrictionRule(params *RuleFileParameters) (rule *RepositoryRul
454496
}
455497
}
456498

499+
// NewMaxFilePathLengthRule creates a rule to restrict file paths longer than the limit from being pushed.
500+
func NewMaxFilePathLengthRule(params *RuleMaxFilePathLengthParameters) (rule *RepositoryRule) {
501+
bytes, _ := json.Marshal(params)
502+
503+
rawParams := json.RawMessage(bytes)
504+
505+
return &RepositoryRule{
506+
Type: "max_file_path_length",
507+
Parameters: &rawParams,
508+
}
509+
}
510+
511+
// NewFileExtensionRestrictionRule creates a rule to restrict file extensions from being pushed to a commit.
512+
func NewFileExtensionRestrictionRule(params *RuleFileExtensionRestrictionParameters) (rule *RepositoryRule) {
513+
bytes, _ := json.Marshal(params)
514+
515+
rawParams := json.RawMessage(bytes)
516+
517+
return &RepositoryRule{
518+
Type: "file_extension_restriction",
519+
Parameters: &rawParams,
520+
}
521+
}
522+
523+
// NewMaxFileSizeRule creates a rule to restrict file sizes from being pushed to a commit.
524+
func NewMaxFileSizeRule(params *RuleMaxFileSizeParameters) (rule *RepositoryRule) {
525+
bytes, _ := json.Marshal(params)
526+
527+
rawParams := json.RawMessage(bytes)
528+
529+
return &RepositoryRule{
530+
Type: "max_file_size",
531+
Parameters: &rawParams,
532+
}
533+
}
534+
457535
// Ruleset represents a GitHub ruleset object.
458536
type Ruleset struct {
459537
ID *int64 `json:"id,omitempty"`

github/repos_rules_test.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,48 @@ func TestRepositoryRule_UnmarshalJSON(t *testing.T) {
312312
},
313313
wantErr: true,
314314
},
315+
"Valid max_file_path_length params": {
316+
data: `{"type":"max_file_path_length","parameters":{"max_file_path_length": 255}}`,
317+
want: NewMaxFilePathLengthRule(&RuleMaxFilePathLengthParameters{
318+
MaxFilePathLength: 255,
319+
}),
320+
},
321+
"Invalid max_file_path_length params": {
322+
data: `{"type":"max_file_path_length","parameters":{"max_file_path_length": "255"}}`,
323+
want: &RepositoryRule{
324+
Type: "max_file_path_length",
325+
Parameters: nil,
326+
},
327+
wantErr: true,
328+
},
329+
"Valid file_extension_restriction params": {
330+
data: `{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":[".exe"]}}`,
331+
want: NewFileExtensionRestrictionRule(&RuleFileExtensionRestrictionParameters{
332+
RestrictedFileExtensions: []string{".exe"},
333+
}),
334+
},
335+
"Invalid file_extension_restriction params": {
336+
data: `{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":true}}`,
337+
want: &RepositoryRule{
338+
Type: "file_extension_restriction",
339+
Parameters: nil,
340+
},
341+
wantErr: true,
342+
},
343+
"Valid max_file_size params": {
344+
data: `{"type":"max_file_size","parameters":{"max_file_size": 1024}}`,
345+
want: NewMaxFileSizeRule(&RuleMaxFileSizeParameters{
346+
MaxFileSize: 1024,
347+
}),
348+
},
349+
"Invalid max_file_size params": {
350+
data: `{"type":"max_file_size","parameters":{"max_file_size": "1024"}}`,
351+
want: &RepositoryRule{
352+
Type: "max_file_size",
353+
Parameters: nil,
354+
},
355+
wantErr: true,
356+
},
315357
}
316358

317359
for name, tc := range tests {
@@ -539,6 +581,94 @@ func TestRepositoriesService_CreateRuleset(t *testing.T) {
539581
})
540582
}
541583

584+
func TestRepositoriesService_CreateRulesetWithPushRules(t *testing.T) {
585+
client, mux, _, teardown := setup()
586+
defer teardown()
587+
588+
mux.HandleFunc("/repos/o/repo/rulesets", func(w http.ResponseWriter, r *http.Request) {
589+
testMethod(t, r, "POST")
590+
fmt.Fprint(w, `{
591+
"id": 42,
592+
"name": "ruleset",
593+
"source_type": "Repository",
594+
"source": "o/repo",
595+
"enforcement": "enabled",
596+
"target": "push",
597+
"rules": [
598+
{
599+
"type": "file_path_restriction",
600+
"parameters": {
601+
"restricted_file_paths": ["/a/file"]
602+
}
603+
},
604+
{
605+
"type": "max_file_path_length",
606+
"parameters": {
607+
"max_file_path_length": 255
608+
}
609+
},
610+
{
611+
"type": "file_extension_restriction",
612+
"parameters": {
613+
"restricted_file_extensions": [".exe"]
614+
}
615+
},
616+
{
617+
"type": "max_file_size",
618+
"parameters": {
619+
"max_file_size": 1024
620+
}
621+
}
622+
]
623+
}`)
624+
})
625+
626+
ctx := context.Background()
627+
ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{
628+
Name: "ruleset",
629+
Enforcement: "enabled",
630+
})
631+
if err != nil {
632+
t.Errorf("Repositories.CreateRuleset returned error: %v", err)
633+
}
634+
635+
want := &Ruleset{
636+
ID: Int64(42),
637+
Name: "ruleset",
638+
SourceType: String("Repository"),
639+
Source: "o/repo",
640+
Target: String("push"),
641+
Enforcement: "enabled",
642+
Rules: []*RepositoryRule{
643+
NewFilePathRestrictionRule(&RuleFileParameters{
644+
RestrictedFilePaths: &[]string{"/a/file"},
645+
}),
646+
NewMaxFilePathLengthRule(&RuleMaxFilePathLengthParameters{
647+
MaxFilePathLength: 255,
648+
}),
649+
NewFileExtensionRestrictionRule(&RuleFileExtensionRestrictionParameters{
650+
RestrictedFileExtensions: []string{".exe"},
651+
}),
652+
NewMaxFileSizeRule(&RuleMaxFileSizeParameters{
653+
MaxFileSize: 1024,
654+
}),
655+
},
656+
}
657+
if !cmp.Equal(ruleSet, want) {
658+
t.Errorf("Repositories.CreateRuleset returned %+v, want %+v", ruleSet, want)
659+
}
660+
661+
const methodName = "CreateRuleset"
662+
663+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
664+
got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{})
665+
if got != nil {
666+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
667+
}
668+
return resp, err
669+
})
670+
}
671+
542672
func TestRepositoriesService_GetRuleset(t *testing.T) {
543673
client, mux, _, teardown := setup()
544674
defer teardown()

0 commit comments

Comments
 (0)