Skip to content

Commit

Permalink
feat: Implement missing push rules (#3294)
Browse files Browse the repository at this point in the history
Fixes: #3274.
  • Loading branch information
srgustafson8 authored Oct 1, 2024
1 parent cd59fac commit 0024ad2
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 0 deletions.
78 changes: 78 additions & 0 deletions github/repos_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ type RuleFileParameters struct {
RestrictedFilePaths *[]string `json:"restricted_file_paths"`
}

// RuleMaxFilePathLengthParameters represents the max_file_path_length rule parameters.
type RuleMaxFilePathLengthParameters struct {
MaxFilePathLength int `json:"max_file_path_length"`
}

// RuleFileExtensionRestrictionParameters represents the file_extension_restriction rule parameters.
type RuleFileExtensionRestrictionParameters struct {
RestrictedFileExtensions []string `json:"restricted_file_extensions"`
}

// RuleMaxFileSizeParameters represents the max_file_size rule parameters.
type RuleMaxFileSizeParameters struct {
MaxFileSize int64 `json:"max_file_size"`
}

// UpdateAllowsFetchAndMergeRuleParameters represents the update rule parameters.
type UpdateAllowsFetchAndMergeRuleParameters struct {
UpdateAllowsFetchAndMerge bool `json:"update_allows_fetch_and_merge"`
Expand Down Expand Up @@ -255,6 +270,33 @@ func (r *RepositoryRule) UnmarshalJSON(data []byte) error {
bytes, _ := json.Marshal(params)
rawParams := json.RawMessage(bytes)

r.Parameters = &rawParams
case "max_file_path_length":
params := RuleMaxFilePathLengthParameters{}
if err := json.Unmarshal(*RepositoryRule.Parameters, &params); err != nil {
return err
}
bytes, _ := json.Marshal(params)
rawParams := json.RawMessage(bytes)

r.Parameters = &rawParams
case "file_extension_restriction":
params := RuleFileExtensionRestrictionParameters{}
if err := json.Unmarshal(*RepositoryRule.Parameters, &params); err != nil {
return err
}
bytes, _ := json.Marshal(params)
rawParams := json.RawMessage(bytes)

r.Parameters = &rawParams
case "max_file_size":
params := RuleMaxFileSizeParameters{}
if err := json.Unmarshal(*RepositoryRule.Parameters, &params); err != nil {
return err
}
bytes, _ := json.Marshal(params)
rawParams := json.RawMessage(bytes)

r.Parameters = &rawParams
default:
r.Type = ""
Expand Down Expand Up @@ -454,6 +496,42 @@ func NewFilePathRestrictionRule(params *RuleFileParameters) (rule *RepositoryRul
}
}

// NewMaxFilePathLengthRule creates a rule to restrict file paths longer than the limit from being pushed.
func NewMaxFilePathLengthRule(params *RuleMaxFilePathLengthParameters) (rule *RepositoryRule) {
bytes, _ := json.Marshal(params)

rawParams := json.RawMessage(bytes)

return &RepositoryRule{
Type: "max_file_path_length",
Parameters: &rawParams,
}
}

// NewFileExtensionRestrictionRule creates a rule to restrict file extensions from being pushed to a commit.
func NewFileExtensionRestrictionRule(params *RuleFileExtensionRestrictionParameters) (rule *RepositoryRule) {
bytes, _ := json.Marshal(params)

rawParams := json.RawMessage(bytes)

return &RepositoryRule{
Type: "file_extension_restriction",
Parameters: &rawParams,
}
}

// NewMaxFileSizeRule creates a rule to restrict file sizes from being pushed to a commit.
func NewMaxFileSizeRule(params *RuleMaxFileSizeParameters) (rule *RepositoryRule) {
bytes, _ := json.Marshal(params)

rawParams := json.RawMessage(bytes)

return &RepositoryRule{
Type: "max_file_size",
Parameters: &rawParams,
}
}

// Ruleset represents a GitHub ruleset object.
type Ruleset struct {
ID *int64 `json:"id,omitempty"`
Expand Down
130 changes: 130 additions & 0 deletions github/repos_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,48 @@ func TestRepositoryRule_UnmarshalJSON(t *testing.T) {
},
wantErr: true,
},
"Valid max_file_path_length params": {
data: `{"type":"max_file_path_length","parameters":{"max_file_path_length": 255}}`,
want: NewMaxFilePathLengthRule(&RuleMaxFilePathLengthParameters{
MaxFilePathLength: 255,
}),
},
"Invalid max_file_path_length params": {
data: `{"type":"max_file_path_length","parameters":{"max_file_path_length": "255"}}`,
want: &RepositoryRule{
Type: "max_file_path_length",
Parameters: nil,
},
wantErr: true,
},
"Valid file_extension_restriction params": {
data: `{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":[".exe"]}}`,
want: NewFileExtensionRestrictionRule(&RuleFileExtensionRestrictionParameters{
RestrictedFileExtensions: []string{".exe"},
}),
},
"Invalid file_extension_restriction params": {
data: `{"type":"file_extension_restriction","parameters":{"restricted_file_extensions":true}}`,
want: &RepositoryRule{
Type: "file_extension_restriction",
Parameters: nil,
},
wantErr: true,
},
"Valid max_file_size params": {
data: `{"type":"max_file_size","parameters":{"max_file_size": 1024}}`,
want: NewMaxFileSizeRule(&RuleMaxFileSizeParameters{
MaxFileSize: 1024,
}),
},
"Invalid max_file_size params": {
data: `{"type":"max_file_size","parameters":{"max_file_size": "1024"}}`,
want: &RepositoryRule{
Type: "max_file_size",
Parameters: nil,
},
wantErr: true,
},
}

for name, tc := range tests {
Expand Down Expand Up @@ -539,6 +581,94 @@ func TestRepositoriesService_CreateRuleset(t *testing.T) {
})
}

