Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new config options, improve comment logic #18

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 52 additions & 9 deletions src/main/java/io/debezium/github/bot/JiraIssueCheck.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.kohsuke.github.GHIssueComment;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHPullRequestCommitDetail;

Expand Down Expand Up @@ -62,23 +63,66 @@ public void run(CheckContext context, CheckRunOutput output) throws IOException
}
}

// Perform checks
issuesAddressed(output, issueKeys);
// commitStartWithKey(output, commitsWithMessageNotStartingWithIssueKey);
issuesNotMentioned(output, getIssueKeysNotMentionedInTitleBody(context.pullRequest, issueKeys));
// If at least one issue isn't found in the comments, add all issues in the output.
Set<String> issuesNotInComments = getIssueKeysNotMentionedInComments(context.pullRequest, issueKeys);
if (deploymentConfig.isCheckAlwaysAddIssuesEnabled() || !issuesNotInComments.isEmpty()) {
issuesAddressed(output, deploymentConfig.isCheckAlwaysAddIssuesEnabled() ? issueKeys : issuesNotInComments);
}

if (deploymentConfig.isCheckCommitStartWithKeyEnabled()) {
commitStartWithKey(output, commitsWithMessageNotStartingWithIssueKey);
}

if (deploymentConfig.isCheckIssuesNotMentionedEnabled()) {
issuesNotMentioned(output, getIssueKeysNotMentionedInTitleBody(context.pullRequest, issueKeys));
}
}

private List<String> getIssueKeysNotMentionedInTitleBody(GHPullRequest pullRequest, Set<String> issueKeys) {
final String title = pullRequest.getTitle();
final String body = pullRequest.getBody();
return issueKeys.stream().filter(k -> {
if (title != null && !title.contains(k)) {
return true;
}
return body != null && !body.contains(k);
boolean foundTitle = title != null && title.contains(k);
boolean foundBody = body != null && body.contains(k);
return !foundTitle && !foundBody;
}).collect(Collectors.toList());
}

private Set<String> getIssueKeysNotMentionedInComments(GHPullRequest pullRequest, Set<String> issueKeys) {
final Set<String> notMentionedKeys = new LinkedHashSet<>();

for (String issueKey : issueKeys) {
boolean found = false;
final String jiraUrl = getJiraUrl(issueKey);
if (pullRequest.getBody() != null && pullRequest.getBody().contains(jiraUrl)) {
continue;
}

try {
for (GHIssueComment comment : pullRequest.listComments()) {
// Ignore comments generated by the bot
final String loginName = comment.getUser().getLogin();
if (loginName.contains(deploymentConfig.getUserName())) {
continue;
}
if (comment.getBody().contains(jiraUrl)) {
found = true;
}
}
}
catch (IOException e) {
// If this happens, lets just add the keys to the comment
return issueKeys;
}

if (!found) {
notMentionedKeys.add(issueKey);
}
}

return notMentionedKeys;
}

