Skip to content

[Issue#617] Update Protected Branches API preview #637

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 28, 2017

Conversation

jkosecki
Copy link
Contributor

Adds pull request reviews enforcement structures and API methods, adds admin enforcement API methods and removes old IncludeAdmins field from the request.

@dmitshur dmitshur self-requested a review May 11, 2017 04:24
Copy link
Member

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty large change. Thanks for working on this.

I've reviewed it partially so far, and everything looks great. I posted some comments inline.

My biggest concern here is the new PullRequestReviewsEnforcementPatchRequest struct. I think it's unfortunate we need that in addition to PullRequestReviewsEnforcementRequest. I understand why you added it. It's because GitHub API docs currently show slightly different things for these endpoints:

The former says that they're all required fields:

image

But the latter says they're optional:

image

First of all, the first one lists dismissal_restrictions object twice, that's clearly a typo. But I wonder if they're not actually that different, maybe the difference is a typo too. It might be good to clarify with GitHub support.

One last thing. I noticed in the docs:

You can disable dismissal restrictions by passing the dismissal_restrictions object as an empty array.

Is there support for that in this PR?

github/repos.go Outdated
// because the request structure is different from the response structure.
type PullRequestReviewsEnforcementRequest struct {
DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"`
DismissStaleReviews bool `json:"dismiss_stale_reviews"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you document the two fields?

// Specify which users and teams can dismiss pull request reviews. (Required.)
DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"`

// Dismiss approved reviews automatically when a new commit is pushed. (Required.)
DismissStaleReviews bool `json:"dismiss_stale_reviews"`

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do and had so at the beginning, but I've noticed that Visual Studio Code go fmt plugin, does not align structure's fields to one line, if the fields have comments. So I thought that maybe commenting fields is not welcome.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're certainly welcome. See some other structs in this file that have documented fields. The gofmt formatting is fine. Thanks.

github/repos.go Outdated
// because the patch request does not require all fields to be initialized.
type PullRequestReviewsEnforcementPatchRequest struct {
DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions,omitempty"`
DismissStaleReviews *bool `json:"dismiss_stale_reviews,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well. Except, the fields are not required here.

github/repos.go Outdated
// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcement above
// because the request structure is different from the response structure.
type PullRequestReviewsEnforcementRequest struct {
DismissalRestrictionsRequest *DismissalRestrictionsRequest `json:"dismissal_restrictions"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this is a required field here, what do you think about using a value DismissalRestrictionsRequest rather than pointer *DismissalRestrictionsRequest (similar to bool below being a value rather than pointer).

Or is it neccessary to have a pointer to be able to send a null value?

Copy link
Contributor Author

@jkosecki jkosecki May 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, I believe I overthought it.

You can disable dismissal restrictions by passing the dismissal_restrictions object as an empty array.

I will clarify it yet with GitHub support, since other structures allow null for disabling:

You must pass the following objects: required_status_checks, enforce_admins, and restrictions. They can have the value null for disabled.

In the case there is also an type error and empty array should by null object, the pointer would make sense and it would support disabling dismissal restrictions. If not, I'm not sure yet, how can I pass an empty array instead of empty object to disable it.

github/repos.go Outdated
// PullRequestReviewsEnforcementPatchRequest represents request to patch the pull request review
// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementPatchRequest above
// because the patch request does not require all fields to be initialized.
type PullRequestReviewsEnforcementPatchRequest struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it turns out we really do need to keep this struct after all, I'd suggest renaming it to PullRequestReviewsEnforcementUpdate. How's that sound?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with that. However, taking into account, that the HTTP request is PATCH, I thought it will be better to use such a name, so it will explicitly say, that not all fields are required. But I believe PullRequestReviewsEnforcementUpdate is also fine

Copy link
Member

@dmitshur dmitshur May 12, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HTTP method is indeed PATCH, but that's a low level implementation detail. The endpoint is called "Update pull request review enforcement of protected branch", which is where my suggestion of using "Update" comes from.

It's still not ideal, because "PullRequestReviewsEnforcementRequest" is used for an endpoint called "Update branch protection"... But still, I think one word is better than "PatchRequest".

@jkosecki
Copy link
Contributor Author

I believe the difference between must and can comes from the difference between HTTP PUT request of the Update branch protection and HTTP PATCH request of the Update pull request reviews enforcment.

I wrote an e-mail to GitHub support to clarify those two endpoints

@jkosecki
Copy link
Contributor Author

@shurcooL:
After exchanging some e-mails with a GitHub support, I know, that we require two different structures for Update branch protection and Update pull request review. The difference between required and not required is intended.

However, I'm still stuck at one point. For update branch protection, it is easy to say "if one pass nil value for dismissal_restrictions, he wants to disable them so we convert it to an empty array.
However, the same option should be available with the Update pull request review and here comes my design problem, because on the one hand we should be able to ignore dismissal_restrictions (that's why omitempty), but on the other hand, we should be able to notify GitHub that one wants to disable them and convert it to an empty array.

@dmitshur
Copy link
Member

The problem you're describing sounds very similar to #236.

@jkosecki
Copy link
Contributor Author

@shurcooL: Thank you. I took your advise and implemented additional API method. I believe, my change set is ready.

Copy link
Member

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left some minor comments.

I'm finding it hard to review the PR as a whole, because of its large size. But the changes you've made seem reasonable.

@gmlewis Can you take a look and see if you have any comments?

D: req.DismissStaleReviews,
}
return json.Marshal(newReq)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really cool solution to work around the GitHub API weirdness. Nice idea! 👍

body := strings.TrimSpace(buf.String())
if wantBody != body {
t.Errorf("Request body = %+v, want %+v", body, wantBody)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use testBody helper. See how other tests use it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the tip, it made the test method definitely nicer.

}

want := `{"dismissal_restrictions":[],"dismiss_stale_reviews":false}`

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This blank line can be removed too.


json, err := json.Marshal(req)

if err != nil {
Copy link
Member

@dmitshur dmitshur Jun 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the blank line between foo, err := something() and if err != nil {. It hurts readability.

@dmitshur dmitshur requested a review from gmlewis June 2, 2017 20:10
Copy link
Collaborator

@gmlewis gmlewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM after @shurcooL's comments and a minor comment typo are fixed.
Thanks, @navarrano!

github/repos.go Outdated
}

// PullRequestReviewsEnforcementUpdate represents request to patch the pull request review
// enforcement of a protected branch. It is separate from PullRequestReviewsEnforcementUpdate above
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/PullRequestReviewsEnforcementUpdate/PullRequestReviewsEnforcementRequest/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmlewis The reason it's not already PullRequestReviewsEnforcementRequest is because that name is already taken. See 3rd paragraph of #637 (review) and #637 (review) for previous discussion about this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let X = "PullRequestReviewsEnforcementUpdate"

This section says:

// X represents... It is separate from X above ...
type X struct {

I think the second X needs to be replaced. The first and third X are fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see what you mean now. 👍 Indeed.

github/repos.go Outdated
//
// GitHub API docs: https://developer.github.com/v3/repos/branches/#get-pull-request-review-enforcement-of-protected-branch
func (s *RepositoriesService) GetPullRequestReviewEnforcement(ctx context.Context, owner, repo, branch string) (*PullRequestReviewsEnforcement, *Response, error) {
u := fmt.Sprintf("/repos/%v/%v/branches/%v/protection/required_pull_request_reviews", owner, repo, branch)
Copy link
Member

@dmitshur dmitshur Jun 2, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An important issue I've spotted is that all 7 of these URLs begin with a /, they should not (it breaks support for GitHub Enterprise). Instead, write:

u := fmt.Sprintf("repos/...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for spotting it, no idea how I came with an idea of starting the URL with a slash...
Should be alright now

Copy link
Member

@dmitshur dmitshur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not spotting any other issues. LGTM.

I haven't verified absolutely all details in this PR (because of its size), but it looks good. I'm sure we can address any issues if they come up. This is still a preview API.

Thanks!

github/repos.go Outdated
return r, resp, err
}

// RemoveAdminEnforcement removess admin enforcement from a protected branch.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor, typo in "removess", should be "removes".

@gmlewis
Copy link
Collaborator

gmlewis commented Jun 28, 2017

Sorry for the delay! LGTM. Merging.

nbareil pushed a commit to nbareil/go-github that referenced this pull request May 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants