Skip to content

Commit

Permalink
Add support for multiline review comments (#1833)
Browse files Browse the repository at this point in the history
* Add support for multi-line review comments

On review comments or during the creation of a new review, support single and multi-line
comments using `line` and `start_line` attributes.

See: https://docs.github.com/en/rest/pulls/comments?apiVersion=2022-11-28#create-a-review-comment-for-a-pull-request
and https://docs.github.com/en/rest/pulls/reviews?apiVersion=2022-11-28#create-a-review-for-a-pull-request

* Add tests for multi-line review comments

* Fix tests for multi-line comments on pull requests

* Add builder to create review comments

* Improve PR review comments implementation

* Update src/main/java/org/kohsuke/github/GHPullRequestReviewCommentBuilder.java

* Update src/main/java/org/kohsuke/github/GHPullRequestReviewCommentBuilder.java

* Update src/main/java/org/kohsuke/github/GHPullRequestReviewCommentBuilder.java

* Fix code formatting

* Update src/test/java/org/kohsuke/github/GHPullRequestTest.java

* Update src/test/java/org/kohsuke/github/GHPullRequestTest.java

---------

Co-authored-by: Maxime Wiewiora <maxime.wiewiora@neofacto.com>
Co-authored-by: Liam Newman <bitwiseman@gmail.com>
  • Loading branch information
3 people committed Jul 1, 2024
1 parent 3e478c2 commit 068b4e6
Show file tree
Hide file tree
Showing 148 changed files with 5,459 additions and 3,539 deletions.
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@
<exclude>org.kohsuke.github.GHCompare.User</exclude>

<!-- TODO: Some coverage, but more needed -->
<exclude>org.kohsuke.github.GHPullRequestReviewBuilder.DraftReviewComment</exclude>
<exclude>org.kohsuke.github.GHIssue.PullRequest</exclude>
<exclude>org.kohsuke.github.GHCommitSearchBuilder</exclude>
<exclude>org.kohsuke.github.GHRepositorySearchBuilder</exclude>
Expand Down
21 changes: 12 additions & 9 deletions src/main/java/org/kohsuke/github/GHPullRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,15 @@ public GHPullRequestReviewBuilder createReview() {
return new GHPullRequestReviewBuilder(this);
}

/**
* Create gh pull request review comment builder.
*
* @return the gh pull request review comment builder.
*/
public GHPullRequestReviewCommentBuilder createReviewComment() {
return new GHPullRequestReviewCommentBuilder(this);
}

/**
* Create review comment gh pull request review comment.
*
Expand All @@ -536,18 +545,12 @@ public GHPullRequestReviewBuilder createReview() {
* @return the gh pull request review comment
* @throws IOException
* the io exception
* @deprecated use {@link #createReviewComment()}
*/
@Deprecated
public GHPullRequestReviewComment createReviewComment(String body, String sha, String path, int position)
throws IOException {
return root().createRequest()
.method("POST")
.with("body", body)
.with("commit_id", sha)
.with("path", path)
.with("position", position)
.withUrlPath(getApiRoute() + COMMENTS_ACTION)
.fetch(GHPullRequestReviewComment.class)
.wrapUp(this);
return createReviewComment().body(body).commitId(sha).path(path).position(position).create();
}

/**
Expand Down
151 changes: 136 additions & 15 deletions src/main/java/org/kohsuke/github/GHPullRequestReviewBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
public class GHPullRequestReviewBuilder {
private final GHPullRequest pr;
private final Requester builder;
private final List<DraftReviewComment> comments = new ArrayList<DraftReviewComment>();
private final List<ReviewComment> comments = new ArrayList<>();

/**
* Instantiates a new GH pull request review builder.
Expand Down Expand Up @@ -75,19 +75,53 @@ public GHPullRequestReviewBuilder event(GHPullRequestReviewEvent event) {
* Comment gh pull request review builder.
*
* @param body
* The relative path to the file that necessitates a review comment.
* Text of the review comment.
* @param path
* The relative path to the file that necessitates a review comment.
* @param position
* 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.
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder comment(String body, String path, int position) {
comments.add(new DraftReviewComment(body, path, position));
return this;
}

/**
* Add a multi-line comment to the gh pull request review builder.
*
* @param body
* Text of the review comment.
* @param path
* The relative path to the file that necessitates a review comment.
* @param startLine
* The first line in the pull request diff that the multi-line comment applies to.
* @param endLine
* The last line of the range that the comment applies to.
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder multiLineComment(String body, String path, int startLine, int endLine) {
this.comments.add(new MultilineDraftReviewComment(body, path, startLine, endLine));
return this;
}

/**
* Add a single line comment to the gh pull request review builder.
*
* @param body
* Text of the review comment.
* @param path
* The relative path to the file that necessitates a review comment.
* @param line
* The line of the blob in the pull request diff that the comment applies to.
* @return the gh pull request review builder
*/
public GHPullRequestReviewBuilder singleLineComment(String body, String path, int line) {
this.comments.add(new SingleLineDraftReviewComment(body, path, line));
return this;
}

/**
* Create gh pull request review.
*
Expand All @@ -103,7 +137,29 @@ public GHPullRequestReview create() throws IOException {
.wrapUp(pr);
}

private static class DraftReviewComment {
/**
* Common properties of the review comments, regardless of how the comment is positioned on the gh pull request.
*/
private interface ReviewComment {
/**
* Gets body.
*
* @return the body.
*/
String getBody();

/**
* Gets path.
*
* @return the path.
*/
String getPath();
}

/**
* Single line comment using the relative position in the diff.
*/
static class DraftReviewComment implements ReviewComment {
private String body;
private String path;
private int position;
Expand All @@ -114,20 +170,10 @@ private static class DraftReviewComment {
this.position = position;
}

/**
* Gets body.
*
* @return the body
*/
public String getBody() {
return body;
}

/**
* Gets path.
*
* @return the path
*/
public String getPath() {
return path;
}
Expand All @@ -141,4 +187,79 @@ public int getPosition() {
return position;
}
}

/**
* Multi-line comment.
*/
static class MultilineDraftReviewComment implements ReviewComment {
private final String body;
private final String path;
private final int line;
private final int start_line;

MultilineDraftReviewComment(final String body, final String path, final int startLine, final int line) {
this.body = body;
this.path = path;
this.line = line;
this.start_line = startLine;
}

public String getBody() {
return this.body;
}

public String getPath() {
return this.path;
}

/**
* Gets end line of the comment.
*
* @return the end line of the comment.
*/
public int getLine() {
return line;
}

/**
* Gets start line of the comment.
*
* @return the start line of the comment.
*/
public int getStartLine() {
return start_line;
}
}

/**
* Single line comment.
*/
static class SingleLineDraftReviewComment implements ReviewComment {
private final String body;
private final String path;
private final int line;

SingleLineDraftReviewComment(final String body, final String path, final int line) {
this.body = body;
this.path = path;
this.line = line;
}

public String getBody() {
return this.body;
}

public String getPath() {
return this.path;
}

/**
* Gets line of the comment.
*
* @return the line of the comment.
*/
public int getLine() {
return line;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.kohsuke.github;

import java.io.IOException;

// TODO: Auto-generated Javadoc

/**
* Builds up a creation of new {@link GHPullRequestReviewComment}.
*
* @see GHPullRequest#createReviewComment()
*/
public class GHPullRequestReviewCommentBuilder {
private final GHPullRequest pr;
private final Requester builder;

/**
* Instantiates a new GH pull request review comment builder.
*
* @param pr
* the pr
*/
GHPullRequestReviewCommentBuilder(GHPullRequest pr) {
this.pr = pr;
this.builder = pr.root().createRequest();
}

/**
* 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.
*
* @param commitId
* the commit id
* @return the gh pull request review comment builder
*/
public GHPullRequestReviewCommentBuilder commitId(String commitId) {
builder.with("commit_id", commitId);
return this;
}

/**
* The text of the pull request review comment.
*
* @param body
* the body
* @return the gh pull request review comment builder
*/
public GHPullRequestReviewCommentBuilder body(String body) {
builder.with("body", body);
return this;
}

/**
* The relative path to the file that necessitates a comment.
*
* @param path
* the path
* @return the gh pull request review comment builder
*/
public GHPullRequestReviewCommentBuilder path(String path) {
builder.with("path", path);
return this;
}

/**
* The position in the diff where you want to add a review comment.
*
* @param position
* the position
* @return the gh pull request review comment builder
* @implNote As position is deprecated in GitHub API, only keep this for internal usage (for retro-compatibility
* with {@link GHPullRequest#createReviewComment(String, String, String, int)}).
*/
GHPullRequestReviewCommentBuilder position(int position) {
builder.with("position", position);
return this;
}

/**
* A single line of the blob in the pull request diff that the comment applies to.
* <p>
* {@link #line(int)} and {@link #lines(int, int)} will overwrite each other's values.
* </p>
*
* @param line
* the line number
* @return the gh pull request review comment builder
*/
public GHPullRequestReviewCommentBuilder line(int line) {
builder.with("line", line);
builder.remove("start_line");
return this;
}

/**
* The range of lines in the pull request diff that this comment applies to.
* <p>
* {@link #line(int)} and {@link #lines(int, int)} will overwrite each other's values.
* </p>
*
* @param startLine
* the start line number of the comment
* @param endLine
* the end line number of the comment
* @return the gh pull request review comment builder
*/
public GHPullRequestReviewCommentBuilder lines(int startLine, int endLine) {
builder.with("start_line", startLine);
builder.with("line", endLine);
return this;
}

/**
* Create gh pull request review comment.
*
* @return the gh pull request review comment builder
* @throws IOException
* the io exception
*/
public GHPullRequestReviewComment create() throws IOException {
return builder.method("POST")
.withUrlPath(pr.getApiRoute() + "/comments")
.fetch(GHPullRequestReviewComment.class)
.wrapUp(pr);
}

}
Loading

0 comments on commit 068b4e6

Please sign in to comment.