Repository: google/go-github
Pull request #3233 (2024-08-11 16:49:22)

Add support for filepath repository rules
Fixes: #3231.

This is an attempt to add support for file_path_restriction in repository rules. It will implement #3231 

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/google/go-github/pull/3233?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 92.95%. Comparing base [(`2b8c7fa`)](https://app.codecov.io/gh/google/go-github/commit/2b8c7fa86fcd1cb4a89a44c8e7b5a49fe4be8a45?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) to head [(`ed264f2`)](https://app.codecov.io/gh/google/go-github/commit/ed264f2d1925a69a760195bfd295a09d74be2b46?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).
> Report is 93 commits behind head on master.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #3233      +/-   ##
==========================================
- Coverage   97.72%   92.95%   -4.78%     
==========================================
  Files         153      171      +18     
  Lines       13390    11646    -1744     
==========================================
- Hits        13085    10825    -2260     
- Misses        215      727     +512     
- Partials       90       94       +4     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/google/go-github/pull/3233?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).


Patch:
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 7d4a0782..86d3b286 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -20846,6 +20846,14 @@ func (r *Rule) GetSeverity() string {
 	return *r.Severity
 }
 
+// GetRestrictedFilePaths returns the RestrictedFilePaths field if it's non-nil, zero value otherwise.
+func (r *RuleFileParameters) GetRestrictedFilePaths() []string {
+	if r == nil || r.RestrictedFilePaths == nil {
+		return nil
+	}
+	return *r.RestrictedFilePaths
+}
+
 // GetName returns the Name field if it's non-nil, zero value otherwise.
 func (r *RulePatternParameters) GetName() string {
 	if r == nil || r.Name == nil {
diff --git a/github/orgs_custom_roles.go b/github/orgs_custom_roles.go
index dcbd79ef..ca0c6d7b 100644
--- a/github/orgs_custom_roles.go
+++ b/github/orgs_custom_roles.go
@@ -53,7 +53,7 @@ type CustomRepoRoles struct {
 type CreateOrUpdateOrgRoleOptions struct {
 	Name        *string  `json:"name,omitempty"`
 	Description *string  `json:"description,omitempty"`
-	Permissions []string `json:"permissions,omitempty"`
+	Permissions []string `json:"permissions"`
 }
 
 // CreateOrUpdateCustomRepoRoleOptions represents options required to create or update a custom repository role.
@@ -61,7 +61,7 @@ type CreateOrUpdateCustomRepoRoleOptions struct {
 	Name        *string  `json:"name,omitempty"`
 	Description *string  `json:"description,omitempty"`
 	BaseRole    *string  `json:"base_role,omitempty"`
-	Permissions []string `json:"permissions,omitempty"`
+	Permissions []string `json:"permissions"`
 }
 
 // ListRoles lists the custom roles available in this organization.
diff --git a/github/repos_rules.go b/github/repos_rules.go
index 2827f85a..17fa170c 100644
--- a/github/repos_rules.go
+++ b/github/repos_rules.go
@@ -79,6 +79,11 @@ type RulePatternParameters struct {
 	Pattern  string `json:"pattern"`
 }
 
+// RuleFileParameters represents a list of file paths.
+type RuleFileParameters struct {
+	RestrictedFilePaths *[]string `json:"restricted_file_paths"`
+}
+
 // UpdateAllowsFetchAndMergeRuleParameters represents the update rule parameters.
 type UpdateAllowsFetchAndMergeRuleParameters struct {
 	UpdateAllowsFetchAndMerge bool `json:"update_allows_fetch_and_merge"`
@@ -213,6 +218,15 @@ func (r *RepositoryRule) UnmarshalJSON(data []byte) error {
 		bytes, _ := json.Marshal(params)
 		rawParams := json.RawMessage(bytes)
 
+		r.Parameters = &rawParams
+	case "file_path_restriction":
+		params := RuleFileParameters{}
+		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 = ""
@@ -390,6 +404,18 @@ func NewRequiredWorkflowsRule(params *RequiredWorkflowsRuleParameters) (rule *Re
 	}
 }
 
+// NewFilePathRestrictionRule creates a rule to restrict file paths from being pushed to.
+func NewFilePathRestrictionRule(params *RuleFileParameters) (rule *RepositoryRule) {
+	bytes, _ := json.Marshal(params)
+
+	rawParams := json.RawMessage(bytes)
+
+	return &RepositoryRule{
+		Type:       "file_path_restriction",
+		Parameters: &rawParams,
+	}
+}
+
 // Ruleset represents a GitHub ruleset object.
 type Ruleset struct {
 	ID   *int64 `json:"id,omitempty"`
diff --git a/scrape/go.mod b/scrape/go.mod
index 47692f98..700a000b 100644
--- a/scrape/go.mod
+++ b/scrape/go.mod
@@ -9,7 +9,7 @@ require (
 	github.com/google/go-cmp v0.6.0
 	github.com/google/go-github/v63 v63.0.0
 	github.com/xlzd/gotp v0.1.0
-	golang.org/x/net v0.27.0
+	golang.org/x/net v0.28.0
 )
 
 require (
diff --git a/scrape/go.sum b/scrape/go.sum
index d83a575d..fb5ccf43 100644
--- a/scrape/go.sum
+++ b/scrape/go.sum
@@ -21,8 +21,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
-golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
-golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
+golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
+golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=


Test patch:
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index a401ecc1..11d8a3bf 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -24225,6 +24225,16 @@ func TestRule_GetSeverity(tt *testing.T) {
 	r.GetSeverity()
 }
 
+func TestRuleFileParameters_GetRestrictedFilePaths(tt *testing.T) {
+	var zeroValue []string
+	r := &RuleFileParameters{RestrictedFilePaths: &zeroValue}
+	r.GetRestrictedFilePaths()
+	r = &RuleFileParameters{}
+	r.GetRestrictedFilePaths()
+	r = nil
+	r.GetRestrictedFilePaths()
+}
+
 func TestRulePatternParameters_GetName(tt *testing.T) {
 	var zeroValue string
 	r := &RulePatternParameters{Name: &zeroValue}
diff --git a/github/repos_rules_test.go b/github/repos_rules_test.go
index 065d3385..c338e37e 100644
--- a/github/repos_rules_test.go
+++ b/github/repos_rules_test.go
@@ -182,6 +182,20 @@ func TestRepositoryRule_UnmarshalJSON(t *testing.T) {
 			},
 			wantErr: true,
 		},
+		"Valid file_path_restriction params": {
+			data: `{"type":"file_path_restriction","parameters":{"restricted_file_paths":["/a/file"]}}`,
+			want: NewFilePathRestrictionRule(&RuleFileParameters{
+				RestrictedFilePaths: &[]string{"/a/file"},
+			}),
+		},
+		"Invalid file_path_restriction params": {
+			data: `{"type":"file_path_restriction","parameters":{"restricted_file_paths":true}}`,
+			want: &RepositoryRule{
+				Type:       "file_path_restriction",
+				Parameters: nil,
+			},
+			wantErr: true,
+		},
 		"Valid pull_request params": {
 			data: `{
 				"type":"pull_request",