private void issuesNotMentioned(CheckRunOutput output, List<String> issuesNotMentioned) {
CheckRunRule pullRequestRule = output.rule("All issues addressed should be included in PR title");
if (issuesNotMentioned.isEmpty()) {
Expand All @@ -94,7 +138,6 @@ private void issuesNotMentioned(CheckRunOutput output, List<String> issuesNotMen
}

private void commitStartWithKey(CheckRunOutput output, Set<String> commitsWithoutIssueKeys) {
// todo: disabled for now as a GH action handles this but kept this as an example
CheckRunRule commitRule = output.rule("All commit messages should start with DBZ-XXXX issue key");
if (commitsWithoutIssueKeys.isEmpty()) {
commitRule.passed();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ public class PullRequestContributionHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(PullRequestContributionHandler.class);

private static final String COMMENT_INTRO_PASSED = "Thanks for your pull request!\n\n"
+ "This pull request appears to follow the contribution rules. :+1:\n";
private static final String COMMENT_INTRO_FAILED = "Thanks for your pull request!\n\n"
+ "This pull request does not follow the contribution rules. Could you please review?\n";
private static final String COMMENT_FOOTER = "\n\n---\n\n:robot: This is an auto-generated message.";

@Inject
DeploymentConfig deploymentConfig;

Expand Down Expand Up @@ -73,26 +67,38 @@ void pullRequestEvent(@Opened @Reopened @Edited @Synchronize PullRequest payload
return;
}

final StringBuilder rulesOutput = new StringBuilder();
outputs.forEach(output -> output.appendFailingRules(rulesOutput));

// Generate the comment text
StringBuilder message = new StringBuilder(passed ? COMMENT_INTRO_PASSED : COMMENT_INTRO_FAILED);
outputs.forEach(output -> output.appendFailingRules(message));
message.append(COMMENT_FOOTER);
StringBuilder message = new StringBuilder(passed ? getPassPreamble() : getFailPreamble());
message.append(rulesOutput);
message.append(deploymentConfig.getFooter());

// Find the comment that should be modified by the bot; may be null if none exist.
GHIssueComment existingComment = findExistingComment(pullRequest);
if (!deploymentConfig.isDryRun()) {
if (existingComment == null) {
if (rulesOutput.length() == 0) {
LOGGER.info("Rules generated no output, adding no message.");
return;
}
// No comment found, add a new comment with the message
pullRequest.comment(message.toString());
}
else {
// Existing comment detected, update the contents
if (rulesOutput.length() == 0) {
LOGGER.info("Rules generated no output, removing existing comment.");
existingComment.delete();
return;
}
existingComment.update(message.toString());
}
}
else {
// In dry-mode run; while contents to the log instead
LOGGER.info("PR #{} - Added comment {}", pullRequest.getNumber(), message.toString());
LOGGER.info("PR #{} - Added comment {}", pullRequest.getNumber(), message);
}
}

Expand Down Expand Up @@ -157,4 +163,12 @@ private GHIssueComment findExistingComment(GHPullRequest pullRequest) throws IOE
}
return null;
}

private String getPassPreamble() {
return deploymentConfig.getPassPreamble();
}

private String getFailPreamble() {
return deploymentConfig.getFailPreamble();
}
}
18 changes: 18 additions & 0 deletions src/main/java/io/debezium/github/bot/config/DeploymentConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,22 @@ public interface DeploymentConfig {

@WithName("issue-key-pattern")
String getIssueKeyPattern();

@WithName("check-always-add-issues")
boolean isCheckAlwaysAddIssuesEnabled();

@WithName("check-commit-start-with-key")
boolean isCheckCommitStartWithKeyEnabled();

@WithName("check-issues-not-mentioned")
boolean isCheckIssuesNotMentionedEnabled();

@WithName("intro-pass")
String getPassPreamble();

@WithName("intro-fail")
String getFailPreamble();

@WithName("footer")
String getFooter();
}
9 changes: 9 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,17 @@ debezium-github-bot.issue-key-pattern=DBZ-\\d+
%dev.debezium-github-bot.issue-key-pattern=DBZ-\\d+
%test.debezium-github-bot.issue-key-pattern=DBZ-\\d+

debezium-github-bot.intro-pass=Thanks for your pull request, it appears to follow the contribution rules. :+1:\n
debezium-github-bot.intro-fail=Thanks for your pull request, it does not follow the contribution rules. Could you please review?\n
debezium-github-bot.footer=\n

# Defines whether the bot is to run in dry-mode or not.
# When in dry-mode, no comments are applied to GitHub but instead output is provided to the console.
debezium-github-bot.dry-run=false
%dev.debezium-github-bot.dry-run=false
%test.debezium-github-bot.dry-run=false

# Additional configs
debezium-github-bot.check-always-add-issues=true
debezium-github-bot.check-commit-start-with-key=false
debezium-github-bot.check-issues-not-mentioned=true