Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions github/repos.go
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,8 @@ type PullRequestReviewsEnforcementRequest struct {
// RequiredApprovingReviewCount specifies the number of approvals required before the pull request can be merged.
// Valid values are 1-6.
RequiredApprovingReviewCount int `json:"required_approving_review_count"`
// RequireLastPushApproval specifies whether the last pusher to a pull request branch can approve it.
RequireLastPushApproval bool `json:"require_last_push_approval"`
}

// PullRequestReviewsEnforcementUpdate represents request to patch the pull request review
Expand Down
52 changes: 49 additions & 3 deletions github/repos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) {
},
"dismiss_stale_reviews":true,
"require_code_owner_reviews":true,
"require_last_push_approval":false,
"required_approving_review_count":1
},
"enforce_admins":{
Expand Down Expand Up @@ -1130,6 +1131,7 @@ func TestRepositoriesService_GetBranchProtection(t *testing.T) {
},
RequireCodeOwnerReviews: true,
RequiredApprovingReviewCount: 1,
RequireLastPushApproval: false,
},
EnforceAdmins: &AdminEnforcement{
URL: String("/repos/o/r/branches/b/protection/enforce_admins"),
Expand Down Expand Up @@ -1633,6 +1635,7 @@ func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T)
},
"dismiss_stale_reviews":true,
"require_code_owner_reviews":true,
"require_last_push_approval":false,
"bypass_pull_request_allowances": {
"users":[{"id":10,"login":"uuu"}],
"teams":[{"id":20,"slug":"ttt"}],
Expand Down Expand Up @@ -1702,6 +1705,48 @@ func TestRepositoriesService_UpdateBranchProtection_StrictNoChecks(t *testing.T)
}
}

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

input := &ProtectionRequest{
RequiredPullRequestReviews: &PullRequestReviewsEnforcementRequest{
RequireLastPushApproval: true,
},
}

mux.HandleFunc("/repos/o/r/branches/b/protection", func(w http.ResponseWriter, r *http.Request) {
v := new(ProtectionRequest)
json.NewDecoder(r.Body).Decode(v)

testMethod(t, r, "PUT")
if !cmp.Equal(v, input) {
t.Errorf("Request body = %+v, want %+v", v, input)
}

fmt.Fprintf(w, `{
"required_pull_request_reviews":{
"require_last_push_approval":true
}
}`)
})

ctx := context.Background()
protection, _, err := client.Repositories.UpdateBranchProtection(ctx, "o", "r", "b", input)
if err != nil {
t.Errorf("Repositories.UpdateBranchProtection returned error: %v", err)
}

want := &Protection{
RequiredPullRequestReviews: &PullRequestReviewsEnforcement{
RequireLastPushApproval: true,
},
}
if !cmp.Equal(protection, want) {
t.Errorf("Repositories.UpdateBranchProtection returned %+v, want %+v", protection, want)
}
}

func TestRepositoriesService_RemoveBranchProtection(t *testing.T) {
client, mux, _, teardown := setup()
defer teardown()
Expand Down Expand Up @@ -2536,7 +2581,7 @@ func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctio
t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
}

want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
want := `{"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0,"require_last_push_approval":false}`
if want != string(got) {
t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
}
Expand All @@ -2550,7 +2595,7 @@ func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctio
t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
}

want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
want = `{"dismissal_restrictions":{},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0,"require_last_push_approval":false}`
if want != string(got) {
t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
}
Expand All @@ -2561,14 +2606,15 @@ func TestPullRequestReviewsEnforcementRequest_MarshalJSON_nilDismissalRestirctio
Teams: &[]string{},
Apps: &[]string{},
},
RequireLastPushApproval: true,
}

got, err = json.Marshal(req)
if err != nil {
t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned error: %v", err)
}

want = `{"dismissal_restrictions":{"users":[],"teams":[],"apps":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0}`
want = `{"dismissal_restrictions":{"users":[],"teams":[],"apps":[]},"dismiss_stale_reviews":false,"require_code_owner_reviews":false,"required_approving_review_count":0,"require_last_push_approval":true}`
if want != string(got) {
t.Errorf("PullRequestReviewsEnforcementRequest.MarshalJSON returned %+v, want %+v", string(got), want)
}
Expand Down