From 12f91bc22a39f820edfa2862d48c90b4bbee6e7e Mon Sep 17 00:00:00 2001 From: Dennis Webb Date: Thu, 5 Oct 2017 08:19:13 -0500 Subject: [PATCH 1/2] Adds RequireCodeOwnerReviews to PullRequestReviewsEnforcement GitHub.com support page about feature https://developer.github.com/v3/repos/branches/#update-branch-protection --- github/repos.go | 10 ++++++++++ github/repos_test.go | 17 +++++++++++------ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/github/repos.go b/github/repos.go index b6d98cc1623..99aafba749e 100644 --- a/github/repos.go +++ b/github/repos.go @@ -562,6 +562,8 @@ type PullRequestReviewsEnforcement struct { DismissalRestrictions DismissalRestrictions `json:"dismissal_restrictions"` // Specifies if approved reviews are dismissed automatically, when a new commit is pushed. DismissStaleReviews bool `json:"dismiss_stale_reviews"` + // Specifies if an approved review is required in pull requests including files with a designated code owner. + RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` } // PullRequestReviewsEnforcementRequest represents request to set the pull request review @@ -572,6 +574,8 @@ type PullRequestReviewsEnforcementRequest struct { DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"` // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required) DismissStaleReviews bool `json:"dismiss_stale_reviews"` + // Specifies if an approved review is required in pull requests including files with a designated code owner. + RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` } // MarshalJSON implements the json.Marshaler interface. @@ -581,18 +585,22 @@ func (req PullRequestReviewsEnforcementRequest) MarshalJSON() ([]byte, error) { newReq := struct { R []interface{} `json:"dismissal_restrictions"` D bool `json:"dismiss_stale_reviews"` + O bool `json:"require_code_owner_reviews"` }{ R: []interface{}{}, D: req.DismissStaleReviews, + O: req.RequireCodeOwnerReviews, } return json.Marshal(newReq) } newReq := struct { R *DismissalRestrictionsRequest `json:"dismissal_restrictions"` D bool `json:"dismiss_stale_reviews"` + O bool `json:"require_code_owner_reviews"` }{ R: req.DismissalRestrictionsRequest, D: req.DismissStaleReviews, + O: req.RequireCodeOwnerReviews, } return json.Marshal(newReq) } @@ -605,6 +613,8 @@ type PullRequestReviewsEnforcementUpdate struct { DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be omitted. DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` + // Specifies if an approved review is required in pull requests including files with a designated code owner. + RequireCodeOwnerReviews bool `json:"require_code_owner_reviews,omitempty"` } // AdminEnforcement represents the configuration to enforce required status checks for repository administrators. diff --git a/github/repos_test.go b/github/repos_test.go index 1f7b424f2f7..0f0401ce07d 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -518,7 +518,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { testMethod(t, r, "GET") testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"required_status_checks":{"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"u"}],"teams":[{"id":4,"slug":"t"}]},"dismiss_stale_reviews":true},"enforce_admins":{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) + fmt.Fprintf(w, `{"required_status_checks":{"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"u"}],"teams":[{"id":4,"slug":"t"}]},"dismiss_stale_reviews":true,"require_code_owner_reviews":true},"enforce_admins":{"url":"/repos/o/r/branches/b/protection/enforce_admins","enabled":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) }) protection, _, err := client.Repositories.GetBranchProtection(context.Background(), "o", "r", "b") @@ -541,6 +541,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) { {Slug: String("t"), ID: Int(4)}, }, }, + RequireCodeOwnerReviews: true, }, EnforceAdmins: &AdminEnforcement{ URL: String("/repos/o/r/branches/b/protection/enforce_admins"), @@ -591,7 +592,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { t.Errorf("Request body = %+v, want %+v", v, input) } testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"required_status_checks":{"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"uu"}],"teams":[{"id":4,"slug":"tt"}]},"dismiss_stale_reviews":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) + fmt.Fprintf(w, `{"required_status_checks":{"strict":true,"contexts":["continuous-integration"]},"required_pull_request_reviews":{"dismissal_restrictions":{"users":[{"id":3,"login":"uu"}],"teams":[{"id":4,"slug":"tt"}]},"dismiss_stale_reviews":true,"require_code_owner_reviews":true},"restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]}}`) }) protection, _, err := client.Repositories.UpdateBranchProtection(context.Background(), "o", "r", "b", input) @@ -614,6 +615,7 @@ func TestRepositoriesService_UpdateBranchProtection(t *testing.T) { {Slug: String("tt"), ID: Int(4)}, }, }, + RequireCodeOwnerReviews: true, }, Restrictions: &BranchRestrictions{ Users: []*User{ @@ -739,7 +741,7 @@ func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { mux.HandleFunc("/repos/o/r/branches/b/protection/required_pull_request_reviews", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]},"dismiss_stale_reviews":true}`) + fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]},"dismiss_stale_reviews":true,"require_code_owner_reviews":true}`) }) enforcement, _, err := client.Repositories.GetPullRequestReviewEnforcement(context.Background(), "o", "r", "b") @@ -757,6 +759,7 @@ func TestRepositoriesService_GetPullRequestReviewEnforcement(t *testing.T) { {Slug: String("t"), ID: Int(2)}, }, }, + RequireCodeOwnerReviews: true, } if !reflect.DeepEqual(enforcement, want) { @@ -784,7 +787,7 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { t.Errorf("Request body = %+v, want %+v", v, input) } testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) - fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]},"dismiss_stale_reviews":true}`) + fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[{"id":1,"login":"u"}],"teams":[{"id":2,"slug":"t"}]},"dismiss_stale_reviews":true,"require_code_owner_reviews":true}`) }) enforcement, _, err := client.Repositories.UpdatePullRequestReviewEnforcement(context.Background(), "o", "r", "b", input) @@ -802,6 +805,7 @@ func TestRepositoriesService_UpdatePullRequestReviewEnforcement(t *testing.T) { {Slug: String("t"), ID: Int(2)}, }, }, + RequireCodeOwnerReviews: true, } if !reflect.DeepEqual(enforcement, want) { t.Errorf("Repositories.UpdatePullRequestReviewEnforcement returned %+v, want %+v", enforcement, want) @@ -816,7 +820,7 @@ func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { testMethod(t, r, "PATCH") testHeader(t, r, "Accept", mediaTypeProtectedBranchesPreview) testBody(t, r, `{"dismissal_restrictions":[]}`+"\n") - fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":true}`) + fmt.Fprintf(w, `{"dismissal_restrictions":{"users":[],"teams":[]},"dismiss_stale_reviews":true,"require_code_owner_reviews":true}`) }) enforcement, _, err := client.Repositories.DisableDismissalRestrictions(context.Background(), "o", "r", "b") @@ -830,6 +834,7 @@ func TestRepositoriesService_DisableDismissalRestrictions(t *testing.T) { Users: []*User{}, Teams: []*Team{}, }, + RequireCodeOwnerReviews: true, } if !reflect.DeepEqual(enforcement, want) { t.Errorf("Repositories.DisableDismissalRestrictions returned %+v, want %+v", enforcement, want) @@ -925,7 +930,7 @@ func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctio t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err) } - want := `{"dismissal_restrictions":[],"dismiss_stale_reviews":false}` + want := `{"dismissal_restrictions":[],"dismiss_stale_reviews":false,"require_code_owner_reviews":false}` if want != string(json) { t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(json), want) } From 14a81fd46847402847b29d09333312bd9f1d8f71 Mon Sep 17 00:00:00 2001 From: Dennis Webb Date: Sat, 14 Oct 2017 07:46:12 -0500 Subject: [PATCH 2/2] updating comments to reflect repo's style --- github/repos.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/github/repos.go b/github/repos.go index 99aafba749e..ecaeb0433e4 100644 --- a/github/repos.go +++ b/github/repos.go @@ -562,7 +562,7 @@ type PullRequestReviewsEnforcement struct { DismissalRestrictions DismissalRestrictions `json:"dismissal_restrictions"` // Specifies if approved reviews are dismissed automatically, when a new commit is pushed. DismissStaleReviews bool `json:"dismiss_stale_reviews"` - // Specifies if an approved review is required in pull requests including files with a designated code owner. + // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` } @@ -574,7 +574,7 @@ type PullRequestReviewsEnforcementRequest struct { DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"` // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. (Required) DismissStaleReviews bool `json:"dismiss_stale_reviews"` - // Specifies if an approved review is required in pull requests including files with a designated code owner. + // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. RequireCodeOwnerReviews bool `json:"require_code_owner_reviews"` } @@ -613,7 +613,7 @@ type PullRequestReviewsEnforcementUpdate struct { DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"` // Specifies if approved reviews can be dismissed automatically, when a new commit is pushed. Can be omitted. DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"` - // Specifies if an approved review is required in pull requests including files with a designated code owner. + // RequireCodeOwnerReviews specifies if an approved review is required in pull requests including files with a designated code owner. RequireCodeOwnerReviews bool `json:"require_code_owner_reviews,omitempty"` }