From 65b8f9e1367fd209da24e99f0085e99969584fb7 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Tue, 6 Aug 2024 23:26:25 +0300 Subject: [PATCH] Release comments --- build.gradle | 2 +- run/config.properties | 4 ++ .../graphql/com/github/api/fragments.graphql | 6 +- .../java/net/neoforged/automation/Main.java | 12 +++- .../handler/ReleaseMessageHandler.java | 62 +++++++++++++++++++ .../automation/webhook/impl/GitHubEvent.java | 1 + 6 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 src/main/java/net/neoforged/automation/webhook/handler/ReleaseMessageHandler.java diff --git a/build.gradle b/build.gradle index d502345..905a784 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java' id 'application' - id 'com.apollographql.apollo' version '2.5.9' + id 'com.apollographql.apollo' version '2.5.14' id 'com.github.johnrengelman.shadow' version '7.+' } diff --git a/run/config.properties b/run/config.properties index f09bfde..0d519fb 100644 --- a/run/config.properties +++ b/run/config.properties @@ -4,4 +4,8 @@ gitHubAppId=962689 gitHubAppKey=file:P:/Keys/neoforged-automation.2024-08-06.private-key.pem gitHubAppOrganization=neoforged +releasesGitHubAppId=962891 +releasesGitHubAppKey=file:P:/Keys/neoforged-releases.2024-08-06.private-key.pem +releasesGitHubAppOrganization=neoforged + configurationLocation=neoforged/actions:reactionable.yml@main diff --git a/src/main/graphql/com/github/api/fragments.graphql b/src/main/graphql/com/github/api/fragments.graphql index e90396f..caabc63 100644 --- a/src/main/graphql/com/github/api/fragments.graphql +++ b/src/main/graphql/com/github/api/fragments.graphql @@ -1,3 +1,7 @@ +fragment IssueInfo on Issue { + number +} + fragment PullRequestInfo on PullRequest { mergeable number @@ -11,7 +15,7 @@ fragment PullRequestInfo on PullRequest { } closingIssuesReferences(first: 100) { nodes { - number + ...IssueInfo } } projectItems(first: 100) { diff --git a/src/main/java/net/neoforged/automation/Main.java b/src/main/java/net/neoforged/automation/Main.java index 75adc08..f21122e 100644 --- a/src/main/java/net/neoforged/automation/Main.java +++ b/src/main/java/net/neoforged/automation/Main.java @@ -6,6 +6,7 @@ import net.neoforged.automation.webhook.handler.ConfigurationUpdateHandler; import net.neoforged.automation.webhook.handler.LabelLockHandler; import net.neoforged.automation.webhook.handler.MergeConflictCheckHandler; +import net.neoforged.automation.webhook.handler.ReleaseMessageHandler; import net.neoforged.automation.webhook.impl.GitHubEvent; import net.neoforged.automation.webhook.impl.WebhookHandler; import org.kohsuke.github.GitHubBuilder; @@ -29,7 +30,7 @@ public static void main(String[] args) throws IOException, NoSuchAlgorithmExcept var location = Configuration.load(gitHub, startupConfig); - var webhook = setupWebhookHandlers(new WebhookHandler(startupConfig, gitHub), location); + var webhook = setupWebhookHandlers(startupConfig, new WebhookHandler(startupConfig, gitHub), location); var app = Javalin.create(cfg -> { cfg.useVirtualThreads = true; @@ -38,10 +39,17 @@ public static void main(String[] args) throws IOException, NoSuchAlgorithmExcept .start(startupConfig.getInt("port", 8080)); } - public static WebhookHandler setupWebhookHandlers(WebhookHandler handler, Configuration.RepoLocation location) { + public static WebhookHandler setupWebhookHandlers(StartupConfiguration startupConfig, WebhookHandler handler, Configuration.RepoLocation location) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { return handler .register(new MergeConflictCheckHandler()) .registerHandler(GitHubEvent.PUSH, new ConfigurationUpdateHandler(location)) + .registerHandler(GitHubEvent.STATUS, new ReleaseMessageHandler(new GitHubBuilder() + .withAuthorizationProvider(AuthUtil.githubApp( + startupConfig.get("releasesGitHubAppId", ""), + AuthUtil.parsePKCS8(startupConfig.get("releasesGitHubAppKey", "")), + ghApp -> ghApp.getInstallationByOrganization(startupConfig.get("releasesGitHubAppOrganization", "")) + )) + .build())) .registerFilteredHandler(GitHubEvent.ISSUES, new LabelLockHandler(), GHAction.LABELED, GHAction.UNLABELED); } } diff --git a/src/main/java/net/neoforged/automation/webhook/handler/ReleaseMessageHandler.java b/src/main/java/net/neoforged/automation/webhook/handler/ReleaseMessageHandler.java new file mode 100644 index 0000000..06430d8 --- /dev/null +++ b/src/main/java/net/neoforged/automation/webhook/handler/ReleaseMessageHandler.java @@ -0,0 +1,62 @@ +package net.neoforged.automation.webhook.handler; + +import com.github.api.GetPullRequestQuery; +import net.neoforged.automation.webhook.impl.EventHandler; +import org.kohsuke.github.GHCommitState; +import org.kohsuke.github.GHEventPayload; +import org.kohsuke.github.GitHub; +import org.kohsuke.github.GitHubAccessor; + +import java.util.HashSet; +import java.util.regex.Pattern; + +public record ReleaseMessageHandler(GitHub releasesApp) implements EventHandler { + private static final Pattern CLOSE_REFERENCE = Pattern.compile("(?mi)(?(?:close|fix|resolve)(?:s|d|es|ed)?) #(?\\d+)"); + + @Override + public void handle(GitHub gitHub, GHEventPayload.Status payload) throws Exception { + if (payload.getState() == GHCommitState.SUCCESS && payload.getContext().equals("Publishing") && payload.getDescription().startsWith("Version: ")) { + var version = payload.getDescription().replace("Version: ", ""); + + var closedIssues = new HashSet(); + var baseIssueComment = "\uD83D\uDE80 This issue has been resolved in " + payload.getRepository().getName() + " version `" + version + "`."; + + for (var pr : payload.getCommit().listPullRequests()) { + if (pr.getMergedAt() == null) return; + + var repo = releasesApp.getRepository(payload.getRepository().getFullName()); + + baseIssueComment = "\uD83D\uDE80 This issue has been resolved in " + repo.getName() + " version `" + + version + "`, as part of #" + pr.getNumber() + "."; + + repo.getPullRequest(pr.getNumber()) + .comment("\uD83D\uDE80 This PR has been released as " + repo.getName() + " version `" + version + "`."); + + for (var issueNode : GitHubAccessor.graphQl(gitHub, GetPullRequestQuery.builder() + .name(payload.getRepository().getName()) + .owner(payload.getRepository().getOwnerName()) + .number(pr.getNumber()) + .build()) + .repository() + .pullRequest() + .fragments() + .pullRequestInfo() + .closingIssuesReferences() + .nodes()) { + repo.getIssue(issueNode.fragments().issueInfo().number()) + .comment(baseIssueComment); + closedIssues.add(issueNode.fragments().issueInfo().number()); + } + } + + var matcher = CLOSE_REFERENCE.matcher(payload.getCommit().getCommitShortInfo().getMessage()); + while (matcher.find()) { + var number = Integer.parseInt(matcher.group("number")); + if (closedIssues.add(number)) { + var repo = releasesApp.getRepository(payload.getRepository().getFullName()); + repo.getIssue(number).comment(baseIssueComment); + } + } + } + } +} diff --git a/src/main/java/net/neoforged/automation/webhook/impl/GitHubEvent.java b/src/main/java/net/neoforged/automation/webhook/impl/GitHubEvent.java index ee96b6f..fdbd251 100644 --- a/src/main/java/net/neoforged/automation/webhook/impl/GitHubEvent.java +++ b/src/main/java/net/neoforged/automation/webhook/impl/GitHubEvent.java @@ -15,6 +15,7 @@ public final class GitHubEvent { public static final GitHubEvent PULL_REQUEST = create("pull_request", GHEventPayload.PullRequest.class); public static final GitHubEvent ISSUE_COMMENT = create("issue_comment", GHEventPayload.IssueComment.class); public static final GitHubEvent PUSH = create("push", GHEventPayload.Push.class); + public static final GitHubEvent STATUS = create("status", GHEventPayload.Status.class); private final Class type; private GitHubEvent(Class type) {