Skip to content

Commit

Permalink
Add support for test/restest command in pull request comment
Browse files Browse the repository at this point in the history
  • Loading branch information
glefloch committed May 3, 2021
1 parent b2d8279 commit 8f78217
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 0 deletions.
77 changes: 77 additions & 0 deletions src/main/java/io/quarkus/bot/PullRequestCommandHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.quarkus.bot;

import io.quarkiverse.githubapp.event.IssueComment;
import io.quarkus.bot.command.Command;
import io.quarkus.bot.config.QuarkusBotConfig;
import org.jboss.logging.Logger;
import org.kohsuke.github.GHEventPayload;
import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHPermissionType;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHUser;
import org.kohsuke.github.ReactionContent;

import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import java.io.IOException;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PullRequestCommandHandler {

private static final Logger LOG = Logger.getLogger(PullRequestCommandHandler.class);

private static final String QUARKUS_BOT_NAME = "quarkus-bot[bot]";
private static final Pattern QUARKUS_BOT_MENTION = Pattern.compile("^@(?:quarkus-?)?bot\\s+([a-z _\\-]+)");

@Inject
Instance<Command<GHPullRequest>> commands;

@Inject
QuarkusBotConfig quarkusBotConfig;

public void onComment(@IssueComment.Created @IssueComment.Edited GHEventPayload.IssueComment commentPayload)
throws IOException {
GHUser user = commentPayload.getComment().getUser();
GHIssue issue = commentPayload.getIssue();
GHRepository repository = commentPayload.getRepository();

if (QUARKUS_BOT_NAME.equals(commentPayload.getComment().getUserName())) {
return;
}

if (issue.isPullRequest()) {
Optional<Command<GHPullRequest>> command = extractCommand(commentPayload.getComment().getBody());
if (command.isPresent() && canRunCommand(repository, user)) {
GHPullRequest pullRequest = repository.getPullRequest(issue.getNumber());
ReactionContent reactionResult = command.get().run(pullRequest);
postReaction(commentPayload, issue, reactionResult);
} else {
postReaction(commentPayload, issue, ReactionContent.MINUS_ONE);
}
}
}

private void postReaction(GHEventPayload.IssueComment comment, GHIssue issue, ReactionContent reactionResult) throws IOException {
if (!quarkusBotConfig.isDryRun()) {
comment.getComment().createReaction(reactionResult);
} else {
LOG.info("Pull Request #" + issue.getNumber() + " - Add reaction: " + reactionResult.getContent());
}
}

private Optional<Command<GHPullRequest>> extractCommand(String comment) {
Matcher matcher = QUARKUS_BOT_MENTION.matcher(comment);
if (matcher.matches()) {
String commandLabel = matcher.group(1);
return commands.stream().filter(command -> command.labels().contains(commandLabel)).findFirst();
}
return Optional.empty();
}

private boolean canRunCommand(GHRepository repository, GHUser user) throws IOException {
return repository.getPermission(user) == GHPermissionType.WRITE || repository.getPermission(user) == GHPermissionType.ADMIN;
}
}
14 changes: 14 additions & 0 deletions src/main/java/io/quarkus/bot/command/Command.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.quarkus.bot.command;

import org.kohsuke.github.ReactionContent;

import java.io.IOException;
import java.util.List;

public interface Command<T> {

List<String> labels();

ReactionContent run(T input) throws IOException;

}
63 changes: 63 additions & 0 deletions src/main/java/io/quarkus/bot/command/RerunWorkflowCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.quarkus.bot.command;

import io.quarkus.bot.config.QuarkusBotConfig;
import io.quarkus.bot.workflow.WorkflowConstants;
import org.jboss.logging.Logger;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GHWorkflowRun;
import org.kohsuke.github.ReactionContent;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@ApplicationScoped
public class RerunWorkflowCommand implements Command<GHPullRequest> {

private static final Logger LOG = Logger.getLogger(RerunWorkflowCommand.class);

@Inject
QuarkusBotConfig quarkusBotConfig;

@Override
public List<String> labels() {
return Arrays.asList("test", "retest");
}

@Override
public ReactionContent run(GHPullRequest pullRequest) throws IOException {
GHRepository repository = pullRequest.getRepository();

List<GHWorkflowRun> ghWorkflowRuns = repository
.queryWorkflowRuns()
.branch(pullRequest.getHead().getRef())
.status(GHWorkflowRun.Status.COMPLETED)
.list().toList();

Map<String, Optional<GHWorkflowRun>> lastWorkflowRuns = ghWorkflowRuns.stream()
.filter(workflowRun -> WorkflowConstants.QUARKUS_CI_WORKFLOW_NAME.equals(workflowRun.getName())
|| WorkflowConstants.QUARKUS_DOCUMENTATION_CI_WORKFLOW_NAME.equals(workflowRun.getName()))
.filter(workflowRun -> workflowRun.getHeadRepository().getOwnerName()
.equals(pullRequest.getHead().getRepository().getOwnerName()))
.collect(Collectors.groupingBy(GHWorkflowRun::getName, Collectors.maxBy(Comparator.comparing(GHWorkflowRun::getRunNumber))));

for (Map.Entry<String, Optional<GHWorkflowRun>> lastWorkflowRun : lastWorkflowRuns.entrySet()) {
if (lastWorkflowRun.getValue().isPresent()) {
if (!quarkusBotConfig.isDryRun()) {
lastWorkflowRun.getValue().get().rerun();
LOG.info("Pull request #" + pullRequest.getNumber() + " - Restart workflow: " + lastWorkflowRun.getValue().get().getHtmlUrl());
} else {
LOG.info("Pull request #" + pullRequest.getNumber() + " - Restart workflow " + lastWorkflowRun.getKey());
}
}
}
return ReactionContent.ROCKET;
}
}

0 comments on commit 8f78217

Please sign in to comment.