Skip to content

Commit 44d4d0d

Browse files
committed
Add support for PR reviews preview
1 parent e9b59c6 commit 44d4d0d

6 files changed

Lines changed: 293 additions & 1 deletion

File tree

src/main/java/org/kohsuke/github/GHPullRequest.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@
2525

2626
import java.io.IOException;
2727
import java.net.URL;
28+
import java.util.ArrayList;
29+
import java.util.Arrays;
2830
import java.util.Collection;
2931
import java.util.Date;
32+
import java.util.List;
33+
import javax.annotation.CheckForNull;
3034

3135
/**
3236
* A pull request.
@@ -223,6 +227,27 @@ protected void wrapUp(GHPullRequestFileDetail[] page) {
223227
};
224228
}
225229

230+
/**
231+
* Retrieves all the reviews associated to this pull request.
232+
*/
233+
public PagedIterable<GHPullRequestReview> listReviews() {
234+
return new PagedIterable<GHPullRequestReview>() {
235+
public PagedIterator<GHPullRequestReview> _iterator(int pageSize) {
236+
return new PagedIterator<GHPullRequestReview>(root.retrieve()
237+
.withPreview("application/vnd.github.black-cat-preview+json")
238+
.asIterator(String.format("%s/reviews", getApiRoute()),
239+
GHPullRequestReview[].class, pageSize)) {
240+
@Override
241+
protected void wrapUp(GHPullRequestReview[] page) {
242+
for (GHPullRequestReview r: page) {
243+
r.wrapUp(GHPullRequest.this);
244+
}
245+
}
246+
};
247+
}
248+
};
249+
}
250+
226251
/**
227252
* Obtains all the review comments associated with this pull request.
228253
*/
@@ -259,6 +284,34 @@ protected void wrapUp(GHPullRequestCommitDetail[] page) {
259284
};
260285
}
261286

