-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
pulls: Support updating base branch #528
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for making this PR @abhinav, this looks really good. I think we need to improve documentation, then this can be merged. See other comments about an optional enhancement to the tests.
State *string `json:"state,omitempty"` | ||
Base *string `json:"base,omitempty"` | ||
} | ||
|
||
// Edit a pull request. | ||
// | ||
// GitHub API docs: https://developer.github.com/v3/pulls/#update-a-pull-request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should document which fields we currently support. It's not obvious that passing github.&PullRequest{Base: &github.PullRequestBranch{Ref: "belong-to-us"}
, out out of all other fields inside PullRequest
struct, will update the base.
Something like:
// Edit a pull request.
//
// Fields that can be edited are: Title, Body, State, Base.Ref to edit base branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Added docs for this.
input *PullRequest | ||
sendResponse string | ||
|
||
wantUpdate *pullRequestUpdate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is optional, but I think it'd be better if you made the type of wantUpdate
a string
and have it contain the expected JSON.
There's no need to decode the update JSON into our own struct that we used for encoding, and compare those.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was concerned that the order in which the struct fields would
be serialized is not deterministic but that doesn't appear to be
the case upon trial. Updated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see.
Yeah, encoding/json
encoder uses the order of fields in a struct when encoding, so it is deterministic. It even sorts map keys, so everything's always deterministic.
{ | ||
input: &PullRequest{Title: String("t")}, | ||
sendResponse: `{"number":1}`, | ||
wantUpdate: &pullRequestUpdate{Title: String("t")}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then, the value for wantUpdate
here would be something like {"title":"t"}
.
It's easier to reason about it being correct, since GitHub API deals with JSON input and we can compare its documentation with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thank you!
See line comment for another simplification opportunity.
gotUpdate, _ := ioutil.ReadAll(r.Body) | ||
wantUpdate := tt.wantUpdate + "\n" // json encoder adds a newline | ||
if string(gotUpdate) != wantUpdate { | ||
t.Errorf("Request body = %q, want %q", gotUpdate, wantUpdate) | ||
} |
There was a problem hiding this comment.
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 to simplify this.
See
go-github/github/pulls_test.go
Line 478 in c9c37fd
testBody(t, r, test.wantBody+"\n") |
for _, tt := range tests { | ||
func() { | ||
setup() | ||
defer teardown() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact, you can use the idea from TestPullRequestsService_Merge_options
to remove the need for the nested closure with per-testcase setup()/defer teardown()
. The idea there is to use i
as the pull request ID, so that registered routes don't overlap.
It also tests that the handler gets called (instead of not being called).
See
go-github/github/pulls_test.go
Lines 438 to 486 in c9c37fd
// Test that different merge options produce expected PUT requests. See issue https://github.com/google/go-github/issues/500. | |
func TestPullRequestsService_Merge_options(t *testing.T) { | |
setup() | |
defer teardown() | |
tests := []struct { | |
options *PullRequestOptions | |
wantBody string | |
}{ | |
{ | |
options: nil, | |
wantBody: `{"commit_message":"merging pull request"}`, | |
}, | |
{ | |
options: &PullRequestOptions{}, | |
wantBody: `{"commit_message":"merging pull request"}`, | |
}, | |
{ | |
options: &PullRequestOptions{MergeMethod: "rebase"}, | |
wantBody: `{"commit_message":"merging pull request","merge_method":"rebase"}`, | |
}, | |
{ | |
options: &PullRequestOptions{SHA: "6dcb09b5b57875f334f61aebed695e2e4193db5e"}, | |
wantBody: `{"commit_message":"merging pull request","sha":"6dcb09b5b57875f334f61aebed695e2e4193db5e"}`, | |
}, | |
{ | |
options: &PullRequestOptions{ | |
CommitTitle: "Extra detail", | |
SHA: "6dcb09b5b57875f334f61aebed695e2e4193db5e", | |
MergeMethod: "squash", | |
}, | |
wantBody: `{"commit_message":"merging pull request","commit_title":"Extra detail","merge_method":"squash","sha":"6dcb09b5b57875f334f61aebed695e2e4193db5e"}`, | |
}, | |
} | |
for i, test := range tests { | |
madeRequest := false | |
mux.HandleFunc(fmt.Sprintf("/repos/o/r/pulls/%d/merge", i), func(w http.ResponseWriter, r *http.Request) { | |
testMethod(t, r, "PUT") | |
testHeader(t, r, "Accept", mediaTypeSquashPreview) | |
testBody(t, r, test.wantBody+"\n") | |
madeRequest = true | |
}) | |
_, _, _ = client.PullRequests.Merge("o", "r", i, "merging pull request", test.options) | |
if !madeRequest { | |
t.Errorf("%d: PullRequests.Merge(%#v): expected request was not made", i, test.options) | |
} | |
} | |
} |
Optional, if you're interested in doing this.
Also test whether the request was acually made.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks for doing this!
LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v := new(PullRequest) | ||
json.NewDecoder(r.Body).Decode(v) | ||
wantUpdate string | ||
wantResponse *PullRequest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I find wantResponse
a bit confusing here... what if we just called it want
?
Either way is fine, though... your call.
As per the discussion in google#421, the PullRequest parameter is converted into an unexported type pullRequestUpdate which matches the shape expected by the pulls PATCH endpoint. Resolves google#421.
This adds support for changing the base branch of a PR.
As per the discussion in #421, the
PullRequest
is converted into anunexported type
pullRequestUpdate
which matches the shape expected by thepulls PATCH endpoint.
Resolves issue #421.