From e7add93d02cd2e50ae355073c1bf0264e466cd22 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 30 May 2022 13:18:08 +0200 Subject: [PATCH] Add support for workflow_job event payload Fixes #1331 --- .../org/kohsuke/github/GHEventPayload.java | 37 ++++ .../org/kohsuke/github/GHWorkflowJob.java | 10 + .../kohsuke/github/GHEventPayloadTest.java | 48 ++++- .../GHEventPayloadTest/workflow_job.json | 190 ++++++++++++++++++ 4 files changed, 283 insertions(+), 2 deletions(-) create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/workflow_job.json diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index 0f1728e107..e7af6e93d1 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -1506,6 +1506,43 @@ void lateBind() { } } + /** + * A workflow job has been queued, is in progress, or has been completed. + * + * @see + * workflow job event + * @see Actions Workflow Jobs + */ + public static class WorkflowJob extends GHEventPayload { + + private GHWorkflowJob workflowJob; + + /** + * Gets the workflow job. + * + * @return the workflow job + */ + @SuppressFBWarnings(value = { "EI_EXPOSE_REP" }, justification = "Expected") + public GHWorkflowJob getWorkflowJob() { + return workflowJob; + } + + @Override + void lateBind() { + if (workflowJob == null) { + throw new IllegalStateException( + "Expected workflow_job payload, but got something else. Maybe we've got another type of event?"); + } + super.lateBind(); + GHRepository repository = getRepository(); + if (repository == null) { + throw new IllegalStateException("Repository must not be null"); + } + workflowJob.wrapUp(repository); + } + } + /** * A label was created, edited or deleted. * diff --git a/src/main/java/org/kohsuke/github/GHWorkflowJob.java b/src/main/java/org/kohsuke/github/GHWorkflowJob.java index 9e701d7f32..767075550c 100644 --- a/src/main/java/org/kohsuke/github/GHWorkflowJob.java +++ b/src/main/java/org/kohsuke/github/GHWorkflowJob.java @@ -35,6 +35,7 @@ public class GHWorkflowJob extends GHObject { private String conclusion; private long runId; + private int runAttempt; private String htmlUrl; private String checkRunUrl; @@ -108,6 +109,15 @@ public long getRunId() { return runId; } + /** + * Attempt number of the associated workflow run, 1 for first attempt and higher if the workflow was re-run. + * + * @return attempt number + */ + public int getRunAttempt() { + return runAttempt; + } + @Override public URL getHtmlUrl() { return GitHubClient.parseURL(htmlUrl); diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java index 93616b0084..0c07d1efe9 100644 --- a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -11,7 +11,18 @@ import java.util.List; import java.util.TimeZone; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.aMapWithSize; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.hasToString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.sameInstance; +import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertThrows; public class GHEventPayloadTest extends AbstractGitHubWireMockTest { @@ -876,7 +887,6 @@ public void workflow_run_pull_request() throws Exception { GHPullRequest pullRequest = pullRequests.get(0); assertThat(pullRequest.getId(), is(599098265L)); assertThat(pullRequest.getRepository(), sameInstance(workflowRunPayload.getRepository())); - } @Test @@ -892,6 +902,40 @@ public void workflow_run_other_repository() throws Exception { assertThat(workflowRunPayload.getWorkflow().getRepository(), sameInstance(workflowRunPayload.getRepository())); } + @Test + public void workflow_job() throws Exception { + final GHEventPayload.WorkflowJob workflowJobPayload = GitHub.offline() + .parseEventPayload(payload.asReader(), GHEventPayload.WorkflowJob.class); + + assertThat(workflowJobPayload.getAction(), is("completed")); + assertThat(workflowJobPayload.getRepository().getFullName(), is("gsmet/quarkus-bot-java-playground")); + assertThat(workflowJobPayload.getSender().getLogin(), is("gsmet")); + + GHWorkflowJob workflowJob = workflowJobPayload.getWorkflowJob(); + assertThat(workflowJob.getId(), is(6653410527L)); + assertThat(workflowJob.getRunId(), is(2408553341L)); + assertThat(workflowJob.getRunAttempt(), is(1)); + assertThat(workflowJob.getUrl().toString(), + is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/jobs/6653410527")); + assertThat(workflowJob.getHtmlUrl().toString(), + is("https://github.com/gsmet/quarkus-bot-java-playground/runs/6653410527?check_suite_focus=true")); + assertThat(workflowJob.getNodeId(), is("CR_kwDOEq3cwc8AAAABjJL83w")); + assertThat(workflowJob.getHeadSha(), is("5dd2dadfbdc2a722c08a8ad42ae4e26e3e731042")); + assertThat(workflowJob.getStatus(), is(GHWorkflowRun.Status.COMPLETED)); + assertThat(workflowJob.getConclusion(), is(GHWorkflowRun.Conclusion.FAILURE)); + assertThat(workflowJob.getStartedAt().getTime(), is(1653908125000L)); + assertThat(workflowJob.getCompletedAt().getTime(), is(1653908157000L)); + assertThat(workflowJob.getName(), is("JVM Tests - JDK JDK16")); + assertThat(workflowJob.getSteps(), + contains(hasProperty("name", is("Set up job")), + hasProperty("name", is("Run actions/checkout@v2")), + hasProperty("name", is("Build with Maven")), + hasProperty("name", is("Post Run actions/checkout@v2")), + hasProperty("name", is("Complete job")))); + assertThat(workflowJob.getCheckRunUrl().toString(), + is("https://api.github.com/repos/gsmet/quarkus-bot-java-playground/check-runs/6653410527")); + } + @Test public void label_created() throws Exception { final GHEventPayload.Label labelPayload = GitHub.offline() diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/workflow_job.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/workflow_job.json new file mode 100644 index 0000000000..b511765106 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/workflow_job.json @@ -0,0 +1,190 @@ +{ + "action": "completed", + "workflow_job": { + "id": 6653410527, + "run_id": 2408553341, + "run_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/runs/2408553341", + "run_attempt": 1, + "node_id": "CR_kwDOEq3cwc8AAAABjJL83w", + "head_sha": "5dd2dadfbdc2a722c08a8ad42ae4e26e3e731042", + "url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/actions/jobs/6653410527", + "html_url": "https://github.com/gsmet/quarkus-bot-java-playground/runs/6653410527?check_suite_focus=true", + "status": "completed", + "conclusion": "failure", + "started_at": "2022-05-30T10:55:25Z", + "completed_at": "2022-05-30T10:55:57Z", + "name": "JVM Tests - JDK JDK16", + "steps": [ + { + "name": "Set up job", + "status": "completed", + "conclusion": "success", + "number": 1, + "started_at": "2022-05-30T10:55:25.000Z", + "completed_at": "2022-05-30T10:55:27.000Z" + }, + { + "name": "Run actions/checkout@v2", + "status": "completed", + "conclusion": "success", + "number": 2, + "started_at": "2022-05-30T10:55:27.000Z", + "completed_at": "2022-05-30T10:55:27.000Z" + }, + { + "name": "Build with Maven", + "status": "completed", + "conclusion": "failure", + "number": 4, + "started_at": "2022-05-30T10:55:35.000Z", + "completed_at": "2022-05-30T10:55:55.000Z" + }, + { + "name": "Post Run actions/checkout@v2", + "status": "completed", + "conclusion": "success", + "number": 10, + "started_at": "2022-05-30T10:55:55.000Z", + "completed_at": "2022-05-30T10:55:56.000Z" + }, + { + "name": "Complete job", + "status": "completed", + "conclusion": "success", + "number": 11, + "started_at": "2022-05-30T10:55:56.000Z", + "completed_at": "2022-05-30T10:55:56.000Z" + } + ], + "check_run_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/check-runs/6653410527", + "labels": [ + "ubuntu-latest" + ], + "runner_id": 10, + "runner_name": "GitHub Actions 10", + "runner_group_id": 2, + "runner_group_name": "GitHub Actions" + }, + "repository": { + "id": 313384129, + "node_id": "MDEwOlJlcG9zaXRvcnkzMTMzODQxMjk=", + "name": "quarkus-bot-java-playground", + "full_name": "gsmet/quarkus-bot-java-playground", + "private": false, + "owner": { + "login": "gsmet", + "id": 1279749, + "node_id": "MDQ6VXNlcjEyNzk3NDk=", + "avatar_url": "https://avatars.githubusercontent.com/u/1279749?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gsmet", + "html_url": "https://github.com/gsmet", + "followers_url": "https://api.github.com/users/gsmet/followers", + "following_url": "https://api.github.com/users/gsmet/following{/other_user}", + "gists_url": "https://api.github.com/users/gsmet/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gsmet/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gsmet/subscriptions", + "organizations_url": "https://api.github.com/users/gsmet/orgs", + "repos_url": "https://api.github.com/users/gsmet/repos", + "events_url": "https://api.github.com/users/gsmet/events{/privacy}", + "received_events_url": "https://api.github.com/users/gsmet/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/gsmet/quarkus-bot-java-playground", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground", + "forks_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/forks", + "keys_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/teams", + "hooks_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/hooks", + "issue_events_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/issues/events{/number}", + "events_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/events", + "assignees_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/assignees{/user}", + "branches_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/branches{/branch}", + "tags_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/tags", + "blobs_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/statuses/{sha}", + "languages_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/languages", + "stargazers_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/stargazers", + "contributors_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/contributors", + "subscribers_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/subscribers", + "subscription_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/subscription", + "commits_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/contents/{+path}", + "compare_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/merges", + "archive_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/downloads", + "issues_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/issues{/number}", + "pulls_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/pulls{/number}", + "milestones_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/milestones{/number}", + "notifications_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/labels{/name}", + "releases_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/releases{/id}", + "deployments_url": "https://api.github.com/repos/gsmet/quarkus-bot-java-playground/deployments", + "created_at": "2020-11-16T17:55:53Z", + "updated_at": "2021-12-22T17:20:52Z", + "pushed_at": "2022-05-30T10:55:11Z", + "git_url": "git://github.com/gsmet/quarkus-bot-java-playground.git", + "ssh_url": "git@github.com:gsmet/quarkus-bot-java-playground.git", + "clone_url": "https://github.com/gsmet/quarkus-bot-java-playground.git", + "svn_url": "https://github.com/gsmet/quarkus-bot-java-playground", + "homepage": null, + "size": 88, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Java", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 2, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 36, + "license": null, + "allow_forking": true, + "is_template": false, + "topics": [], + "visibility": "public", + "forks": 2, + "open_issues": 36, + "watchers": 0, + "default_branch": "main" + }, + "sender": { + "login": "gsmet", + "id": 1279749, + "node_id": "MDQ6VXNlcjEyNzk3NDk=", + "avatar_url": "https://avatars.githubusercontent.com/u/1279749?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gsmet", + "html_url": "https://github.com/gsmet", + "followers_url": "https://api.github.com/users/gsmet/followers", + "following_url": "https://api.github.com/users/gsmet/following{/other_user}", + "gists_url": "https://api.github.com/users/gsmet/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gsmet/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gsmet/subscriptions", + "organizations_url": "https://api.github.com/users/gsmet/orgs", + "repos_url": "https://api.github.com/users/gsmet/repos", + "events_url": "https://api.github.com/users/gsmet/events{/privacy}", + "received_events_url": "https://api.github.com/users/gsmet/received_events", + "type": "User", + "site_admin": false + }, + "installation": { + "id": 13005535, + "node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTMwMDU1MzU=" + } +} \ No newline at end of file