287+
@Preview
288+
@Deprecated
289+
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
290+
GHPullRequestReviewComment... comments)
291+
throws IOException {
292+
return createReview(body, event, Arrays.asList(comments));
293+
}
294+
295+
@Preview
296+
@Deprecated
297+
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
298+
List<GHPullRequestReviewComment> comments)
299+
throws IOException {
300+
if (event == null) {
301+
event = GHPullRequestReviewState.PENDING;
302+
}
303+
List<DraftReviewComment> draftComments = new ArrayList<DraftReviewComment>(comments.size());
304+
for (GHPullRequestReviewComment c : comments) {
305+
draftComments.add(new DraftReviewComment(c.getBody(), c.getPath(), c.getPosition()));
306+
}
307+
return new Requester(root).method("POST")
308+
.with("body", body)
309+
//.with("event", event.name())
310+
._with("comments", draftComments)
311+
.withPreview("application/vnd.github.black-cat-preview+json")
312+
.to(getApiRoute() + "/reviews", GHPullRequestReview.class).wrapUp(this);
313+
}
314+
262315
public GHPullRequestReviewComment createReviewComment(String body, String sha, String path, int position) throws IOException {
263316
return new Requester(root).method("POST")
264317
.with("body", body)
@@ -300,4 +353,28 @@ private void fetchIssue() throws IOException {
300353
fetchedIssueDetails = true;
301354
}
302355
}
356+
357+
private static class DraftReviewComment {
358+
private String body;
359+
private String path;
360+
private int position;
361+
362+
public DraftReviewComment(String body, String path, int position) {
363+
this.body = body;
364+
this.path = path;
365+
this.position = position;
366+
}
367+
368+
public String getBody() {
369+
return body;
370+
}
371+
372+
public String getPath() {
373+
return path;
374+
}
375+
376+
public int getPosition() {
377+
return position;
378+
}
379+
}
303380
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2017, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package org.kohsuke.github;
25+
26+
import java.io.IOException;
27+
import java.net.URL;
28+
29+
/**
30+
* Review to the pull request
31+
*
32+
* @see GHPullRequest#listReviews()
33+
* @see GHPullRequest#createReview(String, GHPullRequestReviewState, GHPullRequestReviewComment...)
34+
*/
35+
public class GHPullRequestReview extends GHObject {
36+
GHPullRequest owner;
37+
38+
private String body;
39+
private GHUser user;
40+
private String commit_id;
41+
private GHPullRequestReviewState state;
42+
43+
/*package*/ GHPullRequestReview wrapUp(GHPullRequest owner) {
44+
this.owner = owner;
45+
return this;
46+
}
47+
48+
/**
49+
* Gets the pull request to which this review is associated.
50+
*/
51+
public GHPullRequest getParent() {
52+
return owner;
53+
}
54+
55+
/**
56+
* The comment itself.
57+
*/
58+
public String getBody() {
59+
return body;
60+
}
61+
62+
/**
63+
* Gets the user who posted this review.
64+
*/
65+
public GHUser getUser() throws IOException {
66+
return owner.root.getUser(user.getLogin());
67+
}
68+
69+
public String getCommitId() {
70+
return commit_id;
71+
}
72+
73+
public GHPullRequestReviewState getState() {
74+
return state;
75+
}
76+
77+
@Override
78+
public URL getHtmlUrl() {
79+
return null;
80+
}
81+
82+
protected String getApiRoute() {
83+
return owner.getApiRoute()+"/reviews/"+id;
84+
}
85+
86+
/**
87+
* Updates the comment.
88+
*/
89+
@Preview
90+
@Deprecated
91+
public void submit(String body, GHPullRequestReviewState event) throws IOException {
92+
new Requester(owner.root).method("POST")
93+
.with("body", body)
94+
.with("event", event.action())
95+
.withPreview("application/vnd.github.black-cat-preview+json")
96+
.to(getApiRoute()+"/events",this);
97+
this.body = body;
98+
this.state = event;
99+
}
100+
101+
/**
102+
* Deletes this review.
103+
*/
104+
@Preview
105+
@Deprecated
106+
public void delete() throws IOException {
107+
new Requester(owner.root).method("DELETE")
108+
.withPreview("application/vnd.github.black-cat-preview+json")
109+
.to(getApiRoute());
110+
}
111+
112+
/**
113+
* Dismisses this review.
114+
*/
115+
@Preview
116+
@Deprecated
117+
public void dismiss(String message) throws IOException {
118+
new Requester(owner.root).method("PUT")
119+
.with("message", message)
120+
.withPreview("application/vnd.github.black-cat-preview+json")
121+
.to(getApiRoute()+"/dismissals");
122+
state = GHPullRequestReviewState.DISMISSED;
123+
}
124+
125+
/**
126+
* Obtains all the review comments associated with this pull request review.
127+
*/
128+
@Preview
129+
@Deprecated
130+
public PagedIterable<GHPullRequestReviewComment> listReviewComments() throws IOException {
131+
return new PagedIterable<GHPullRequestReviewComment>() {
132+
public PagedIterator<GHPullRequestReviewComment> _iterator(int pageSize) {
133+
return new PagedIterator<GHPullRequestReviewComment>(
134+
owner.root.retrieve()
135+
.withPreview("application/vnd.github.black-cat-preview+json")
136+
.asIterator(getApiRoute() + "/comments",
137+
GHPullRequestReviewComment[].class, pageSize)) {
138+
protected void wrapUp(GHPullRequestReviewComment[] page) {
139+
for (GHPullRequestReviewComment c : page)
140+
c.wrapUp(owner);
141+
}
142+
};
143+
}
144+
};
145+
}
146+
147+
}

src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
4444
private int position;
4545
private int originalPosition;
4646

