diff --git a/src/main/java/org/kohsuke/github/GHCheckRun.java b/src/main/java/org/kohsuke/github/GHCheckRun.java index 37d67d997..e32ff2e8f 100644 --- a/src/main/java/org/kohsuke/github/GHCheckRun.java +++ b/src/main/java/org/kohsuke/github/GHCheckRun.java @@ -30,8 +30,7 @@ public class GHCheckRun extends GHObject { private Output output; private GHApp app; private GHPullRequest[] pullRequests; - - // TODO: Add Check Suite object + private GHCheckSuite checkSuite; GHCheckRun wrap(GHRepository owner) { this.owner = owner; @@ -168,6 +167,15 @@ public class GHCheckRun extends GHObject { return app; } + /** + * Gets the check suite this check run belongs to + * + * @return Check suite + */ + public GHCheckSuite getCheckSuite() { + return checkSuite; + } + /** * Gets an output for a check run. * diff --git a/src/main/java/org/kohsuke/github/GHCheckSuite.java b/src/main/java/org/kohsuke/github/GHCheckSuite.java new file mode 100644 index 000000000..a96f40abd --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHCheckSuite.java @@ -0,0 +1,176 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; +import java.util.Date; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +/** + * Represents a check suite. + * + * @see documentation + * @return global node id + */ + public String getNodeId() { + return nodeId; + } + + /** + * The head branch name the changes are on. + * + * @return head branch name + */ + public String getHeadBranch() { + return headBranch; + } + + /** + * Gets the HEAD SHA. + * + * @return sha for the HEAD commit + */ + public String getHeadSha() { + return headSha; + } + + /** + * Gets status of the check suite. It can be one of request, in_progress, or completed. + * + * @return status of the check suite + */ + public String getStatus() { + return status; + } + + /** + * Gets conclusion of a completed check suite. It can be one of success, failure, neutral, cancelled, time_out, + * action_required, or stale. The check suite will report the highest priority check run conclusion in the check + * suite's conclusion. + * + * @return conclusion of the check suite + */ + public String getConclusion() { + return conclusion; + } + + /** + * The SHA of the most recent commit on ref before the push. + * + * @return sha of a commit + */ + public Date getBefore() { + return GitHubClient.parseDate(before); + } + + /** + * The SHA of the most recent commit on ref after the push. + * + * @return sha of a commit + */ + public Date getAfter() { + return GitHubClient.parseDate(after); + } + + /** + * The quantity of check runs that had run as part of the latest push. + * + * @return sha of the most recent commit + */ + public int getLatestCheckRunsCount() { + return latestCheckRunsCount; + } + + /** + * The url used to list all the check runs belonged to this suite. + * + * @return url containing all check runs + */ + public URL getCheckRunsUrl() { + return checkRunsUrl; + } + + /** + * The commit of current head. + * + * @return head commit + */ + public GHCommit.ShortInfo getHeadCommit() { + return headCommit; + } + + /** + * Gets the GitHub app this check suite belongs to, included in response. + * + * @return GitHub App + */ + public GHApp getApp() { + return app; + } + + /** + * Gets the pull requests participated in this check suite. + * + * @return Pull requests + */ + GHPullRequest[] getPullRequests() throws IOException { + if (pullRequests != null && pullRequests.length != 0) { + for (GHPullRequest singlePull : pullRequests) { + singlePull.refresh(); + } + } + return pullRequests; + } + + /** + * Check suite doesn't have a HTML URL. + * + * @return null + */ + @Override + public URL getHtmlUrl() { + return null; + } +} \ No newline at end of file diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index 8909a9df3..3a39a4f54 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -5,11 +5,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.IOException; import java.net.URL; -import java.util.AbstractList; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; +import java.util.*; /** * A commit in a repository. @@ -38,12 +34,43 @@ public class GHCommit { private int comment_count; + private String id; + private String timestamp; + private String treeId; + static class Tree { String sha; } private Tree tree; + /** + * Gets id of the commit, used by {@link GHCheckSuite} when a {@link GHEvent#CHECK_SUITE} comes + * + * @return id of the commit + */ + public String getId() { + return id; + } + + /** + * Gets timestamp of the commit, used by {@link GHCheckSuite} when a {@link GHEvent#CHECK_SUITE} comes + * + * @return timestamp of the commit + */ + public Date getTimestamp() { + return GitHubClient.parseDate(timestamp); + } + + /** + * Gets id of the tree, used by {@link GHCheckSuite} when a {@link GHEvent#CHECK_SUITE} comes + * + * @return id of the tree + */ + public String getTreeId() { + return treeId; + } + /** * Gets author. * diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index f3607eea3..ce9836a3e 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -150,6 +150,47 @@ public abstract class GHEventPayload { } } + /** + * A check suite event has been requested, rerequested or completed. + * + * @see authoritative source + */ + @SuppressFBWarnings( + value = { "UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD" }, + justification = "JSON API") + public static class CheckSuite extends GHEventPayload { + private String action; + private GHCheckSuite checkSuite; + private GHRepository repository; + + /** + * Gets action. + * + * @return the action + */ + public String getAction() { + return action; + } + + /** + * Gets the Check Suite object + * + * @return the Check Suite object + */ + public GHCheckSuite getCheckSuite() { + return checkSuite; + } + + /** + * Gets repository. + * + * @return the repository + */ + public GHRepository getRepository() { + return repository; + } + } + /** * A pull request status has changed. * diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java index 83ab7a3a5..918487363 100644 --- a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -345,10 +345,41 @@ public class GHEventPayloadTest { assertThat(checkRun.getHtmlUrl().toString(), is("https://github.com/Codertocat/Hello-World/runs/128620228")); assertThat(checkRun.getDetailsUrl().toString(), is("https://octocoders.io")); assertThat(checkRun.getApp().getId(), is(29310L)); + assertThat(checkRun.getCheckSuite().getId(), is(118578147L)); assertThat(checkRun.getOutput().getTitle(), is("check-run output")); // Checks the deserialization of sender assertThat(event.getSender().getId(), is(21031067L)); } + @Test + @Payload("check-suite") + public void checkSuiteEvent() throws Exception { + GHEventPayload.CheckSuite event = GitHub.offline() + .parseEventPayload(payload.asReader(), GHEventPayload.CheckSuite.class); + + assertThat(event.getRepository().getName(), is("Hello-World")); + assertThat(event.getAction(), is("completed")); + assertThat(event.getSender().getId(), is(21031067L)); + + // Checks the deserialization of check_suite + GHCheckSuite checkSuite = event.getCheckSuite(); + assertThat(checkSuite.getNodeId(), is("MDEwOkNoZWNrU3VpdGUxMTg1NzgxNDc=")); + assertThat(checkSuite.getHeadBranch(), is("changes")); + assertThat(checkSuite.getHeadSha(), is("ec26c3e57ca3a959ca5aad62de7213c562f8c821")); + assertThat(checkSuite.getStatus(), is("completed")); + assertThat(checkSuite.getConclusion(), is("success")); + assertThat(checkSuite.getBefore(), is("6113728f27ae82c7b1a177c8d03f9e96e0adf246")); + assertThat(checkSuite.getAfter(), is("ec26c3e57ca3a959ca5aad62de7213c562f8c821")); + assertThat(checkSuite.getLatestCheckRunsCount(), is(1)); + assertThat(checkSuite.getCheckRunsUrl().toString(), + is("https://api.github.com/repos/Codertocat/Hello-World/check-suites/118578147/check-runs")); + assertThat(checkSuite.getHeadCommit().getMessage(), is("Update README.md")); + assertThat(checkSuite.getHeadCommit().getId(), is("ec26c3e57ca3a959ca5aad62de7213c562f8c821")); + assertThat(checkSuite.getHeadCommit().getTreeId(), is("31b122c26a97cf9af023e9ddab94a82c6e77b0ea")); + assertThat(checkSuite.getHeadCommit().getAuthor().getName(), is("Codertocat")); + assertThat(checkSuite.getHeadCommit().getCommitter().getName(), is("Codertocat")); + assertThat(checkSuite.getApp().getId(), is(29310L)); + } + } diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/check-suite.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/check-suite.json new file mode 100644 index 000000000..4f3dfdcfe --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/check-suite.json @@ -0,0 +1,225 @@ +{ + "action": "completed", + "check_suite": { + "id": 118578147, + "node_id": "MDEwOkNoZWNrU3VpdGUxMTg1NzgxNDc=", + "head_branch": "changes", + "head_sha": "ec26c3e57ca3a959ca5aad62de7213c562f8c821", + "status": "completed", + "conclusion": "success", + "url": "https://api.github.com/repos/Codertocat/Hello-World/check-suites/118578147", + "before": "6113728f27ae82c7b1a177c8d03f9e96e0adf246", + "after": "ec26c3e57ca3a959ca5aad62de7213c562f8c821", + "pull_requests": [ + { + "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2", + "id": 279147437, + "number": 2, + "head": { + "ref": "changes", + "sha": "ec26c3e57ca3a959ca5aad62de7213c562f8c821", + "repo": { + "id": 186853002, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "name": "Hello-World" + } + }, + "base": { + "ref": "master", + "sha": "f95f852bd8fca8fcc58a9a2d6c842781e32a215e", + "repo": { + "id": 186853002, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "name": "Hello-World" + } + } + } + ], + "app": { + "id": 29310, + "node_id": "MDM6QXBwMjkzMTA=", + "owner": { + "login": "Octocoders", + "id": 38302899, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjM4MzAyODk5", + "avatar_url": "https://avatars1.githubusercontent.com/u/38302899?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Octocoders", + "html_url": "https://github.com/Octocoders", + "followers_url": "https://api.github.com/users/Octocoders/followers", + "following_url": "https://api.github.com/users/Octocoders/following{/other_user}", + "gists_url": "https://api.github.com/users/Octocoders/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Octocoders/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Octocoders/subscriptions", + "organizations_url": "https://api.github.com/users/Octocoders/orgs", + "repos_url": "https://api.github.com/users/Octocoders/repos", + "events_url": "https://api.github.com/users/Octocoders/events{/privacy}", + "received_events_url": "https://api.github.com/users/Octocoders/received_events", + "type": "Organization", + "site_admin": false + }, + "name": "octocoders-linter", + "description": "", + "external_url": "https://octocoders.io", + "html_url": "https://github.com/apps/octocoders-linter", + "created_at": "2019-04-19T19:36:24Z", + "updated_at": "2019-04-19T19:36:56Z", + "permissions": { + "administration": "write", + "checks": "write", + "contents": "write", + "deployments": "write", + "issues": "write", + "members": "write", + "metadata": "read", + "organization_administration": "write", + "organization_hooks": "write", + "organization_plan": "read", + "organization_projects": "write", + "organization_user_blocking": "write", + "pages": "write", + "pull_requests": "write", + "repository_hooks": "write", + "repository_projects": "write", + "statuses": "write", + "team_discussions": "write", + "vulnerability_alerts": "read" + }, + "events": [ + + ] + }, + "created_at": "2019-05-15T15:20:31Z", + "updated_at": "2019-05-15T15:21:14Z", + "latest_check_runs_count": 1, + "check_runs_url": "https://api.github.com/repos/Codertocat/Hello-World/check-suites/118578147/check-runs", + "head_commit": { + "id": "ec26c3e57ca3a959ca5aad62de7213c562f8c821", + "tree_id": "31b122c26a97cf9af023e9ddab94a82c6e77b0ea", + "message": "Update README.md", + "timestamp": "2019-05-15T15:20:30Z", + "author": { + "name": "Codertocat", + "email": "21031067+Codertocat@users.noreply.github.com" + }, + "committer": { + "name": "Codertocat", + "email": "21031067+Codertocat@users.noreply.github.com" + } + } + }, + "repository": { + "id": 186853002, + "node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "private": false, + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2019-05-15T15:19:25Z", + "updated_at": "2019-05-15T15:21:14Z", + "pushed_at": "2019-05-15T15:20:57Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": "Ruby", + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": null, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + } +} \ No newline at end of file