Compare commits

..

35 Commits

Author SHA1 Message Date
Kohsuke Kawaguchi
188245fa7f [maven-release-plugin] prepare release github-api-1.91 2018-01-13 10:36:45 -08:00
Kohsuke Kawaguchi
e10b747d6a Re-retried the object.
It looks like the format has changed a bit since this payload was
retrieved originally?
2018-01-13 10:30:48 -08:00
Kohsuke Kawaguchi
f2bb6a05a5 Merge pull request #384 2018-01-13 10:19:12 -08:00
Kohsuke Kawaguchi
f41da19db5 Further restoration of the compatibility 2018-01-13 09:54:14 -08:00
Kohsuke Kawaguchi
d0a56dbb21 Merge pull request #406
... with some further changes
2018-01-13 09:47:37 -08:00
Kohsuke Kawaguchi
acbf286e59 Massaged the changes
- Restored binary compatibility. The draft API has changed in some
  significant way when it became public, and the PR took the liberty to
  delete removed constants and method signatures. I brought them back so
  that older clients can keep functioning.

- Introduced a builder pattern to create PR review

- replying to a review comment should be an instance method, not a
  static method.

- GHPullRequestReview and GHPullRequestReviewDraft was not making sense
  to me, since GitHub API doesn't differentiate them. It creates a
  practical problem of not being able to submit a review comment unless
  you created the review comment in the same JVM session. That said, I
  don't understand the point of this two phase approach in the GitHub
  API to begin with!
2018-01-13 09:43:44 -08:00
Kohsuke Kawaguchi
0f7c160409 Based on issue #399, adjusting the behaviour.
This ends up changing the behaviour cloes to that of #394.
2018-01-12 21:33:03 -08:00
Kohsuke Kawaguchi
5113aacb89 Issue #403: Typo in method name 2018-01-12 21:28:37 -08:00
Kohsuke Kawaguchi
4e31636181 Allow the caller to wait for the mergeable state to change.
This approaches #394 differently. The problem with the original #394 is
that the supposed behaviour is only useful for people waiting for
`getMergeable()` to return non-null in a busy loop, yet it impacts all
the other methods of this object.
2018-01-12 21:25:30 -08:00
Kohsuke Kawaguchi
1e497d2c44 Merge branch 'master' into bridge-method-annotation 2018-01-12 21:13:49 -08:00
Kohsuke Kawaguchi
70bd4fa161 Merge pull request #379 2018-01-12 21:12:48 -08:00
Kohsuke Kawaguchi
65996050d5 Massaged changes to follow the convention 2018-01-12 21:12:40 -08:00
Kohsuke Kawaguchi
7f52031199 Merge branch 'master' of github.com:kohsuke/github-api 2018-01-12 21:07:11 -08:00
Kohsuke Kawaguchi
5430f3d33c Merge pull request #391 2018-01-12 21:06:55 -08:00
Kohsuke Kawaguchi
43075faaf8 By convention we use "listXyz" method names 2018-01-12 21:06:47 -08:00
Kohsuke Kawaguchi
f3a1272e31 Merge pull request #397 from mizoguche/set-milestone
Add GHIssue#setMilestone
2018-01-12 21:04:18 -08:00
Kohsuke Kawaguchi
41c028d4d9 Merge pull request #401 2018-01-12 21:00:56 -08:00
Kohsuke Kawaguchi
a17ce04552 Adjustment to compensate 2018-01-12 21:00:25 -08:00
Björn Häuser
d0b4652dcd Replace "new Error" with GHException
(rolled back some of the hunks from the original PR)
2018-01-12 19:44:25 -08:00
Kohsuke Kawaguchi
e66f71c76e Merge pull request #407 from notsudo/GHCreateRepositoryBuilder_Add_Merge_Settings
Adding merge settings to GHCreateRepositoryBuilder
2018-01-12 19:39:03 -08:00
Kohsuke Kawaguchi
6effd4b846 Merge pull request #396 from Rechi/fixGHPersonNullPointer
[fix] GHPerson: check if root is null
2018-01-12 08:45:02 -08:00
Timothy McNally
df861f5403 Adding methods to GHCreateRepositoryBuilder to allow setting the allowed merge methods for pull requests. 2018-01-09 17:32:54 -08:00
Sébastien Lesaint
e74346fed6 support create PR review in single API call & remove @Preview 2018-01-09 14:13:25 +01:00
Sébastien Lesaint
6961c467a6 create review comment reply from GHPullRequest 2018-01-09 14:13:25 +01:00
Sébastien Lesaint
892d305165 add Requester#with override for long value 2018-01-09 14:13:25 +01:00
Sébastien Lesaint
fa16261d7a position of pr comment can be null and original_position is not parsed
position of pr comment is null when comment is outdated (ie. not located in diff patch anymore)
2018-01-09 14:13:25 +01:00
Sébastien Lesaint
15991fd2f7 PullRequest review state and event do not have same values
this fixes parsing of response of WS call submitting a review to fail
when event of new review is REQUEST_CHANGES
also, specifying event when creating a pending PR review is useless and
providing it when submitting the review is enough
2018-01-09 14:13:25 +01:00
Michiaki Mizoguchi
c80b8f60f8 Add GHIssue#setMilestone 2017-11-16 12:42:52 +09:00
Rechi
ab6253cbd0 [fix] GHPerson: check if root is null 2017-11-09 22:41:49 +01:00
sg012265
35ba267115 Revert wildcard usage for imports 2017-10-30 15:38:19 -05:00
sg012265
ab24e6e1c1 Add get for all orgs 2017-10-30 15:32:25 -05:00
Kohsuke Kawaguchi
e25ae27a15 [maven-release-plugin] prepare for next development iteration 2017-10-28 15:54:44 -07:00
Matt Nelson
0f81d1dbb3 Add support for pr review/review comment events 2017-10-05 18:14:15 -05:00
Anton Zagorskii
ae1ec8b558 Roles for team members 2017-09-20 13:22:30 +01:00
Jesse Glick
09c2b39530 bridge-method-annotation should be an optional dep. 2017-09-13 15:14:42 -04:00
21 changed files with 559 additions and 135 deletions

