Search in sources :

Example 1 with ApprovalStrategy

use of com.github.avano.pr.workflow.config.ApprovalStrategy in project pull-request-workflow by avano.

the class MergeHandler method merge.

/**
 * Merges the PR if all prerequisities are fulfilled.
 *
 * @param msg {@link BusMessage} instance
 */
@Log
@ConsumeEvent(Constants.PR_MERGE)
public void merge(BusMessage msg) {
    GHClient client = msg.client();
    GHPullRequest pr = msg.get(GHPullRequest.class);
    try {
        // Refresh the PR to work with latest state
        pr.refresh();
        if (pr.isMerged()) {
            LOG.info("PR #{}: Not merging - already merged", pr.getNumber());
            return;
        }
        if (pr.isDraft()) {
            LOG.info("PR #{}: Not merging - draft state", pr.getNumber());
            return;
        }
        if (pr.getLabels().stream().map(GHLabel::getName).collect(Collectors.toSet()).contains(client.getRepositoryConfiguration().wipLabel())) {
            LOG.info("PR #{}: Not merging - work in progress", pr.getNumber());
            return;
        }
        // Check if all required checks passed
        final String targetBranch = pr.getBase().getRef();
        Set<String> requiredChecks = client.getRequiredChecks(targetBranch);
        if (requiredChecks != null && !requiredChecks.isEmpty()) {
            LOG.info("PR #{}: Required checks: {}", pr.getNumber(), String.join(", ", requiredChecks));
            final StringBuilder logMsg = new StringBuilder("PR #").append(pr.getNumber()).append(": Checks - ");
            client.getChecks(pr).forEach((name, result) -> {
                logMsg.append("[").append(name).append(": ").append(result).append("], ");
                if ("success".equalsIgnoreCase(result)) {
                    requiredChecks.remove(name);
                }
            });
            LOG.info(logMsg.substring(0, logMsg.length() - 2));
            if (!requiredChecks.isEmpty()) {
                LOG.info("PR #{}: Not merging - some of the required checks did not pass", pr.getNumber());
                return;
            }
        } else {
            LOG.debug("PR #{}: No required checks defined for branch {}", pr.getNumber(), targetBranch);
        }
        if (pr.getMergeable() == null || !pr.getMergeable()) {
            LOG.warn("PR #{}: Not merging - not mergeable", pr.getNumber());
            return;
        }
        if (Constants.DEPENDABOT_NAME.equals(client.getAuthor(pr).getLogin()) && client.getRepositoryConfiguration().automergeDependabot()) {
            LOG.info("PR #{}: Automerging dependabot PR", pr.getNumber());
            mergePullRequest(msg);
            return;
        }
        if (client.getRepositoryConfiguration().automergeOwnerPRs() && client.getAuthor(pr).getLogin().equals(client.getRepositoryConfiguration().repository().split("/")[0])) {
            LOG.info("PR #{}: Automerging owner's PR", pr.getNumber());
            mergePullRequest(msg);
            return;
        }
        Map<GHUser, GHPullRequestReviewState> reviews = client.getReviews(pr);
        if (reviews.size() == 0) {
            LOG.info("PR #{}: Not merging - no reviews", pr.getNumber());
            return;
        }
        if (reviews.values().stream().noneMatch(r -> r == GHPullRequestReviewState.APPROVED)) {
            LOG.info("PR #{}: Not merging - no approvals", pr.getNumber());
            return;
        }
        if (client.changesRequested(pr)) {
            LOG.info("PR #{}: Not merging - at least one \"changes requested\" review present", pr.getNumber());
            return;
        }
        if (ApprovalStrategy.ALL == client.getRepositoryConfiguration().approvalStrategy()) {
            if (pr.getRequestedReviewers().size() != reviews.size() || reviews.values().stream().anyMatch(r -> r != GHPullRequestReviewState.APPROVED)) {
                LOG.info("PR #{}: Not merging - approval from some reviewer missing (using \"all\" strategy)", pr.getNumber());
                return;
            }
        }
        mergePullRequest(msg);
    } catch (IOException e) {
        LOG.error("PR #{}: Unable to process merge", pr.getNumber(), e);
    }
}
Also used : GHLabel(org.kohsuke.github.GHLabel) GHPullRequestReviewState(org.kohsuke.github.GHPullRequestReviewState) BaseHandler(com.github.avano.pr.workflow.handler.base.BaseHandler) GHPullRequest(org.kohsuke.github.GHPullRequest) ConflictMessage(com.github.avano.pr.workflow.message.ConflictMessage) GHPullRequestReviewState(org.kohsuke.github.GHPullRequestReviewState) Collection(java.util.Collection) Set(java.util.Set) IOException(java.io.IOException) ConsumeEvent(io.quarkus.vertx.ConsumeEvent) Collectors(java.util.stream.Collectors) ApprovalStrategy(com.github.avano.pr.workflow.config.ApprovalStrategy) GHPerson(org.kohsuke.github.GHPerson) Constants(com.github.avano.pr.workflow.config.Constants) List(java.util.List) GHUser(org.kohsuke.github.GHUser) GHClient(com.github.avano.pr.workflow.gh.GHClient) Map(java.util.Map) BusMessage(com.github.avano.pr.workflow.message.BusMessage) GHLabel(org.kohsuke.github.GHLabel) Log(com.github.avano.pr.workflow.handler.interceptor.Log) GHPullRequest(org.kohsuke.github.GHPullRequest) GHClient(com.github.avano.pr.workflow.gh.GHClient) GHUser(org.kohsuke.github.GHUser) IOException(java.io.IOException) Log(com.github.avano.pr.workflow.handler.interceptor.Log) ConsumeEvent(io.quarkus.vertx.ConsumeEvent)

Aggregations

ApprovalStrategy (com.github.avano.pr.workflow.config.ApprovalStrategy)1 Constants (com.github.avano.pr.workflow.config.Constants)1 GHClient (com.github.avano.pr.workflow.gh.GHClient)1 BaseHandler (com.github.avano.pr.workflow.handler.base.BaseHandler)1 Log (com.github.avano.pr.workflow.handler.interceptor.Log)1 BusMessage (com.github.avano.pr.workflow.message.BusMessage)1 ConflictMessage (com.github.avano.pr.workflow.message.ConflictMessage)1 ConsumeEvent (io.quarkus.vertx.ConsumeEvent)1 IOException (java.io.IOException)1 Collection (java.util.Collection)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 Collectors (java.util.stream.Collectors)1 GHLabel (org.kohsuke.github.GHLabel)1 GHPerson (org.kohsuke.github.GHPerson)1 GHPullRequest (org.kohsuke.github.GHPullRequest)1 GHPullRequestReviewState (org.kohsuke.github.GHPullRequestReviewState)1 GHUser (org.kohsuke.github.GHUser)1