Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extend the PostReview REST endpoint to support posting of robot comments. For this ReviewInput got a new field that can contain a list of robot comments. For reading robot comments new REST endpoints have been added. Robot comments are only supported with NoteDb, but not with ReviewDb. Robot comments are always stored as JSON, even if notedb.writeJson is set to false. In NoteDb robot comments are not stored in the change meta ref but in a separate refs/changes/XX/YYYY/robot-comments ref. By storing robot comments in a separate ref we can delete robot comments without rewriting the history of the change meta branch which is needed for auditing and hence cannot be rewritten. Deletion of robot comments is not implemented in this change, but we may want to support this later as the amount and size of robot comments can be large. Draft robot comments are not supported, but robot comments are always published comments. Change-Id: I2d8a5ca59e9a8b2c34863c54a3a9576599f69526 Signed-off-by: Edwin Kempin <ekempin@google.com>
- Loading branch information
1 parent
76b1375
commit 3fde7e4
Showing
46 changed files
with
1,710 additions
and
229 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
= Gerrit Code Review - Robot Comments | ||
|
||
Gerrit has special support for inline comments that are generated by | ||
automated third-party systems, so called "robot comments". For example | ||
robot comments can be used to represent the results of code analyzers. | ||
|
||
In contrast to regular inline comments which are free-text comments, | ||
robot comments are more structured and can contain additional data, | ||
such as a robot ID, a robot run ID and a URL, see | ||
link:rest-api-changes.html#robot-comment-info[RobotCommentInfo] for | ||
details. | ||
|
||
It is planned to visualize robot comments differently in the web UI so | ||
that they can be easily distinguished from human comments. Users should | ||
also be able to use filtering on robot comments, so that only part of | ||
the robot comments or no robot comments are shown. In addition it is | ||
planned that robot comments can contain fixes, that users can apply by | ||
a single click. | ||
|
||
== REST endpoints | ||
|
||
* Posting robot comments is done by the | ||
link:rest-api-changes.html[Set Review] REST endpoint. The | ||
link:rest-api-changes.html#review-input[input] for this REST endpoint | ||
can contain robot comments in its `robot_comments` field. | ||
* link:rest-api-changes.html#list-robot-comments[List Robot Comments] | ||
* link:rest-api-changes.html#get-robot-comment[Get Robot Comment] | ||
|
||
== Storage | ||
|
||
Robot comments are stored per change in a | ||
`refs/changes/XX/YYYY/robot-comments` ref, where `XX/YYYY` is the | ||
sharded change ID. | ||
|
||
Robot comments can be dropped by deleting this ref. | ||
|
||
== Limitations | ||
|
||
* Robot comments are only supported with NoteDb, but not with ReviewDb. | ||
* Robot comments are not displayed in the web UI yet. | ||
* There is no support for draft robot comments, but robot comments are | ||
always published and visible to everyone who can see the change. | ||
|
||
GERRIT | ||
------ | ||
Part of link:index.html[Gerrit Code Review] | ||
|
||
SEARCHBOX | ||
--------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
130 changes: 130 additions & 0 deletions
130
...ptance-tests/src/test/java/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// Copyright (C) 2016 The Android Open Source Project | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package com.google.gerrit.acceptance.api.revision; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
import static com.google.common.truth.TruthJUnit.assume; | ||
import static com.google.gerrit.acceptance.PushOneCommit.FILE_NAME; | ||
|
||
import com.google.common.collect.Iterables; | ||
import com.google.gerrit.acceptance.AbstractDaemonTest; | ||
import com.google.gerrit.acceptance.PushOneCommit; | ||
import com.google.gerrit.extensions.api.changes.ReviewInput; | ||
import com.google.gerrit.extensions.api.changes.ReviewInput.RobotCommentInput; | ||
import com.google.gerrit.extensions.common.RobotCommentInfo; | ||
import com.google.gerrit.extensions.restapi.MethodNotAllowedException; | ||
|
||
import org.junit.Test; | ||
|
||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class RobotCommentsIT extends AbstractDaemonTest { | ||
@Test | ||
public void comments() throws Exception { | ||
assume().that(notesMigration.enabled()).isTrue(); | ||
|
||
PushOneCommit.Result r = createChange(); | ||
RobotCommentInput in = createRobotCommentInput(); | ||
ReviewInput reviewInput = new ReviewInput(); | ||
Map<String, List<RobotCommentInput>> robotComments = new HashMap<>(); | ||
robotComments.put(in.path, Collections.singletonList(in)); | ||
reviewInput.robotComments = robotComments; | ||
reviewInput.message = "comment test"; | ||
gApi.changes() | ||
.id(r.getChangeId()) | ||
.current() | ||
.review(reviewInput); | ||
|
||
Map<String, List<RobotCommentInfo>> out = gApi.changes() | ||
.id(r.getChangeId()) | ||
.revision(r.getCommit().name()) | ||
.robotComments(); | ||
assertThat(out).hasSize(1); | ||
RobotCommentInfo comment = Iterables.getOnlyElement(out.get(in.path)); | ||
assertRobotComment(comment, in, false); | ||
|
||
List<RobotCommentInfo> list = gApi.changes() | ||
.id(r.getChangeId()) | ||
.revision(r.getCommit().name()) | ||
.robotCommentsAsList(); | ||
assertThat(list).hasSize(1); | ||
|
||
RobotCommentInfo comment2 = list.get(0); | ||
assertRobotComment(comment2, in); | ||
|
||
RobotCommentInfo comment3 = gApi.changes() | ||
.id(r.getChangeId()) | ||
.revision(r.getCommit().name()) | ||
.robotComment(comment.id) | ||
.get(); | ||
assertRobotComment(comment3, in); | ||
} | ||
|
||
@Test | ||
public void robotCommentsNotSupported() throws Exception { | ||
assume().that(notesMigration.enabled()).isFalse(); | ||
|
||
PushOneCommit.Result r = createChange(); | ||
RobotCommentInput in = createRobotCommentInput(); | ||
ReviewInput reviewInput = new ReviewInput(); | ||
Map<String, List<RobotCommentInput>> robotComments = new HashMap<>(); | ||
robotComments.put(FILE_NAME, Collections.singletonList(in)); | ||
reviewInput.robotComments = robotComments; | ||
reviewInput.message = "comment test"; | ||
|
||
exception.expect(MethodNotAllowedException.class); | ||
exception.expectMessage("robot comments not supported"); | ||
gApi.changes() | ||
.id(r.getChangeId()) | ||
.current() | ||
.review(reviewInput); | ||
} | ||
|
||
private RobotCommentInput createRobotCommentInput() { | ||
RobotCommentInput in = new RobotCommentInput(); | ||
in.robotId = "happyRobot"; | ||
in.robotRunId = "1"; | ||
in.url = "http://www.happy-robot.com"; | ||
in.line = 1; | ||
in.message = "nit: trailing whitespace"; | ||
in.path = FILE_NAME; | ||
return in; | ||
} | ||
|
||
private void assertRobotComment(RobotCommentInfo c, | ||
RobotCommentInput expected) { | ||
assertRobotComment(c, expected, true); | ||
} | ||
|
||
private void assertRobotComment(RobotCommentInfo c, | ||
RobotCommentInput expected, boolean expectPath) { | ||
assertThat(c.robotId).isEqualTo(expected.robotId); | ||
assertThat(c.robotRunId).isEqualTo(expected.robotRunId); | ||
assertThat(c.url).isEqualTo(expected.url); | ||
assertThat(c.line).isEqualTo(expected.line); | ||
assertThat(c.message).isEqualTo(expected.message); | ||
|
||
assertThat(c.author.email).isEqualTo(admin.email); | ||
|
||
if (expectPath) { | ||
assertThat(c.path).isEqualTo(expected.path); | ||
} else { | ||
assertThat(c.path).isNull(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.