View File

@@ -7,7 +7,7 @@
</parent>
<artifactId>github-api</artifactId>
<version>1.90</version>
<version>1.91</version>
<name>GitHub API for Java</name>
<url>http://github-api.kohsuke.org/</url>
<description>GitHub API for Java</description>
@@ -16,7 +16,7 @@
<connection>scm:git:git@github.com/kohsuke/${project.artifactId}.git</connection>
<developerConnection>scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git</developerConnection>
<url>http://${project.artifactId}.kohsuke.org/</url>
<tag>github-api-1.90</tag>
<tag>github-api-1.91</tag>
</scm>
<distributionManagement>
@@ -131,6 +131,7 @@
<groupId>com.infradna.tool</groupId>
<artifactId>bridge-method-annotation</artifactId>
<version>1.17</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.kohsuke.stapler</groupId>

View File

@@ -21,8 +21,8 @@ public class GHCreateRepositoryBuilder {
}
public GHCreateRepositoryBuilder description(String description) {
this.builder.with("description",description);
return this;
this.builder.with("description",description);
return this;
}
public GHCreateRepositoryBuilder homepage(URL homepage) {
@@ -74,6 +74,30 @@ public class GHCreateRepositoryBuilder {
return this;
}
/**
* Allow or disallow squash-merging pull requests.
*/
public GHCreateRepositoryBuilder allowSquashMerge(boolean b) {
this.builder.with("allow_squash_merge",b);
return this;
}
/**
* Allow or disallow merging pull requests with a merge commit.
*/
public GHCreateRepositoryBuilder allowMergeCommit(boolean b) {
this.builder.with("allow_merge_commit",b);
return this;
}
/**
* Allow or disallow rebase-merging pull requests.
*/
public GHCreateRepositoryBuilder allowRebaseMerge(boolean b) {
this.builder.with("allow_rebase_merge",b);
return this;
}
/**
* Creates a default .gitignore
*

View File

@@ -85,6 +85,95 @@ public abstract class GHEventPayload {
}
}
/**
* A review was added to a pull request
*
* @see <a href="https://developer.github.com/v3/activity/events/types/#pullrequestreviewevent">authoritative source</a>
*/
public static class PullRequestReview extends GHEventPayload {
private String action;
private GHPullRequestReview review;
private GHPullRequest pull_request;
private GHRepository repository;
public String getAction() {
return action;
}
public GHPullRequestReview getReview() {
return review;
}
public GHPullRequest getPullRequest() {
return pull_request;
}
public GHRepository getRepository() {
return repository;
}
@Override
void wrapUp(GitHub root) {
super.wrapUp(root);
if (review==null)
throw new IllegalStateException("Expected pull_request_review payload, but got something else. Maybe we've got another type of event?");
review.wrapUp(pull_request);
if (repository!=null) {
repository.wrap(root);
pull_request.wrapUp(repository);
} else {
pull_request.wrapUp(root);
}
}
}
/**
* A review comment was added to a pull request
*
* @see <a href="https://developer.github.com/v3/activity/events/types/#pullrequestreviewcommentevent">authoritative source</a>
*/
public static class PullRequestReviewComment extends GHEventPayload {
private String action;
private GHPullRequestReviewComment comment;
private GHPullRequest pull_request;
private GHRepository repository;
public String getAction() {
return action;
}
public GHPullRequestReviewComment getComment() {
return comment;
}
public GHPullRequest getPullRequest() {
return pull_request;
}
public GHRepository getRepository() {
return repository;
}
@Override
void wrapUp(GitHub root) {
super.wrapUp(root);
if (comment==null)
throw new IllegalStateException("Expected pull_request_review_comment payload, but got something else. Maybe we've got another type of event?");
comment.wrapUp(pull_request);
if (repository!=null) {
repository.wrap(root);
pull_request.wrapUp(repository);
} else {
pull_request.wrapUp(root);
}
}
}
/**
* A comment was added to an issue
*

View File

@@ -103,7 +103,7 @@ public class GHGist extends GHObject {
* Used when caller obtains {@link GHGist} without knowing its owner.
* A partially constructed owner object is interned.
*/
/*package*/ GHGist wrapUp(GitHub root) throws IOException {
/*package*/ GHGist wrapUp(GitHub root) {
this.owner = root.getUser(owner);
this.root = root;
wrapUp();
@@ -144,12 +144,8 @@ public class GHGist extends GHObject {
return new PagedIterator<GHGist>(root.retrieve().asIterator(getApiTailUrl("forks"), GHGist[].class, pageSize)) {
@Override
protected void wrapUp(GHGist[] page) {
try {
for (GHGist c : page)
c.wrapUp(root);
} catch (IOException e) {
throw new Error(e);
}
for (GHGist c : page)
c.wrapUp(root);
}
};
}

View File

@@ -203,6 +203,10 @@ public class GHIssue extends GHObject implements Reactable{
edit("body",body);
}
public void setMilestone(GHMilestone milestone) throws IOException {
edit("milestone",milestone.getNumber());
}
public void assignTo(GHUser user) throws IOException {
setAssignees(user);
}

View File

@@ -41,7 +41,7 @@ public abstract class GHPerson extends GHObject {
if (created_at!=null) {
return; // already populated
}
if (root.isOffline()) {
if (root == null || root.isOffline()) {
return; // cannot populate, will have to live with what we have
}
root.retrieve().to(url, this);

View File

@@ -26,23 +26,22 @@ package org.kohsuke.github;
import javax.annotation.CheckForNull;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import static org.kohsuke.github.Previews.*;
/**
* A pull request.
*
*
* @author Kohsuke Kawaguchi
* @see GHRepository#getPullRequest(int)
*/
@SuppressWarnings({"UnusedDeclaration"})
public class GHPullRequest extends GHIssue {
private static final String COMMENTS_ACTION = "/comments";
private String patch_url, diff_url, issue_url;
private GHCommitPointer base;
private String merged_at;
@@ -91,7 +90,7 @@ public class GHPullRequest extends GHIssue {
public URL getPatchUrl() {
return GitHub.parseURL(patch_url);
}
/**
* The URL of the patch file.
* like https://github.com/jenkinsci/jenkins/pull/100.patch
@@ -114,7 +113,7 @@ public class GHPullRequest extends GHIssue {
public GHCommitPointer getHead() {
return head;
}
@Deprecated
public Date getIssueUpdatedAt() throws IOException {
return super.getUpdatedAt();
@@ -182,8 +181,17 @@ public class GHPullRequest extends GHIssue {
return maintainer_can_modify;
}
/**
* Is this PR mergeable?
*
* @return
* null if the state has not been determined yet, for example when a PR is newly created.
* If this method is called on an instance whose mergeable state is not yet known,
* API call is made to retrieve the latest state.
*/
public Boolean getMergeable() throws IOException {
populate();
if (mergeable==null)
refresh();
return mergeable;
}
@@ -217,6 +225,13 @@ public class GHPullRequest extends GHIssue {
*/
private void populate() throws IOException {
if (mergeable_state!=null) return; // already populated
refresh();
}
/**
* Repopulates this object.
*/
public void refresh() throws IOException {
if (root.isOffline()) {
return; // cannot populate, will have to live with what we have
}
@@ -246,7 +261,6 @@ public class GHPullRequest extends GHIssue {
return new PagedIterable<GHPullRequestReview>() {
public PagedIterator<GHPullRequestReview> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestReview>(root.retrieve()
.withPreview(BLACK_CAT)
.asIterator(String.format("%s/reviews", getApiRoute()),
GHPullRequestReview[].class, pageSize)) {
@Override
@@ -266,7 +280,7 @@ public class GHPullRequest extends GHIssue {
public PagedIterable<GHPullRequestReviewComment> listReviewComments() throws IOException {
return new PagedIterable<GHPullRequestReviewComment>() {
public PagedIterator<GHPullRequestReviewComment> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestReviewComment>(root.retrieve().asIterator(getApiRoute() + "/comments",
return new PagedIterator<GHPullRequestReviewComment>(root.retrieve().asIterator(getApiRoute() + COMMENTS_ACTION,
GHPullRequestReviewComment[].class, pageSize)) {
protected void wrapUp(GHPullRequestReviewComment[] page) {
for (GHPullRequestReviewComment c : page)
@@ -296,32 +310,30 @@ public class GHPullRequest extends GHIssue {
};
}
@Preview
@Deprecated
/**
* @deprecated
* Use {@link #createReview()}
*/
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
GHPullRequestReviewComment... comments)
throws IOException {
GHPullRequestReviewComment... comments) throws IOException {
return createReview(body, event, Arrays.asList(comments));
}
@Preview
@Deprecated
/**
* @deprecated
* Use {@link #createReview()}
*/
public GHPullRequestReview createReview(String body, @CheckForNull GHPullRequestReviewState event,
List<GHPullRequestReviewComment> comments)
throws IOException {
// if (event == null) {
// event = GHPullRequestReviewState.PENDING;
// }
List<DraftReviewComment> draftComments = new ArrayList<DraftReviewComment>(comments.size());
List<GHPullRequestReviewComment> comments) throws IOException {
GHPullRequestReviewBuilder b = createReview().body(body);
for (GHPullRequestReviewComment c : comments) {
draftComments.add(new DraftReviewComment(c.getBody(), c.getPath(), c.getPosition()));
b.comment(c.getBody(), c.getPath(), c.getPosition());
}
return new Requester(root).method("POST")
.with("body", body)
//.with("event", event.name())
._with("comments", draftComments)
.withPreview(BLACK_CAT)
.to(getApiRoute() + "/reviews", GHPullRequestReview.class).wrapUp(this);
return b.create();
}
public GHPullRequestReviewBuilder createReview() {
return new GHPullRequestReviewBuilder(this);
}
public GHPullRequestReviewComment createReviewComment(String body, String sha, String path, int position) throws IOException {
@@ -330,7 +342,7 @@ public class GHPullRequest extends GHIssue {
.with("commit_id", sha)
.with("path", path)
.with("position", position)
.to(getApiRoute() + "/comments", GHPullRequestReviewComment.class).wrapUp(this);
.to(getApiRoute() + COMMENTS_ACTION, GHPullRequestReviewComment.class).wrapUp(this);
}
/**
@@ -371,10 +383,10 @@ public class GHPullRequest extends GHIssue {
*/
public void merge(String msg, String sha, MergeMethod method) throws IOException {
new Requester(root).method("PUT")
.with("commit_message",msg)
.with("sha",sha)
.with("merge_method",method)
.to(getApiRoute()+"/merge");
.with("commit_message", msg)
.with("sha", sha)
.with("merge_method", method)
.to(getApiRoute() + "/merge");
}
public enum MergeMethod{ MERGE, SQUASH, REBASE }
@@ -385,28 +397,4 @@ public class GHPullRequest extends GHIssue {
fetchedIssueDetails = true;
}
}
private static class DraftReviewComment {
private String body;
private String path;
private int position;
public DraftReviewComment(String body, String path, int position) {
this.body = body;
this.path = path;
this.position = position;
}
public String getBody() {
return body;
}
public String getPath() {
return path;
}
public int getPosition() {
return position;
}
}
}

View File

@@ -23,17 +23,19 @@
*/
package org.kohsuke.github;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import javax.annotation.CheckForNull;
import java.io.IOException;
import java.net.URL;
import static org.kohsuke.github.Previews.*;
/**
* Review to the pull request
* Review to a pull request.
*
* @see GHPullRequest#listReviews()
* @see GHPullRequest#createReview(String, GHPullRequestReviewState, GHPullRequestReviewComment...)
* @see GHPullRequestReviewBuilder
*/
@SuppressFBWarnings(value = {"UWF_UNWRITTEN_FIELD"}, justification = "JSON API")
public class GHPullRequestReview extends GHObject {
GHPullRequest owner;
@@ -72,6 +74,7 @@ public class GHPullRequestReview extends GHObject {
return commit_id;
}
@CheckForNull
public GHPullRequestReviewState getState() {
return state;
}
@@ -85,41 +88,41 @@ public class GHPullRequestReview extends GHObject {
return owner.getApiRoute()+"/reviews/"+id;
}
/**
* @deprecated
* Former preview method that changed when it got public. Left here for backward compatibility.
* Use {@link #submit(String, GHPullRequestReviewEvent)}
*/
public void submit(String body, GHPullRequestReviewState state) throws IOException {
submit(body,state.toEvent());
}
/**
* Updates the comment.
*/
@Preview
@Deprecated
public void submit(String body, GHPullRequestReviewState event) throws IOException {
public void submit(String body, GHPullRequestReviewEvent event) throws IOException {
new Requester(owner.root).method("POST")
.with("body", body)
.with("event", event.action())
.withPreview("application/vnd.github.black-cat-preview+json")
.to(getApiRoute()+"/events",this);
this.body = body;
this.state = event;
this.state = event.toState();
}
/**
* Deletes this review.
*/
@Preview
@Deprecated
public void delete() throws IOException {
new Requester(owner.root).method("DELETE")
.withPreview(BLACK_CAT)
.to(getApiRoute());
}
/**
* Dismisses this review.
*/
@Preview
@Deprecated
public void dismiss(String message) throws IOException {
new Requester(owner.root).method("PUT")
.with("message", message)
.withPreview(BLACK_CAT)
.to(getApiRoute()+"/dismissals");
state = GHPullRequestReviewState.DISMISSED;
}
@@ -127,14 +130,11 @@ public class GHPullRequestReview extends GHObject {
/**
* Obtains all the review comments associated with this pull request review.
*/
@Preview
@Deprecated
public PagedIterable<GHPullRequestReviewComment> listReviewComments() throws IOException {
return new PagedIterable<GHPullRequestReviewComment>() {
public PagedIterator<GHPullRequestReviewComment> _iterator(int pageSize) {
return new PagedIterator<GHPullRequestReviewComment>(
owner.root.retrieve()
.withPreview(BLACK_CAT)
.asIterator(getApiRoute() + "/comments",
GHPullRequestReviewComment[].class, pageSize)) {
protected void wrapUp(GHPullRequestReviewComment[] page) {
@@ -145,5 +145,4 @@ public class GHPullRequestReview extends GHObject {
}
};
}
}

View File

@@ -0,0 +1,91 @@
package org.kohsuke.github;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Builds up a creation of new {@link GHPullRequestReview}.
*
* @author Kohsuke Kawaguchi
* @see GHPullRequest#createReview()
*/
public class GHPullRequestReviewBuilder {
private final GHPullRequest pr;
private final Requester builder;
private final List<DraftReviewComment> comments = new ArrayList<DraftReviewComment>();
/*package*/ GHPullRequestReviewBuilder(GHPullRequest pr) {
this.pr = pr;
this.builder = new Requester(pr.root);
}
// public GHPullRequestReview createReview(@Nullable String commitId, String body, GHPullRequestReviewEvent event,
// List<GHPullRequestReviewComment> comments) throws IOException
/**
* The SHA of the commit that needs a review. Not using the latest commit SHA may render your review comment outdated if a subsequent commit modifies the line you specify as the position. Defaults to the most recent commit in the pull request when you do not specify a value.
*/
public GHPullRequestReviewBuilder commitId(String commitId) {
builder.with("commit_id",commitId);
return this;
}
/**
* Required when using REQUEST_CHANGES or COMMENT for the event parameter. The body text of the pull request review.
*/
public GHPullRequestReviewBuilder body(String body) {
builder.with("body",body);
return this;
}
/**
* The review action you want to perform. The review actions include: APPROVE, REQUEST_CHANGES, or COMMENT.
* By leaving this blank, you set the review action state to PENDING,
* which means you will need to {@linkplain GHPullRequestReview#submit() submit the pull request review} when you are ready.
*/
public GHPullRequestReviewBuilder event(GHPullRequestReviewEvent event) {
builder.with("event",event.action());
return this;
}
/**
* @param body The relative path to the file that necessitates a review comment.
* @param path The position in the diff where you want to add a review comment. Note this value is not the same as the line number in the file. For help finding the position value, read the note below.
* @param position Text of the review comment.
*/
public GHPullRequestReviewBuilder comment(String body, String path, int position) {
comments.add(new DraftReviewComment(body,path,position));
return this;
}
public GHPullRequestReview create() throws IOException {
return builder.method("POST")._with("comments",comments)
.to(pr.getApiRoute() + "/reviews", GHPullRequestReview.class)
.wrapUp(pr);
}
private static class DraftReviewComment {
private String body;
private String path;
private int position;
DraftReviewComment(String body, String path, int position) {
this.body = body;
this.path = path;
this.position = position;
}
public String getBody() {
return body;
}
public String getPath() {
return path;
}
public int getPosition() {
return position;
}
}
}

View File

@@ -25,6 +25,7 @@ package org.kohsuke.github;
import java.io.IOException;
import java.net.URL;
import javax.annotation.CheckForNull;
import static org.kohsuke.github.Previews.*;
@@ -41,9 +42,15 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
private String body;
private GHUser user;
private String path;
private int position;
private int originalPosition;
private int position = -1;
private int original_position = -1;
private long in_reply_to_id = -1L;
/**
* @deprecated
* You should be using {@link GHPullRequestReviewBuilder#comment(String, String, int)}
*/
public static GHPullRequestReviewComment draft(String body, String path, int position) {
GHPullRequestReviewComment result = new GHPullRequestReviewComment();
result.body = body;
@@ -82,12 +89,18 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
return path;
}
@CheckForNull
public int getPosition() {
return position;
}
public int getOriginalPosition() {
return originalPosition;
return original_position;
}
@CheckForNull
public long getInReplyToId() {
return in_reply_to_id;
}
@Override
@@ -114,6 +127,17 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
new Requester(owner.root).method("DELETE").to(getApiRoute());
}
/**
* Create a new comment that replies to this comment.
*/
public GHPullRequestReviewComment reply(String body) throws IOException {
return new Requester(owner.root).method("POST")
.with("body", body)
.with("in_reply_to", getId())
.to(getApiRoute() + "/comments", GHPullRequestReviewComment.class)
.wrapUp(owner);
}
@Preview @Deprecated
public GHReaction createReaction(ReactionContent content) throws IOException {
return new Requester(owner.root)
@@ -126,7 +150,7 @@ public class GHPullRequestReviewComment extends GHObject implements Reactable {
public PagedIterable<GHReaction> listReactions() {
return new PagedIterable<GHReaction>() {
public PagedIterator<GHReaction> _iterator(int pageSize) {
return new PagedIterator<GHReaction>(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute()+"/reactions", GHReaction[].class, pageSize)) {
return new PagedIterator<GHReaction>(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute() + "/reactions", GHReaction[].class, pageSize)) {
@Override
protected void wrapUp(GHReaction[] page) {
for (GHReaction c : page)

View File

@@ -0,0 +1,51 @@
/*
* The MIT License
*
* Copyright (c) 2011, Eric Maupin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.kohsuke.github;
/**
* Action to perform on {@link GHPullRequestReview}.
*/
public enum GHPullRequestReviewEvent {
PENDING,
APPROVE,
REQUEST_CHANGES,
COMMENT;
/*package*/ String action() {
return this==PENDING ? null : name();
}
/**
* When a {@link GHPullRequestReview} is submitted with this event, it should transition to this state.
*/
/*package*/ GHPullRequestReviewState toState() {
switch (this) {
case PENDING: return GHPullRequestReviewState.PENDING;
case APPROVE: return GHPullRequestReviewState.APPROVED;
case REQUEST_CHANGES: return GHPullRequestReviewState.CHANGES_REQUESTED;
case COMMENT: return GHPullRequestReviewState.COMMENTED;
}
throw new IllegalStateException();
}
}

View File

@@ -1,19 +1,39 @@
package org.kohsuke.github;
/**
* Current state of {@link GHPullRequestReview}
*/
public enum GHPullRequestReviewState {
PENDING(null),
APPROVED("APPROVE"),
REQUEST_CHANGES("REQUEST_CHANGES"),
COMMENTED("COMMENT"),
DISMISSED(null);
PENDING,
APPROVED,
CHANGES_REQUESTED,
/**
* @deprecated
* This was the thing when this API was in preview, but it changed when it became public.
* Use {@link #CHANGES_REQUESTED}. Left here for compatibility.
*/
REQUEST_CHANGES,
COMMENTED,
DISMISSED;
private final String _action;
GHPullRequestReviewState(String action) {
_action = action;
/**
* @deprecated
* This was an internal method accidentally exposed.
* Left here for compatibility.
*/
public String action() {
GHPullRequestReviewEvent e = toEvent();
return e==null ? null : e.action();
}
public String action() {
return _action;
/*package*/ GHPullRequestReviewEvent toEvent() {
switch (this) {
case PENDING: return GHPullRequestReviewEvent.PENDING;
case APPROVED: return GHPullRequestReviewEvent.APPROVE;
case CHANGES_REQUESTED: return GHPullRequestReviewEvent.REQUEST_CHANGES;
case REQUEST_CHANGES: return GHPullRequestReviewEvent.REQUEST_CHANGES;
case COMMENTED: return GHPullRequestReviewEvent.COMMENT;
}
return null;
}
}

View File

@@ -173,6 +173,14 @@ public class GHRepository extends GHObject {
* Gets the HTTPS URL to this repository, such as "https://github.com/kohsuke/jenkins.git"
* This URL is read-only.
*/
public String getHttpTransportUrl() {
return clone_url;
}
/**
* @deprecated
* Typo of {@link #getHttpTransportUrl()}
*/
public String gitHttpTransportUrl() {
return clone_url;
}

View File

@@ -18,6 +18,18 @@ public class GHTeam {
protected /*final*/ GHOrganization org;
/** Member's role in a team */
public enum Role {
/**
* A normal member of the team
*/
MEMBER,
/**
* Able to add/remove other team members, promote other team members to team maintainer, and edit the team's name and description.
*/
MAINTAINER
}
/*package*/ GHTeam wrapUp(GHOrganization owner) {
this.org = owner;
return this;
@@ -116,6 +128,22 @@ public class GHTeam {
org.root.retrieve().method("PUT").to(api("/memberships/" + u.getLogin()), null);
}
/**
* Adds a member to the team
*
* The user will be invited to the organization if required.
*
* @param user github user
* @param role role for the new member
*
* @throws IOException
*/
public void add(GHUser user, Role role) throws IOException {
org.root.retrieve().method("PUT")
.with("role", role.name())
.to(api("/memberships/" + user.getLogin()), null);
}
/**
* Removes a member to the team.
*/
@@ -129,7 +157,7 @@ public class GHTeam {
public void add(GHRepository r, GHOrganization.Permission permission) throws IOException {
org.root.retrieve().method("PUT")
.with("permission",permission)
.with("permission", permission)
.to(api("/repos/" + r.getOwnerName() + '/' + r.getName()), null);
}
@@ -145,7 +173,7 @@ public class GHTeam {
}
private String api(String tail) {
return "/teams/"+id+tail;
return "/teams/" + id + tail;
}
public GHOrganization getOrganization() {

View File

@@ -48,7 +48,6 @@ import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -424,6 +423,9 @@ public class GitHub {
return u;
}
/**
* Gets {@link GHOrganization} specified by name.
*/
public GHOrganization getOrganization(String name) throws IOException {
GHOrganization o = orgs.get(name);
if (o==null) {
@@ -433,6 +435,35 @@ public class GitHub {
return o;
}
/**
* Gets a list of all organizations.
*/
public PagedIterable<GHOrganization> listOrganizations() {
return listOrganizations(null);
}
/**
* Gets a list of all organizations starting after the organization identifier specified by 'since'.
*
* @see <a href="https://developer.github.com/v3/orgs/#parameters">List All Orgs - Parameters</a>
*/
public PagedIterable<GHOrganization> listOrganizations(final String since) {
return new PagedIterable<GHOrganization>() {
@Override
public PagedIterator<GHOrganization> _iterator(int pageSize) {
System.out.println("page size: " + pageSize);
return new PagedIterator<GHOrganization>(retrieve().with("since",since)
.asIterator("/organizations", GHOrganization[].class, pageSize)) {
@Override
protected void wrapUp(GHOrganization[] page) {
for (GHOrganization c : page)
c.wrapUp(GitHub.this);
}
};
}
};
}
/**
* Gets the repository object from 'user/reponame' string that GitHub calls as "repository name"
*

View File

@@ -8,5 +8,4 @@ package org.kohsuke.github;
static final String DRAX = "application/vnd.github.drax-preview+json";
static final String SQUIRREL_GIRL = "application/vnd.github.squirrel-girl-preview";
static final String CLOAK = "application/vnd.github.cloak-preview";
static final String BLACK_CAT = "application/vnd.github.black-cat-preview+json";
}

View File

@@ -54,16 +54,17 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import static java.util.Arrays.*;
import static java.util.logging.Level.*;
import static org.apache.commons.lang.StringUtils.*;
import static org.kohsuke.github.GitHub.*;
import static java.util.Arrays.asList;
import static java.util.logging.Level.FINE;
import static java.util.logging.Level.FINEST;
import static java.util.logging.Level.INFO;
import static org.apache.commons.lang.StringUtils.defaultString;
import static org.kohsuke.github.GitHub.MAPPER;
/**
* A builder pattern for making HTTP call and parsing its output.
@@ -134,6 +135,10 @@ class Requester {
return _with(key, value);
}
public Requester with(String key, long value) {
return _with(key, value);
}
public Requester with(String key, Integer value) {
if (value!=null)
_with(key, value);
@@ -452,7 +457,7 @@ class Requester {
try {
return new PagingIterator<T>(type, tailApiUrl, root.getApiURL(s.toString()));
} catch (IOException e) {
throw new Error(e);
throw new GHException("Unable to build github Api URL",e);
}
}
@@ -513,7 +518,7 @@ class Requester {
}
}
} catch (IOException e) {
throw new Error(e);
throw new GHException("Failed to retrieve "+url);
}
}

View File

@@ -187,13 +187,61 @@ public class GHEventPayloadTest {
assertThat(event.getSender().getLogin(), is("baxterthehacker"));
}
// TODO implement support classes and write test
// @Test
// public void pull_request_review() throws Exception {}
@Test
public void pull_request_review() throws Exception {
GHEventPayload.PullRequestReview event =
GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.PullRequestReview.class);
assertThat(event.getAction(), is("submitted"));
assertThat(event.getReview().getId(), is(2626884L));
assertThat(event.getReview().getBody(), is("Looks great!\n"));
assertThat(event.getReview().getState(), is(GHPullRequestReviewState.APPROVED));
assertThat(event.getPullRequest().getNumber(), is(8));
assertThat(event.getPullRequest().getTitle(), is("Add a README description"));
assertThat(event.getPullRequest().getBody(), is("Just a few more details"));
assertThat(event.getPullRequest().getUser().getLogin(), is("skalnik"));
assertThat(event.getPullRequest().getHead().getUser().getLogin(), is("skalnik"));
assertThat(event.getPullRequest().getHead().getRef(), is("patch-2"));
assertThat(event.getPullRequest().getHead().getLabel(), is("skalnik:patch-2"));
assertThat(event.getPullRequest().getHead().getSha(), is("b7a1f9c27caa4e03c14a88feb56e2d4f7500aa63"));
assertThat(event.getPullRequest().getBase().getUser().getLogin(), is("baxterthehacker"));
assertThat(event.getPullRequest().getBase().getRef(), is("master"));
assertThat(event.getPullRequest().getBase().getLabel(), is("baxterthehacker:master"));
assertThat(event.getPullRequest().getBase().getSha(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b"));
assertThat(event.getRepository().getName(), is("public-repo"));
assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker"));
assertThat(event.getSender().getLogin(), is("baxterthehacker"));
}
// TODO implement support classes and write test
// @Test
// public void pull_request_review_comment() throws Exception {}
@Test
public void pull_request_review_comment() throws Exception {
GHEventPayload.PullRequestReviewComment event =
GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.PullRequestReviewComment.class);
assertThat(event.getAction(), is("created"));
assertThat(event.getComment().getBody(), is("Maybe you should use more emojji on this line."));
assertThat(event.getPullRequest().getNumber(), is(1));
assertThat(event.getPullRequest().getTitle(), is("Update the README with new information"));
assertThat(event.getPullRequest().getBody(), is("This is a pretty simple change that we need to pull into master."));
assertThat(event.getPullRequest().getUser().getLogin(), is("baxterthehacker"));
assertThat(event.getPullRequest().getHead().getUser().getLogin(), is("baxterthehacker"));
assertThat(event.getPullRequest().getHead().getRef(), is("changes"));
assertThat(event.getPullRequest().getHead().getLabel(), is("baxterthehacker:changes"));
assertThat(event.getPullRequest().getHead().getSha(), is("0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c"));
assertThat(event.getPullRequest().getBase().getUser().getLogin(), is("baxterthehacker"));
assertThat(event.getPullRequest().getBase().getRef(), is("master"));
assertThat(event.getPullRequest().getBase().getLabel(), is("baxterthehacker:master"));
assertThat(event.getPullRequest().getBase().getSha(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b"));
assertThat(event.getRepository().getName(), is("public-repo"));
assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker"));
assertThat(event.getSender().getLogin(), is("baxterthehacker"));
}
@Test
public void push() throws Exception {

View File

@@ -5,11 +5,14 @@ import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Iterables;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
@@ -155,4 +158,16 @@ public class GitHubTest {
System.out.println(u.getName());
}
}
@Test
public void getOrgs() throws IOException {
GitHub hub = GitHub.connect();
int iterations = 10;
Set<Long> orgIds = new HashSet<Long>();
for (GHOrganization org : Iterables.limit(hub.listOrganizations().withPageSize(2), iterations)) {
orgIds.add(org.getId());
System.out.println(org.getName());
}
assertThat(orgIds.size(), equalTo(iterations));
}
}

View File

@@ -7,8 +7,7 @@ import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.*;
/**
* @author Kohsuke Kawaguchi
@@ -33,9 +32,10 @@ public class PullRequestTest extends AbstractGitHubApiTestBase {
public void testPullRequestReviews() throws Exception {
String name = rnd.next();
GHPullRequest p = getRepository().createPullRequest(name, "stable", "master", "## test");
GHPullRequestReview draftReview = p.createReview("Some draft review", null,
GHPullRequestReviewComment.draft("Some niggle", "changelog.html", 1)
);
GHPullRequestReview draftReview = p.createReview()
.body("Some draft review")
.comment("Some niggle", "changelog.html", 1)
.create();
assertThat(draftReview.getState(), is(GHPullRequestReviewState.PENDING));
assertThat(draftReview.getBody(), is("Some draft review"));
assertThat(draftReview.getCommitId(), notNullValue());
@@ -45,15 +45,16 @@ public class PullRequestTest extends AbstractGitHubApiTestBase {
assertThat(review.getState(), is(GHPullRequestReviewState.PENDING));
assertThat(review.getBody(), is("Some draft review"));
assertThat(review.getCommitId(), notNullValue());
review.submit("Some review comment", GHPullRequestReviewState.COMMENTED);
draftReview.submit("Some review comment", GHPullRequestReviewEvent.COMMENT);
List<GHPullRequestReviewComment> comments = review.listReviewComments().asList();
assertEquals(1, comments.size());
GHPullRequestReviewComment comment = comments.get(0);
assertEquals("Some niggle", comment.getBody());
review = p.createReview("Some new review", null,
GHPullRequestReviewComment.draft("Some niggle", "changelog.html", 1)
);
review.delete();
draftReview = p.createReview()
.body("Some new review")
.comment("Some niggle", "changelog.html", 1)
.create();
draftReview.delete();
}
@Test

View File

@@ -5,7 +5,7 @@
"user": {
"login": "baxterthehacker",
"id": 6752317,
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3",
"avatar_url": "https://avatars3.githubusercontent.com/u/6752317?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/baxterthehacker",
"html_url": "https://github.com/baxterthehacker",
@@ -21,11 +21,11 @@
"type": "User",
"site_admin": false
},
"body": "Looks great!",
"submitted_at": "2016-10-03T23:39:09Z",
"state": "approved",
"body": "Looks great!\n",
"state": "APPROVED",
"html_url": "https://github.com/baxterthehacker/public-repo/pull/8#pullrequestreview-2626884",
"pull_request_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8",
"author_association": "OWNER",
"_links": {
"html": {
"href": "https://github.com/baxterthehacker/public-repo/pull/8#pullrequestreview-2626884"
@@ -33,7 +33,9 @@
"pull_request": {
"href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8"
}
}
},
"submitted_at": "2016-10-03T23:39:09Z",
"commit_id": "b7a1f9c27caa4e03c14a88feb56e2d4f7500aa63"
},
"pull_request": {
"url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8",