47+
public static GHPullRequestReviewComment draft(String body, String path, int position) {
48+
GHPullRequestReviewComment result = new GHPullRequestReviewComment();
49+
result.body = body;
50+
result.path = path;
51+
result.position = position;
52+
return result;
53+
}
54+
4755
/*package*/ GHPullRequestReviewComment wrapUp(GHPullRequest owner) {
4856
this.owner = owner;
4957
return this;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.kohsuke.github;
2+
3+
public enum GHPullRequestReviewState {
4+
PENDING(null),
5+
APPROVED("APPROVE"),
6+
REQUEST_CHANGES("REQUEST_CHANGES"),
7+
COMMENTED("COMMENT"),
8+
DISMISSED(null);
9+
10+
private final String _action;
11+
12+
GHPullRequestReviewState(String action) {
13+
_action = action;
14+
}
15+
16+
public String action() {
17+
return _action;
18+
}
19+
}

src/test/java/org/kohsuke/github/AbstractGitHubApiTestBase.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.kohsuke.github;
22

3+
import java.io.FileInputStream;
4+
import java.util.Properties;
5+
import org.apache.commons.io.IOUtils;
36
import org.junit.Assert;
47
import org.junit.Assume;
58
import org.junit.Before;
@@ -19,9 +22,17 @@ public abstract class AbstractGitHubApiTestBase extends Assert {
1922
public void setUp() throws Exception {
2023
File f = new File(System.getProperty("user.home"), ".github.kohsuke2");
2124
if (f.exists()) {
25+
Properties props = new Properties();
26+
FileInputStream in = null;
27+
try {
28+
in = new FileInputStream(f);
29+
props.load(in);
30+
} finally {
31+
IOUtils.closeQuietly(in);
32+
}
2233
// use the non-standard credential preferentially, so that developers of this library do not have
2334
// to clutter their event stream.
24-
gitHub = GitHubBuilder.fromPropertyFile(f.getPath()).withRateLimitHandler(RateLimitHandler.FAIL).build();
35+
gitHub = GitHubBuilder.fromProperties(props).withRateLimitHandler(RateLimitHandler.FAIL).build();
2536
} else {
2637
gitHub = GitHubBuilder.fromCredentials().withRateLimitHandler(RateLimitHandler.FAIL).build();
2738
}

src/test/java/org/kohsuke/github/PullRequestTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
import java.util.Collection;
88
import java.util.List;
99

10+
import static org.hamcrest.CoreMatchers.is;
11+
import static org.hamcrest.CoreMatchers.notNullValue;
12+
1013
/**
1114
* @author Kohsuke Kawaguchi
1215
*/
@@ -26,6 +29,33 @@ public void createPullRequestComment() throws Exception {
2629
p.comment("Some comment");
2730
}
2831

32+
@Test
33+
public void testPullRequestReviews() throws Exception {
34+
String name = rnd.next();
35+
GHPullRequest p = getRepository().createPullRequest(name, "stable", "master", "## test");
36+
GHPullRequestReview draftReview = p.createReview("Some draft review", null,
37+
GHPullRequestReviewComment.draft("Some niggle", "changelog.html", 1)
38+
);
39+
assertThat(draftReview.getState(), is(GHPullRequestReviewState.PENDING));
40+
assertThat(draftReview.getBody(), is("Some draft review"));
41+
assertThat(draftReview.getCommitId(), notNullValue());
42+
List<GHPullRequestReview> reviews = p.listReviews().asList();
43+
assertThat(reviews.size(), is(1));
44+
GHPullRequestReview review = reviews.get(0);
45+
assertThat(review.getState(), is(GHPullRequestReviewState.PENDING));
46+
assertThat(review.getBody(), is("Some draft review"));
47+
assertThat(review.getCommitId(), notNullValue());
48+
review.submit("Some review comment", GHPullRequestReviewState.COMMENTED);
49+
List<GHPullRequestReviewComment> comments = review.listReviewComments().asList();
50+
assertEquals(1, comments.size());
51+
GHPullRequestReviewComment comment = comments.get(0);
52+
assertEquals("Some niggle", comment.getBody());
53+
review = p.createReview("Some new review", null,
54+
GHPullRequestReviewComment.draft("Some niggle", "changelog.html", 1)
55+
);
56+
review.delete();
57+
}
58+
2959
@Test
3060
public void testPullRequestReviewComments() throws Exception {
3161
String name = rnd.next();

0 commit comments

Comments
 (0)