Skip to content

Commit

Permalink
Merge pull request #2 from gsmet/first-implementation
Browse files Browse the repository at this point in the history
First implementation of the action
  • Loading branch information
gsmet authored Jan 17, 2025
2 parents 58ff204 + e6afcb2 commit 2c5d207
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 15 deletions.
17 changes: 16 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ inputs:
action:
description: 'Name of the action (if named)'
required: false
status:
description: 'Status of the CI run'
required: true
issue-repository:
description: 'The repository where the issue resides (e.g. quarkusio/quarkus)'
required: true
issue-number:
description: 'The issue to update'
required: true
repository:
description: 'The repository for which we are reporting the CI status (by default, the repository running the action)'
required: false
run-id:
description: 'The ID of the Github Action run for which we are reporting the CI status (by default, the run id of the current run)'
required: false

runs:
using: "composite"
Expand Down Expand Up @@ -37,7 +52,7 @@ runs:
uses: jbangdev/setup-jbang@main
- name: Run the action
id: action
run: jbang --java 17 --fresh --repos 'quarkus-github-action=https://maven.pkg.github.com/quarkusio/report-status-in-issue/' --repos 'mavencentral' io.quarkus.bot:report-status-in-issue:999-SNAPSHOT
run: jbang --java 21 --fresh --repos 'quarkus-github-action=https://maven.pkg.github.com/quarkusio/report-status-in-issue/' --repos 'mavencentral' io.quarkus.bot:report-status-in-issue:999-SNAPSHOT
shell: bash
env:
JSON_INPUTS: ${{ toJSON(inputs) }}
Expand Down
14 changes: 0 additions & 14 deletions src/main/java/io/quarkus/bot/MyAction.java

This file was deleted.

13 changes: 13 additions & 0 deletions src/main/java/io/quarkus/bot/reportstatus/InputKeys.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.quarkus.bot.reportstatus;

public final class InputKeys {

private InputKeys() {
}

static final String STATUS = "status";
static final String ISSUE_REPOSITORY = "issue-repository";
static final String ISSUE_NUMBER = "issue-number";
static final String REPOSITORY = "repository";
static final String RUN_ID = "run-id";
}
117 changes: 117 additions & 0 deletions src/main/java/io/quarkus/bot/reportstatus/ReportStatusInIssue.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package io.quarkus.bot.reportstatus;

import java.io.IOException;
import java.time.Instant;
import java.util.regex.Pattern;

import org.kohsuke.github.GHIssue;
import org.kohsuke.github.GHIssueComment;
import org.kohsuke.github.GHIssueState;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import io.quarkiverse.githubaction.Action;
import io.quarkiverse.githubaction.Commands;
import io.quarkiverse.githubaction.Context;
import io.quarkiverse.githubaction.Inputs;

public class ReportStatusInIssue {

private static final String STATUS_MARKER = "<!-- status.quarkus.io/status:";
private static final String END_OF_MARKER = "-->";
private static final Pattern STATUS_PATTERN = Pattern.compile(STATUS_MARKER + "(.*?)" + END_OF_MARKER,
Pattern.DOTALL);

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(new YAMLFactory());

static {
OBJECT_MAPPER.registerModule(new JavaTimeModule());
}

@Action
void reportStatus(Commands commands, Inputs inputs, Context context) throws IOException {
String status = inputs.getRequired(InputKeys.STATUS);
String issueRepository = inputs.getRequired(InputKeys.ISSUE_REPOSITORY);
int issueNumber = inputs.getRequiredInt(InputKeys.ISSUE_NUMBER);
String repositoryName = inputs.get(InputKeys.REPOSITORY).orElse(context.getGitHubRepository());
Long runId = inputs.getLong(InputKeys.RUN_ID).orElse(context.getGitHubRunId());

final boolean succeed = "success".equalsIgnoreCase(status);
if ("cancelled".equalsIgnoreCase(status)) {
commands.warning("Job status is `cancelled` - exiting");
return;
}

commands.notice(String.format("The CI build had status %s.", status));

final GitHub github = new GitHubBuilder().withOAuthToken(inputs.getGitHubToken().get()).build();
final GHRepository repository = github.getRepository(issueRepository);

final GHIssue issue = repository.getIssue(issueNumber);
if (issue == null) {
commands.error(String.format("Unable to find the issue %s in repository %s", issueNumber, issueRepository));
return;
} else {
commands.notice(
String.format("Report issue found: %s - %s", issue.getTitle(), issue.getHtmlUrl().toString()));
commands.notice(String.format("The issue is currently %s", issue.getState().toString()));
}

if (succeed) {
if (issue != null && isOpen(issue)) {
// close issue with a comment
final GHIssueComment comment = issue.comment(
String.format("Build fixed:\n* Link to latest CI run: https://github.com/%s/actions/runs/%s",
repositoryName, runId));
issue.close();
commands.notice(String.format("Comment added on issue %s - %s, the issue has also been closed",
issue.getHtmlUrl().toString(), comment.getHtmlUrl().toString()));
} else {
System.out.println("Nothing to do - the build passed and the issue is already closed");
}
} else {
if (isOpen(issue)) {
final GHIssueComment comment = issue.comment(String.format(
"The build is still failing:\n* Link to latest CI run: https://github.com/%s/actions/runs/%s",
repositoryName, runId));
commands.notice(String.format("Comment added on issue %s - %s", issue.getHtmlUrl().toString(),
comment.getHtmlUrl().toString()));
} else {
issue.reopen();
final GHIssueComment comment = issue.comment(String.format(
"Unfortunately, the build failed:\n* Link to latest CI run: https://github.com/%s/actions/runs/%s",
repositoryName, runId));
commands.notice(String.format("Comment added on issue %s - %s, the issue has been re-opened",
issue.getHtmlUrl().toString(), comment.getHtmlUrl().toString()));
}
}

issue.setBody(appendStatusInformation(issue.getBody(), new Status(Instant.now(), !succeed, repositoryName, runId)));
}

private static boolean isOpen(GHIssue issue) {
return (issue.getState() == GHIssueState.OPEN);
}

public String appendStatusInformation(String body, Status status) {
try {
String descriptor = STATUS_MARKER + "\n" + OBJECT_MAPPER.writeValueAsString(status) + END_OF_MARKER;

if (!body.contains(STATUS_MARKER)) {
return body + "\n\n" + descriptor;
}

return STATUS_PATTERN.matcher(body).replaceFirst(descriptor);
} catch (Exception e) {
throw new IllegalStateException("Unable to update the status descriptor", e);
}
}

public record Status(Instant updatedAt, boolean failure, String repository, Long runId) {
};
}

0 comments on commit 2c5d207

Please sign in to comment.