func TestRepositoriesService_CreateRulesetWithPushRules(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()

mux.HandleFunc("/repos/o/repo/rulesets", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
fmt.Fprint(w, `{
"id": 42,
"name": "ruleset",
"source_type": "Repository",
"source": "o/repo",
"enforcement": "enabled",
"target": "push",
"rules": [
{
"type": "file_path_restriction",
"parameters": {
"restricted_file_paths": ["/a/file"]
}
},
{
"type": "max_file_path_length",
"parameters": {
"max_file_path_length": 255
}
},
{
"type": "file_extension_restriction",
"parameters": {
"restricted_file_extensions": [".exe"]
}
},
{
"type": "max_file_size",
"parameters": {
"max_file_size": 1024
}
}
]
}`)
})

ctx := context.Background()
ruleSet, _, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{
Name: "ruleset",
Enforcement: "enabled",
})
if err != nil {
t.Errorf("Repositories.CreateRuleset returned error: %v", err)
}

want := &Ruleset{
ID: Int64(42),
Name: "ruleset",
SourceType: String("Repository"),
Source: "o/repo",
Target: String("push"),
Enforcement: "enabled",
Rules: []*RepositoryRule{
NewFilePathRestrictionRule(&RuleFileParameters{
RestrictedFilePaths: &[]string{"/a/file"},
}),
NewMaxFilePathLengthRule(&RuleMaxFilePathLengthParameters{
MaxFilePathLength: 255,
}),
NewFileExtensionRestrictionRule(&RuleFileExtensionRestrictionParameters{
RestrictedFileExtensions: []string{".exe"},
}),
NewMaxFileSizeRule(&RuleMaxFileSizeParameters{
MaxFileSize: 1024,
}),
},
}
if !cmp.Equal(ruleSet, want) {
t.Errorf("Repositories.CreateRuleset returned %+v, want %+v", ruleSet, want)
}

const methodName = "CreateRuleset"

testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
got, resp, err := client.Repositories.CreateRuleset(ctx, "o", "repo", &Ruleset{})
if got != nil {
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
}
return resp, err
})
}

func TestRepositoriesService_GetRuleset(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()
Expand Down

0 comments on commit 0024ad2

Please sign in to comment.