use of com.github.avano.pr.workflow.message.BusMessage in project pull-request-workflow by avano.
the class CheckHandler method tryToMergePrWithSha.
/**
* Tries to merge all PRs where the given commit is HEAD of the PR.
*
* @param client {@link GHClient} instance
* @param sha commit sha
*/
private void tryToMergePrWithSha(GHClient client, String sha) {
// Check if this SHA is a HEAD of some PR
List<GHPullRequest> pullRequestList = client.getPullRequests(sha);
if (pullRequestList != null && pullRequestList.size() > 0) {
for (GHPullRequest pr : pullRequestList) {
LOG.debug("Commit {}: This commit is head of PR #{}", sha, pr.getNumber());
eventBus.publish(Constants.PR_MERGE, new BusMessage(client, pr));
}
} else {
LOG.info("Commit {}: This commit isn't the HEAD of any PR, ignoring its status change", sha);
}
}
use of com.github.avano.pr.workflow.message.BusMessage 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.BusMessage in project pull-request-workflow by avano.
the class LifecycleHandler method handlePrUpdated.
/**
* Handles the
* <a href="https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request">pull request</a>
* synchronized event.
* <p>
* When the PR is updated (new commits are pushed to the PR), it dismisses all reviews, clears internal tracking and set the labels and
* assignees to the correct state.
* <p>
* All users with a review on the PR will be assigned to the PR and re-requested for review.
*
* @param msg {@link BusMessage} instance
*/
@Log
@ConsumeEvent(Constants.PR_UPDATED)
public void handlePrUpdated(BusMessage msg) {
GHClient client = msg.client();
GHPullRequest pr = msg.get(GHPullRequest.class);
LOG.info("PR #{}: Pull request updated - dismissing all reviews", pr.getNumber());
// Dismiss all approved/changes requested reviews, since the PR was updated
try {
pr.listReviews().toList().stream().filter(r -> r.getState() == GHPullRequestReviewState.APPROVED || r.getState() == GHPullRequestReviewState.CHANGES_REQUESTED).forEach(r -> {
try {
r.dismiss(client.getRepositoryConfiguration().reviewDismissMessage());
} catch (IOException e) {
LOG.error("PR #{}: Unable to dismiss review: " + e, pr.getNumber());
}
});
} catch (IOException e) {
LOG.error("PR #{}: Unable to list all pull request reviews: " + e, pr.getNumber());
}
// Re-apply labels to current state
List<String> addLabels = new ArrayList<>();
List<String> removeLabels = new ArrayList<>();
Map<GHUser, GHPullRequestReviewState> reviews = client.getReviews(pr);
if (!reviews.isEmpty()) {
// Request review from all previous reviewers (except for the author of the PR - if he responds to some comment, it is counted as
// "commented" review)
// Set the assignees back to requested reviewers
// Don't add "review requested labels", as that will be done by the "review requested" event
List<GHUser> reviewers = reviews.keySet().stream().filter(u -> !u.equals(client.getAuthor(pr))).collect(Collectors.toList());
client.requestReviewers(pr, reviewers);
client.setAssignees(pr, reviewers);
}
removeLabels.addAll(client.getRepositoryConfiguration().changesRequestedLabels());
removeLabels.addAll(client.getRepositoryConfiguration().approvedLabels());
removeLabels.addAll(client.getRepositoryConfiguration().commentedLabels());
eventBus.publish(Constants.EDIT_LABELS, new BusMessage(client, new LabelsMessage(pr, addLabels, removeLabels)));
}
use of com.github.avano.pr.workflow.message.BusMessage in project pull-request-workflow by avano.
the class ReviewSubmittedHandler method handleReview.
/**
* Handles the
* <a href="https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#pull_request_review">pull request review</a> submitted event.
* <p>
* When the user provided a review, he is removed from the assignee list.
* <p>
* When the PR is approved and there are no changes-requested reviews from other reviewers, approved label is added to the PR and it is tried
* to merge the PR, otherwise the approved review is ignored.
* <p>
* When changes are requested, the PR is assigned back to author and corresponding label is added and approved label is removed.
* <p>
* When the PR is commented (not only PR's "comment only" action, but also all conversation), commented label is applied and if the author of
* the comment is in the assignees list, he is removed (as he provided a "review")
*
* @param msg {@link BusMessage} instance
*/
@Log
@ConsumeEvent(Constants.PR_REVIEW_SUBMITTED)
public void handleReview(BusMessage msg) {
GHClient client = msg.client();
GHPullRequestReview review = msg.get(GHPullRequestReview.class);
GHPullRequest pr = msg.get(BusMessage.INFO_PR_KEY, GHPullRequest.class);
List<String> addLabels = new ArrayList<>();
List<String> removeLabels = new ArrayList<>();
switch(review.getState()) {
case APPROVED:
LOG.info("PR #{}: Approved by {}", pr.getNumber(), msg.getSender().getLogin());
List<GHUser> assignees = new ArrayList<>(pr.getAssignees());
if (assignees.contains(msg.getSender())) {
assignees.remove(msg.getSender());
LOG.info("PR #{}: Removing {} from assignees", pr.getNumber(), msg.getSender().getLogin());
client.setAssignees(pr, assignees);
} else {
LOG.debug("PR #{}: {} wasn't in assignees list and provided a review", pr.getNumber(), msg.getSender().getLogin());
}
// Only add approved label if there are no "changes required" reviews left
if (!client.changesRequested(pr)) {
addLabels.addAll(client.getRepositoryConfiguration().approvedLabels());
removeLabels.addAll(client.getRepositoryConfiguration().changesRequestedLabels());
eventBus.publish(Constants.CHECK_RUN_CREATE, new BusMessage(client, new CheckRunMessage(pr, GHCheckRun.Status.COMPLETED, GHCheckRun.Conclusion.SUCCESS)));
}
// Review was provided, dismiss review requested label
removeLabels.addAll(client.getRepositoryConfiguration().reviewRequestedLabels());
eventBus.publish(Constants.EDIT_LABELS, new BusMessage(client, new LabelsMessage(pr, addLabels, removeLabels)));
// Don't merge here, it will be handled by the checkrun event
break;
case CHANGES_REQUESTED:
LOG.info("PR #{}: Changes requested by {}", pr.getNumber(), msg.getSender().getLogin());
client.assignToAuthor(pr);
eventBus.publish(Constants.CHECK_RUN_CREATE, new BusMessage(client, new CheckRunMessage(pr, GHCheckRun.Status.COMPLETED, GHCheckRun.Conclusion.FAILURE)));
removeLabels.addAll(client.getRepositoryConfiguration().approvedLabels());
removeLabels.addAll(client.getRepositoryConfiguration().reviewRequestedLabels());
eventBus.publish(Constants.EDIT_LABELS, new BusMessage(client, new LabelsMessage(pr, client.getRepositoryConfiguration().changesRequestedLabels(), removeLabels)));
break;
case COMMENTED:
LOG.info("PR #{}: Commented by {}", pr.getNumber(), msg.getSender().getLogin());
addLabels.addAll(client.getRepositoryConfiguration().commentedLabels());
eventBus.publish(Constants.EDIT_LABELS, new BusMessage(client, new LabelsMessage(pr, addLabels, removeLabels)));
break;
default:
LOG.info("PR #{}: Ignoring review state {}", pr.getNumber(), review.getState().name().toLowerCase());
break;
}
}
use of com.github.avano.pr.workflow.message.BusMessage in project pull-request-workflow by avano.
the class LabelsTest method shouldTryToMergeWhenWipLabelWasRemovedTest.
@Test
public void shouldTryToMergeWhenWipLabelWasRemovedTest() {
BusMessage message = new BusMessage(client, loadPullRequest(PULL_REQUEST_ID)).with(BusMessage.LABEL, client.getRepositoryConfiguration().wipLabel());
labelHandler.handlePrUnlabeled(message);
waitForInvocationsAndAssert(1);
assertThat(busInvocations.get(0).getDestination()).isEqualTo(Constants.PR_MERGE);
}
Aggregations