use of com.github.avano.pr.workflow.message.ConflictMessage in project pull-request-workflow by avano.
the class ConflictHandler method checkForConflict.
/**
* Checks if a PR merge caused conflict in other opened PRs, if so a comment is added to each open PR and it's assigned back to the author to fix.
*
* @param msg {@link BusMessage} instance
*/
@Log
@ConsumeEvent(Constants.PR_CHECK_CONFLICT)
public void checkForConflict(BusMessage msg) {
GHClient client = msg.client();
ConflictMessage cm = msg.get(ConflictMessage.class);
if (client.getRepositoryConfiguration().conflictMessage() == null || client.getRepositoryConfiguration().conflictMessage().isEmpty()) {
LOG.debug("Skipping conflict detection - conflict message not set");
return;
}
for (GHPullRequest openPullRequest : cm.getOpenPullRequests()) {
try {
openPullRequest.refresh();
if ("dirty".equals(openPullRequest.getMergeableState())) {
LOG.info("PR #{}: Caused conflict in PR #{}", cm.getMergedPrId(), openPullRequest.getNumber());
client.postComment(openPullRequest, client.getRepositoryConfiguration().conflictMessage().replace("<ID>", cm.getMergedPrId() + ""));
client.assignToAuthor(openPullRequest);
List<String> removeLabels = new ArrayList<>();
removeLabels.addAll(client.getRepositoryConfiguration().approvedLabels());
removeLabels.addAll(client.getRepositoryConfiguration().reviewRequestedLabels());
eventBus.publish(Constants.EDIT_LABELS, new BusMessage(client, new LabelsMessage(openPullRequest, client.getRepositoryConfiguration().changesRequestedLabels(), removeLabels)));
} else {
LOG.trace("PR #{}: No conflict in PR #{}", cm.getMergedPrId(), openPullRequest.getNumber());
}
} catch (IOException e) {
LOG.error("PR #{}: Unable to process PR", openPullRequest.getNumber(), e);
}
}
}
use of com.github.avano.pr.workflow.message.ConflictMessage in project pull-request-workflow by avano.
the class ConflictHandlerTest method shouldAssignOtherPrToAuthorWhenConflictWasCausedTest.
@Test
public void shouldAssignOtherPrToAuthorWhenConflictWasCausedTest() {
stubFor(WireMock.get(urlEqualTo("/repos/" + TEST_REPO + "/pulls?state=open")).willReturn(ok().withBodyFile("merge/conflict/twoMergeable.json")));
stubFor(WireMock.get(urlPathMatching("/repos/" + TEST_REPO + "/pulls/20")).willReturn(ok().withBodyFile("merge/conflict/20_conflict.json")));
stubFor(WireMock.get(urlPathMatching("/repos/" + TEST_REPO + "/pulls/21")).willReturn(ok().withBodyFile("merge/conflict/21_ok.json")));
stubFor(WireMock.post(urlPathMatching("/repos/" + TEST_REPO + "/issues/\\d+/comments")).willReturn(aResponse().withStatus(201).withBody("{}")));
List<GHPullRequest> pullRequestList = new ArrayList<>();
pullRequestList.add(loadPullRequest(20));
pullRequestList.add(loadPullRequest(21));
ConflictMessage msg = new ConflictMessage(123, pullRequestList);
conflictHandler.checkForConflict(new BusMessage(client, msg));
List<LoggedRequest> requests = getRequests(WireMock.patchRequestedFor(urlPathMatching("/repos/" + TEST_REPO + "/issues/\\d+")));
assertThat(requests).hasSize(1);
assertThat(requests.get(0).getAbsoluteUrl()).endsWith("issues/20");
JSONArray assignees = new JSONObject(requests.get(0).getBodyAsString()).getJSONArray("assignees");
assertThat(assignees).containsExactly("creator");
}
use of com.github.avano.pr.workflow.message.ConflictMessage in project pull-request-workflow by avano.
the class ConflictHandlerTest method shouldNotPostCommentWhenEverythingWasOkTest.
@Test
public void shouldNotPostCommentWhenEverythingWasOkTest() {
stubFor(WireMock.get(urlEqualTo("/repos/" + TEST_REPO + "/pulls?state=open")).willReturn(ok().withBodyFile("merge/conflict/twoMergeable.json")));
stubFor(WireMock.get(urlPathMatching("/repos/" + TEST_REPO + "/pulls/20")).willReturn(ok().withBodyFile("merge/conflict/20_ok.json")));
stubFor(WireMock.get(urlPathMatching("/repos/" + TEST_REPO + "/pulls/21")).willReturn(ok().withBodyFile("merge/conflict/21_ok.json")));
stubFor(WireMock.post(urlPathMatching("/repos/" + TEST_REPO + "/issues/\\d+/comments")).willReturn(aResponse().withStatus(201).withBody("{}")));
List<GHPullRequest> pullRequestList = new ArrayList<>();
pullRequestList.add(loadPullRequest(20));
pullRequestList.add(loadPullRequest(21));
ConflictMessage msg = new ConflictMessage(123, pullRequestList);
conflictHandler.checkForConflict(new BusMessage(client, msg));
List<LoggedRequest> requests = getRequests(WireMock.postRequestedFor(urlPathMatching("/repos/" + TEST_REPO + "/issues/\\d+/comments")));
assertThat(requests).isEmpty();
}
use of com.github.avano.pr.workflow.message.ConflictMessage in project pull-request-workflow by avano.
the class ConflictHandlerTest method shouldPostCommentWhenCausedConflictTest.
@Test
public void shouldPostCommentWhenCausedConflictTest() {
stubFor(WireMock.get(urlEqualTo("/repos/" + TEST_REPO + "/pulls?state=open")).willReturn(ok().withBodyFile("merge/conflict/twoMergeable.json")));
stubFor(WireMock.get(urlPathMatching("/repos/" + TEST_REPO + "/pulls/20")).willReturn(ok().withBodyFile("merge/conflict/20_conflict.json")));
stubFor(WireMock.get(urlPathMatching("/repos/" + TEST_REPO + "/pulls/21")).willReturn(ok().withBodyFile("merge/conflict/21_ok.json")));
stubFor(WireMock.post(urlEqualTo("/repos/" + TEST_REPO + "/issues/20/comments")).willReturn(aResponse().withStatus(201).withBody("{}")));
List<GHPullRequest> pullRequestList = new ArrayList<>();
pullRequestList.add(loadPullRequest(20));
pullRequestList.add(loadPullRequest(21));
ConflictMessage msg = new ConflictMessage(123, pullRequestList);
conflictHandler.checkForConflict(new BusMessage(client, msg));
List<LoggedRequest> requests = getRequests(WireMock.postRequestedFor(urlPathMatching("/repos/" + TEST_REPO + "/issues/\\d+/comments")));
assertThat(requests).hasSize(1);
assertThat(requests.get(0).getAbsoluteUrl()).endsWith("issues/20/comments");
assertThat(new JSONObject(requests.get(0).getBodyAsString()).getString("body")).isEqualTo(client.getRepositoryConfiguration().conflictMessage().replace("<ID>", 123 + ""));
}
use of com.github.avano.pr.workflow.message.ConflictMessage in project pull-request-workflow by avano.
the class MergeHandler method mergePullRequest.
/**
* Set the reviewers as assignees and merge the pull request.
*
* @param msg {@link BusMessage} instance
*/
private void mergePullRequest(BusMessage msg) {
GHClient client = msg.client();
GHPullRequest pr = msg.get(GHPullRequest.class);
try {
if (!Constants.DEPENDABOT_NAME.equals(client.getAuthor(pr).getLogin())) {
// Assign the PR to all users who provided a review, so that it will be visible who was involved
Set<GHUser> reviewers = client.getReviews(pr).keySet();
reviewers.remove(pr.getUser());
LOG.info("PR #{}: Setting assignees to: {}", pr.getNumber(), reviewers.stream().map(GHPerson::getLogin).collect(Collectors.joining(", ")));
client.setAssignees(pr, reviewers);
}
// Save open PRs so that we can check later if merging this PR caused a conflict in some other PR
List<GHPullRequest> mergeableOpenPullRequests = client.listOpenPullRequests().stream().filter(pullRequest -> {
try {
// Filter out this PR and all that are not mergeable
return pr.getNumber() != pullRequest.getNumber() && pullRequest.getMergeable() != null && pullRequest.getMergeable();
} catch (IOException e) {
LOG.error("PR #{}: Unable to determine mergeable state", pullRequest.getNumber());
}
return false;
}).collect(Collectors.toList());
LOG.info("PR #{}: Merging", pr.getNumber());
pr.merge(client.getRepositoryConfiguration().mergeMessage(), null, client.getRepositoryConfiguration().mergeMethod());
LOG.info("PR #{}: Merged", pr.getNumber());
if (!mergeableOpenPullRequests.isEmpty()) {
eventBus.publish(Constants.PR_CHECK_CONFLICT, new BusMessage(client, new ConflictMessage(pr.getNumber(), mergeableOpenPullRequests)));
}
} catch (IOException e) {
LOG.error("PR #{}: Unable to process merge", pr.getNumber(), e);
}
}
Aggregations