From ac39b564a83f3788501c0e3caac5566eab914efd Mon Sep 17 00:00:00 2001 From: Daniel Lovera Date: Sun, 13 Dec 2015 20:59:49 +0100 Subject: [PATCH 001/118] Support for auto_init parameter The GitHub api auto_init parameter allows to initialize created repository with a readme file. Add a createRepository method using auto_init parameter. Already existing createRepository method uses auto_init parameter as false for retro-compatibility. --- src/main/java/org/kohsuke/github/GitHub.java | 18 ++++++++++++++++-- src/test/java/org/kohsuke/github/AppTest.java | 12 ++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index b6ddd6e96..55d1bcac5 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -417,9 +417,23 @@ public class GitHub { * Newly created repository. */ public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) throws IOException { + return createRepository(name, description, homepage, isPublic, false); + } + + /** + * Creates a new repository. + * + * To create a repository in an organization, see + * {@link GHOrganization#createRepository(String, String, String, GHTeam, boolean, boolean)} + * + * @return + * Newly created repository. + */ + public GHRepository createRepository(String name, String description, String homepage, boolean isPublic, boolean autoInit) throws IOException { Requester requester = new Requester(this) - .with("name", name).with("description", description).with("homepage", homepage) - .with("public", isPublic ? 1 : 0); + .with("name", name).with("description", description).with("homepage", homepage) + .with("public", isPublic ? 1 : 0) + .with("auto_init", autoInit); return requester.method("POST").to("/user/repos", GHRepository.class).wrap(this); } diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 5d5e0a5fe..0ccd0d11c 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -38,6 +38,18 @@ public class AppTest extends AbstractGitHubApiTestBase { getUser().getRepository(targetName).delete(); } + @Test + public void testRepositoryWithAutoInitializationCRUD() throws IOException { + String name = "github-api-test-autoinit"; + deleteRepository(name); + GHRepository r = gitHub.createRepository(name, "a test repository for auto init", "http://github-api.kohsuke.org/", true, true); + r.enableIssueTracker(false); + r.enableDownloads(false); + r.enableWiki(false); + assertNotNull(r.getReadme()); + getUser().getRepository(name).delete(); + } + private void deleteRepository(final String name) throws IOException { GHRepository repository = getUser().getRepository(name); if(repository != null) { From c879e9e34d00c3d8f91ea04b028e028b86afff67 Mon Sep 17 00:00:00 2001 From: Daniel Lovera Date: Sun, 13 Dec 2015 21:00:40 +0100 Subject: [PATCH 002/118] Support for auto_init parameter in organization The GitHub api auto_init parameter allows to initialize created repository with a readme file. Add createRepository methods in GHOrganization using auto_init parameter. Already existing createRepository methods use auto_init parameter as false for retro-compatibility. --- .../org/kohsuke/github/GHOrganization.java | 16 ++++++--- .../kohsuke/github/GHOrganizationTest.java | 36 +++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/test/java/org/kohsuke/github/GHOrganizationTest.java diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 83c8a0474..9c4a42042 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -26,19 +26,27 @@ public class GHOrganization extends GHPerson { * Newly created repository. */ public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic) throws IOException { + return createRepository(name, description, homepage, team, isPublic, false); + } + + public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic, boolean autoInit) throws IOException { GHTeam t = getTeams().get(team); if (t==null) throw new IllegalArgumentException("No such team: "+team); - return createRepository(name, description, homepage, t, isPublic); + return createRepository(name, description, homepage, t, isPublic, autoInit); } public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException { + return createRepository(name, description, homepage, team, isPublic, false); + } + + public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic, boolean autoInit) throws IOException { if (team==null) throw new IllegalArgumentException("Invalid team"); // such API doesn't exist, so fall back to HTML scraping return new Requester(root) - .with("name", name).with("description", description).with("homepage", homepage) - .with("public", isPublic).with("team_id",team.getId()).to("/orgs/"+login+"/repos", GHRepository.class).wrap(root); + .with("name", name).with("description", description).with("homepage", homepage) + .with("public", isPublic).with("auto_init", autoInit).with("team_id",team.getId()).to("/orgs/"+login+"/repos", GHRepository.class).wrap(root); } /** @@ -185,7 +193,7 @@ public class GHOrganization extends GHPerson { } public GHTeam createTeam(String name, Permission p, GHRepository... repositories) throws IOException { - return createTeam(name,p, Arrays.asList(repositories)); + return createTeam(name, p, Arrays.asList(repositories)); } /** diff --git a/src/test/java/org/kohsuke/github/GHOrganizationTest.java b/src/test/java/org/kohsuke/github/GHOrganizationTest.java new file mode 100644 index 000000000..3f425f3fe --- /dev/null +++ b/src/test/java/org/kohsuke/github/GHOrganizationTest.java @@ -0,0 +1,36 @@ +package org.kohsuke.github; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; + +public class GHOrganizationTest extends AbstractGitHubApiTestBase { + + public static final String GITHUB_API_TEST_ORG = "github-api-test-org"; + public static final String GITHUB_API_TEST = "github-api-test"; + + @Test + public void testCreateRepository() throws IOException { + GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); + GHRepository repository = org.createRepository(GITHUB_API_TEST, + "a test repository used to test kohsuke's github-api", "http://github-api.kohsuke.org/", "Core Developers", true); + Assert.assertNotNull(repository); + } + + @Test + public void testCreateRepositoryWithAutoInitialization() throws IOException { + GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); + GHRepository repository = org.createRepository(GITHUB_API_TEST, + "a test repository used to test kohsuke's github-api", "http://github-api.kohsuke.org/", "Core Developers", true, true); + Assert.assertNotNull(repository); + Assert.assertNotNull(repository.getReadme()); + } + + @After + public void cleanUp() throws Exception { + GHRepository repository = gitHub.getOrganization(GITHUB_API_TEST_ORG).getRepository(GITHUB_API_TEST); + repository.delete(); + } +} From e94c36b7e6f4cb18d3403a05994a03b528584e2e Mon Sep 17 00:00:00 2001 From: Daniel Lovera Date: Sun, 13 Dec 2015 21:05:36 +0100 Subject: [PATCH 003/118] clean: remove unused import --- src/main/java/org/kohsuke/github/GHOrganization.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 9c4a42042..33daecd59 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -7,7 +7,6 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.TreeMap; From f573f83fb9232a8a8bbbdf185824529e9741c063 Mon Sep 17 00:00:00 2001 From: benbek Date: Tue, 19 Jan 2016 00:05:01 +0200 Subject: [PATCH 004/118] Amendment to the documentation The status reported by GitHub for deleting a file is actually "removed", not "deleted". --- src/main/java/org/kohsuke/github/GHCommit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index a350eeb53..031e15c31 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -102,7 +102,7 @@ public class GHCommit { } /** - * "modified", "added", or "deleted" + * "modified", "added", or "removed" */ public String getStatus() { return status; From 33d95d3e3a2ace95682a34f60f1e25e831541089 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Wed, 20 Jan 2016 23:30:10 +0100 Subject: [PATCH 005/118] Fix error when creating email service hook --- src/main/java/org/kohsuke/github/GHRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index b02481462..fbd64709a 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -475,7 +475,7 @@ public class GHRepository extends GHObject { public void setEmailServiceHook(String address) throws IOException { Map config = new HashMap(); config.put("address", address); - new Requester(root).method("POST").with("name", "email").with("config", config).with("active", "true") + new Requester(root).method("POST").with("name", "email").with("config", config).with("active", true) .to(getApiTailUrl("hooks")); } From c0a05e06501bc162ec15afeaf364964646323cf5 Mon Sep 17 00:00:00 2001 From: Daniel Beck Date: Sun, 21 Feb 2016 01:26:43 +0100 Subject: [PATCH 006/118] Populate commit with data for getCommitShortInfo --- src/main/java/org/kohsuke/github/GHCommit.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index a350eeb53..ee6131709 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -178,7 +178,8 @@ public class GHCommit { User author,committer; - public ShortInfo getCommitShortInfo() { + public ShortInfo getCommitShortInfo() throws IOException { + populate(); return commit; } From f4b129b9f10928f05bd9cdb589fbcfe2d642206c Mon Sep 17 00:00:00 2001 From: Artem Gubanov Date: Thu, 25 Feb 2016 10:46:17 +0200 Subject: [PATCH 007/118] Added getHtmlUrl() to GHCommit --- src/main/java/org/kohsuke/github/GHCommit.java | 9 ++++++++- src/test/java/org/kohsuke/github/AppTest.java | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index a350eeb53..c7825b88b 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -171,7 +171,7 @@ public class GHCommit { String login; } - String url,sha; + String url,html_url,sha; List files; Stats stats; List parents; @@ -213,6 +213,13 @@ public class GHCommit { return stats.deletions; } + /** + * URL of this commit like "https://github.com/kohsuke/sandbox-ant/commit/8ae38db0ea5837313ab5f39d43a6f73de3bd9000" + */ + public URL getHtmlUrl() { + return GitHub.parseURL(html_url); + } + /** * [0-9a-f]{40} SHA1 checksum. */ diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 5d5e0a5fe..82952a796 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -326,6 +326,8 @@ public class AppTest extends AbstractGitHubApiTestBase { System.out.println(commit); assertEquals(1, commit.getParents().size()); assertEquals(1,commit.getFiles().size()); + assertEquals("https://github.com/jenkinsci/jenkins/commit/08c1c9970af4d609ae754fbe803e06186e3206f7", + commit.getHtmlUrl().toString()); File f = commit.getFiles().get(0); assertEquals(48,f.getLinesChanged()); From d80ad778710f17f60ecf86c11de4d3d46a551ff1 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 29 Feb 2016 19:57:16 -0800 Subject: [PATCH 008/118] Use builder pattern to support all the other options --- .../github/GHCreateRepositoryBuilder.java | 114 ++++++++++++++++++ .../org/kohsuke/github/GHOrganization.java | 32 +++-- src/main/java/org/kohsuke/github/GitHub.java | 27 ++--- src/test/java/org/kohsuke/github/AppTest.java | 5 +- .../kohsuke/github/GHOrganizationTest.java | 19 ++- 5 files changed, 162 insertions(+), 35 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java diff --git a/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java b/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java new file mode 100644 index 000000000..492aaf5c8 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHCreateRepositoryBuilder.java @@ -0,0 +1,114 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; + +/** + * Creates a repository + * + * @author Kohsuke Kawaguchi + */ +public class GHCreateRepositoryBuilder { + private final GitHub root; + protected final Requester builder; + private final String apiUrlTail; + + /*package*/ GHCreateRepositoryBuilder(GitHub root, String apiUrlTail, String name) { + this.root = root; + this.apiUrlTail = apiUrlTail; + this.builder = new Requester(root); + this.builder.with("name",name); + } + + public GHCreateRepositoryBuilder description(String description) { + this.builder.with("description",description); + return this; + } + + public GHCreateRepositoryBuilder homepage(URL homepage) { + return homepage(homepage.toExternalForm()); + } + + public GHCreateRepositoryBuilder homepage(String homepage) { + this.builder.with("homepage",homepage); + return this; + } + + /** + * Creates a private repository + */ + public GHCreateRepositoryBuilder private_(boolean b) { + this.builder.with("private",b); + return this; + } + + /** + * Enables issue tracker + */ + public GHCreateRepositoryBuilder issues(boolean b) { + this.builder.with("has_issues",b); + return this; + } + + /** + * Enables wiki + */ + public GHCreateRepositoryBuilder wiki(boolean b) { + this.builder.with("has_wiki",b); + return this; + } + + /** + * Enables downloads + */ + public GHCreateRepositoryBuilder downloads(boolean b) { + this.builder.with("has_downloads",b); + return this; + } + + /** + * If true, create an initial commit with empty README. + */ + public GHCreateRepositoryBuilder autoInit(boolean b) { + this.builder.with("auto_init",b); + return this; + } + + /** + * Creates a default .gitignore + * + * See https://developer.github.com/v3/repos/#create + */ + public GHCreateRepositoryBuilder gitignoreTemplate(String language) { + this.builder.with("gitignore_template",language); + return this; + } + + /** + * Desired license template to apply + * + * See https://developer.github.com/v3/repos/#create + */ + public GHCreateRepositoryBuilder licenseTemplate(String license) { + this.builder.with("license_template",license); + return this; + } + + /** + * The team that gets granted access to this repository. Only valid for creating a repository in + * an organization. + */ + public GHCreateRepositoryBuilder team(GHTeam team) { + if (team!=null) + this.builder.with("team_id",team.getId()); + return this; + } + + /** + * Creates a repository with all the parameters. + */ + public GHRepository create() throws IOException { + return builder.method("POST").to(apiUrlTail, GHRepository.class).wrap(root); + } + +} diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 33daecd59..c4ae92e6d 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -23,29 +23,35 @@ public class GHOrganization extends GHPerson { * * @return * Newly created repository. + * @deprecated + * Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect. */ public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic) throws IOException { - return createRepository(name, description, homepage, team, isPublic, false); - } - - public GHRepository createRepository(String name, String description, String homepage, String team, boolean isPublic, boolean autoInit) throws IOException { GHTeam t = getTeams().get(team); if (t==null) throw new IllegalArgumentException("No such team: "+team); - return createRepository(name, description, homepage, t, isPublic, autoInit); + return createRepository(name, description, homepage, t, isPublic); } + /** + * @deprecated + * Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect. + */ public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic) throws IOException { - return createRepository(name, description, homepage, team, isPublic, false); - } - - public GHRepository createRepository(String name, String description, String homepage, GHTeam team, boolean isPublic, boolean autoInit) throws IOException { if (team==null) throw new IllegalArgumentException("Invalid team"); - // such API doesn't exist, so fall back to HTML scraping - return new Requester(root) - .with("name", name).with("description", description).with("homepage", homepage) - .with("public", isPublic).with("auto_init", autoInit).with("team_id",team.getId()).to("/orgs/"+login+"/repos", GHRepository.class).wrap(root); + return createRepository(name).description(description).homepage(homepage).private_(!isPublic).team(team).create(); + } + + /** + * Starts a builder that creates a new repository. + * + *

+ * You use the returned builder to set various properties, then call {@link GHCreateRepositoryBuilder#create()} + * to finally createa repository. + */ + public GHCreateRepositoryBuilder createRepository(String name) throws IOException { + return new GHCreateRepositoryBuilder(root,"/orgs/"+login+"/repos",name); } /** diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 55d1bcac5..77d178800 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -410,31 +410,28 @@ public class GitHub { /** * Creates a new repository. * - * To create a repository in an organization, see - * {@link GHOrganization#createRepository(String, String, String, GHTeam, boolean)} - * * @return * Newly created repository. + * @deprecated + * Use {@link #createRepository(String)} that uses a builder pattern to let you control every aspect. */ public GHRepository createRepository(String name, String description, String homepage, boolean isPublic) throws IOException { - return createRepository(name, description, homepage, isPublic, false); + return createRepository(name).description(description).homepage(homepage).private_(!isPublic).create(); } /** - * Creates a new repository. + * Starts a builder that creates a new repository. * + *

+ * You use the returned builder to set various properties, then call {@link GHCreateRepositoryBuilder#create()} + * to finally createa repository. + * + *

* To create a repository in an organization, see - * {@link GHOrganization#createRepository(String, String, String, GHTeam, boolean, boolean)} - * - * @return - * Newly created repository. + * {@link GHOrganization#createRepository(String, String, String, GHTeam, boolean)} */ - public GHRepository createRepository(String name, String description, String homepage, boolean isPublic, boolean autoInit) throws IOException { - Requester requester = new Requester(this) - .with("name", name).with("description", description).with("homepage", homepage) - .with("public", isPublic ? 1 : 0) - .with("auto_init", autoInit); - return requester.method("POST").to("/user/repos", GHRepository.class).wrap(this); + public GHCreateRepositoryBuilder createRepository(String name) { + return new GHCreateRepositoryBuilder(this,"/user/repos",name); } /** diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 0ccd0d11c..c3a7d6a43 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -42,7 +42,10 @@ public class AppTest extends AbstractGitHubApiTestBase { public void testRepositoryWithAutoInitializationCRUD() throws IOException { String name = "github-api-test-autoinit"; deleteRepository(name); - GHRepository r = gitHub.createRepository(name, "a test repository for auto init", "http://github-api.kohsuke.org/", true, true); + GHRepository r = gitHub.createRepository(name) + .description("a test repository for auto init") + .homepage("http://github-api.kohsuke.org/") + .autoInit(true).create(); r.enableIssueTracker(false); r.enableDownloads(false); r.enableWiki(false); diff --git a/src/test/java/org/kohsuke/github/GHOrganizationTest.java b/src/test/java/org/kohsuke/github/GHOrganizationTest.java index 3f425f3fe..a1c5d3b92 100644 --- a/src/test/java/org/kohsuke/github/GHOrganizationTest.java +++ b/src/test/java/org/kohsuke/github/GHOrganizationTest.java @@ -8,12 +8,17 @@ import java.io.IOException; public class GHOrganizationTest extends AbstractGitHubApiTestBase { - public static final String GITHUB_API_TEST_ORG = "github-api-test-org"; public static final String GITHUB_API_TEST = "github-api-test"; + private GHOrganization org; + + @Override + public void setUp() throws Exception { + super.setUp(); + org = gitHub.getOrganization("github-api-test-org"); + } @Test public void testCreateRepository() throws IOException { - GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); GHRepository repository = org.createRepository(GITHUB_API_TEST, "a test repository used to test kohsuke's github-api", "http://github-api.kohsuke.org/", "Core Developers", true); Assert.assertNotNull(repository); @@ -21,16 +26,18 @@ public class GHOrganizationTest extends AbstractGitHubApiTestBase { @Test public void testCreateRepositoryWithAutoInitialization() throws IOException { - GHOrganization org = gitHub.getOrganization(GITHUB_API_TEST_ORG); - GHRepository repository = org.createRepository(GITHUB_API_TEST, - "a test repository used to test kohsuke's github-api", "http://github-api.kohsuke.org/", "Core Developers", true, true); + GHRepository repository = org.createRepository(GITHUB_API_TEST) + .description("a test repository used to test kohsuke's github-api") + .homepage("http://github-api.kohsuke.org/") + .team(org.getTeamByName("Core Developers")) + .autoInit(true).create(); Assert.assertNotNull(repository); Assert.assertNotNull(repository.getReadme()); } @After public void cleanUp() throws Exception { - GHRepository repository = gitHub.getOrganization(GITHUB_API_TEST_ORG).getRepository(GITHUB_API_TEST); + GHRepository repository = org.getRepository(GITHUB_API_TEST); repository.delete(); } } From 14f7198a07fc5365eafbd708388bf0e6f6a8d971 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 29 Feb 2016 20:56:28 -0800 Subject: [PATCH 009/118] Handle "all" webhook correctly This fixes #250 --- src/main/java/org/kohsuke/github/GHEvent.java | 17 ++++++++++++++++- src/main/java/org/kohsuke/github/GHHook.java | 6 ++++-- src/main/java/org/kohsuke/github/GHHooks.java | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHEvent.java b/src/main/java/org/kohsuke/github/GHEvent.java index 9e172146a..e8e79bb45 100644 --- a/src/main/java/org/kohsuke/github/GHEvent.java +++ b/src/main/java/org/kohsuke/github/GHEvent.java @@ -1,5 +1,7 @@ package org.kohsuke.github; +import java.util.Locale; + /** * Hook event type. * @@ -33,5 +35,18 @@ public enum GHEvent { STATUS, TEAM_ADD, WATCH, - PING + PING, + /** + * Special event type that means "every possible event" + */ + ALL; + + + /** + * Returns GitHub's internal representation of this event. + */ + String symbol() { + if (this==ALL) return "*"; + return name().toLowerCase(Locale.ENGLISH); + } } diff --git a/src/main/java/org/kohsuke/github/GHHook.java b/src/main/java/org/kohsuke/github/GHHook.java index 7d63f9d95..73b2eb436 100644 --- a/src/main/java/org/kohsuke/github/GHHook.java +++ b/src/main/java/org/kohsuke/github/GHHook.java @@ -26,8 +26,10 @@ public abstract class GHHook extends GHObject { public EnumSet getEvents() { EnumSet s = EnumSet.noneOf(GHEvent.class); - for (String e : events) - s.add(Enum.valueOf(GHEvent.class,e.toUpperCase(Locale.ENGLISH))); + for (String e : events) { + if (e.equals("*")) s.add(GHEvent.ALL); + else s.add(Enum.valueOf(GHEvent.class, e.toUpperCase(Locale.ENGLISH))); + } return s; } diff --git a/src/main/java/org/kohsuke/github/GHHooks.java b/src/main/java/org/kohsuke/github/GHHooks.java index 4ee939c5a..6f64587b1 100644 --- a/src/main/java/org/kohsuke/github/GHHooks.java +++ b/src/main/java/org/kohsuke/github/GHHooks.java @@ -39,7 +39,7 @@ class GHHooks { if (events!=null) { ea = new ArrayList(); for (GHEvent e : events) - ea.add(e.name().toLowerCase(Locale.ENGLISH)); + ea.add(e.symbol()); } GHHook hook = new Requester(root) From 751043bf81a5e3afe3ac15300ca198c5d6a220a4 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 29 Feb 2016 21:01:18 -0800 Subject: [PATCH 010/118] change in the markup generated --- src/test/java/org/kohsuke/github/AppTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index f9fb4c95b..c8d523cd8 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -791,7 +791,7 @@ public class AppTest extends AbstractGitHubApiTestBase { assertTrue(actual.contains("href=\"https://github.com/kohsuke\"")); assertTrue(actual.contains("href=\"https://github.com/kohsuke/github-api/pull/1\"")); assertTrue(actual.contains("class=\"user-mention\"")); - assertTrue(actual.contains("class=\"issue-link\"")); + assertTrue(actual.contains("class=\"issue-link ")); assertTrue(actual.contains("to fix issue")); } From 013eaa30b64a33c70231844e1c52fdbfcd630d27 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 29 Feb 2016 21:03:31 -0800 Subject: [PATCH 011/118] [maven-release-plugin] prepare release github-api-1.73 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a81a8e0fe..05d286b71 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.73-SNAPSHOT + 1.73 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.73 From 54c3070607fb1957c89aa224cdf99f3445311379 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 29 Feb 2016 21:03:34 -0800 Subject: [PATCH 012/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 05d286b71..0af43488f 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.73 + 1.74-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.73 + HEAD From dbc79f8c423749311495cb548c1a9cda1d8638cf Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 1 Mar 2016 19:46:50 -0800 Subject: [PATCH 013/118] Fixing issue raised in https://github.com/kohsuke/github-api/pull/247 From Shredder121, -------------------- Only the HttpURLConnection.method was set by that change. Not the Requester.method. This means that Requester.method is still set to POST, isMethodWithBody will return true, and uc.setDoOutput(true) will be called. I use Okhttp, and their HttpURLConnectionImpl's method changes to POST if you tell it to open a stream to write to. --- src/main/java/org/kohsuke/github/Requester.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index c9835677e..af4819c3a 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -264,10 +264,9 @@ class Requester { */ public int asHttpStatusCode(String tailApiUrl) throws IOException { while (true) {// loop while API rate limit is hit + method("GET"); setupConnection(root.getApiURL(tailApiUrl)); - uc.setRequestMethod("GET"); - buildRequest(); try { @@ -280,12 +279,10 @@ class Requester { public InputStream asStream(String tailApiUrl) throws IOException { while (true) {// loop while API rate limit is hit + method("GET"); // if the download link is encoded with a token on the query string, the default behavior of POST will fail setupConnection(root.getApiURL(tailApiUrl)); - // if the download link is encoded with a token on the query string, the default behavior of POST will fail - uc.setRequestMethod("GET"); - - buildRequest(); + buildRequest(); try { return wrapStream(uc.getInputStream()); From ae85cf4b6c02ba9c330d436bbee39d211428755d Mon Sep 17 00:00:00 2001 From: Manuel Recena Date: Sat, 5 Mar 2016 17:42:25 +0100 Subject: [PATCH 014/118] Improve checkApiUrlValidity() method to support the private mode in GitHub Enterprise servers --- src/main/java/org/kohsuke/github/GitHub.java | 30 ++++++++++++++++++- .../java/org/kohsuke/github/GitHubTest.java | 7 ++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 77d178800..14e7b1336 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -31,6 +31,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.ParseException; @@ -482,7 +483,34 @@ public class GitHub { * Otherwise this method throws {@link IOException} to indicate the problem. */ public void checkApiUrlValidity() throws IOException { - retrieve().to("/", GHApiInfo.class).check(apiUrl); + try { + retrieve().to("/", GHApiInfo.class).check(apiUrl); + } catch (IOException ioe) { + if (isPrivateModeEnabled()) { + throw new IOException("GitHub Enterprise server (" + apiUrl + ") with private mode enabled"); + } + throw ioe; + } + } + + /** + * Ensures if a GitHub Enterprise server is configured in private mode. + * + * @return {@code true} if private mode is enabled. If it tries to use this method with GitHub, returns {@code + * false}. + */ + private boolean isPrivateModeEnabled() { + try { + HttpURLConnection connect = getConnector().connect(getApiURL("/")); + if (connect.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED + && connect.getHeaderField("Server") != null + && connect.getHeaderField("Server").equals("GitHub.com")) { + return true; + } + return false; + } catch (IOException e) { + return false; + } } /** diff --git a/src/test/java/org/kohsuke/github/GitHubTest.java b/src/test/java/org/kohsuke/github/GitHubTest.java index 1663d2414..b8ae4ff0d 100644 --- a/src/test/java/org/kohsuke/github/GitHubTest.java +++ b/src/test/java/org/kohsuke/github/GitHubTest.java @@ -124,6 +124,11 @@ public class GitHubTest { @Test public void testGitHubIsApiUrlValid() throws IOException { GitHub github = GitHub.connectAnonymously(); - github.checkApiUrlValidity(); + //GitHub github = GitHub.connectToEnterpriseAnonymously("https://github.mycompany.com/api/v3/"); + try { + github.checkApiUrlValidity(); + } catch (IOException ioe) { + assertTrue(ioe.getMessage().contains("private mode enabled")); + } } } From ba951cb6e301a56c673f00395e08e87d80422da3 Mon Sep 17 00:00:00 2001 From: Cyrille Le Clerc Date: Sun, 6 Mar 2016 18:09:36 +0100 Subject: [PATCH 015/118] Fix #252: infinite loop because the "hypertext engine" may duplicate '?' generating invalid "https://api.github.com/notifications?all=true&page=2?all=true" instead of "https://api.github.com/notifications?all=true&page=2&all=true". A better fix will be to prevent duplication of parameters ("all=true" in this case). --- .../java/org/kohsuke/github/Requester.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index af4819c3a..5096f5ff4 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -45,6 +45,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.ListIterator; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; @@ -219,15 +220,19 @@ class Requester { } private T _to(String tailApiUrl, Class type, T instance) throws IOException { - while (true) {// loop while API rate limit is hit - if (METHODS_WITHOUT_BODY.contains(method) && !args.isEmpty()) { - StringBuilder qs=new StringBuilder(); - for (Entry arg : args) { - qs.append(qs.length()==0 ? '?' : '&'); - qs.append(arg.key).append('=').append(URLEncoder.encode(arg.value.toString(),"UTF-8")); + if (METHODS_WITHOUT_BODY.contains(method) && !args.isEmpty()) { + boolean questionMarkFound = tailApiUrl.indexOf('?') != -1; + tailApiUrl += questionMarkFound ? '&' : '?'; + for (Iterator it = args.listIterator(); it.hasNext();) { + Entry arg = it.next(); + tailApiUrl += arg.key + '=' + URLEncoder.encode(arg.value.toString(),"UTF-8"); + if (it.hasNext()) { + tailApiUrl += '&'; } - tailApiUrl += qs.toString(); } + } + + while (true) {// loop while API rate limit is hit setupConnection(root.getApiURL(tailApiUrl)); buildRequest(); From 027e4b4f25390627b1ccc386e688246d07a2016d Mon Sep 17 00:00:00 2001 From: Cyrille Le Clerc Date: Sun, 6 Mar 2016 16:11:56 +0100 Subject: [PATCH 016/118] Better error message: introduce HttpException, subclass of IOException with url, http responseCode and http responseMessage to help exception handling. --- pom.xml | 8 ++ src/main/java/org/kohsuke/github/GitHub.java | 6 + .../org/kohsuke/github/HttpException.java | 119 ++++++++++++++++++ .../java/org/kohsuke/github/Requester.java | 28 ++++- 4 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/HttpException.java diff --git a/pom.xml b/pom.xml index 0af43488f..dde789075 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,14 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + + org.codehaus.mojo findbugs-maven-plugin diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 77d178800..fe94840fd 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -31,6 +31,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.ParseException; @@ -55,6 +56,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import java.nio.charset.Charset; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Root of the GitHub API. @@ -68,6 +71,8 @@ import java.nio.charset.Charset; * @author Kohsuke Kawaguchi */ public class GitHub { + protected final transient Logger logger = Logger.getLogger(getClass().getName()); + /*package*/ final String login; /** @@ -458,6 +463,7 @@ public class GitHub { retrieve().to("/user", GHUser.class); return true; } catch (IOException e) { + logger.log(Level.FINEST, "Exception validating credentials on {0} with login {1}: {2}", new Object[]{this.apiUrl, this.login, e, e}); return false; } } diff --git a/src/main/java/org/kohsuke/github/HttpException.java b/src/main/java/org/kohsuke/github/HttpException.java new file mode 100644 index 000000000..37c16f4a1 --- /dev/null +++ b/src/main/java/org/kohsuke/github/HttpException.java @@ -0,0 +1,119 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * Http exception + * + * @author Cyrille Le Clerc + */ +public class HttpException extends IOException { + static final long serialVersionUID = 1L; + + private final int responseCode; + private final String responseMessage; + private final String url; + + /** + * @param message The detail message (which is saved for later retrieval + * by the {@link #getMessage()} method) + * @param responseCode Http response code. {@code -1} if no code can be discerned. + * @param responseMessage Http response message + * @param url The url that was invoked + * @see HttpURLConnection#getResponseCode() + * @see HttpURLConnection#getResponseMessage() + */ + public HttpException(String message, int responseCode, String responseMessage, String url) { + super(message); + this.responseCode = responseCode; + this.responseMessage = responseMessage; + this.url = url; + } + + /** + * @param message The detail message (which is saved for later retrieval + * by the {@link #getMessage()} method) + * @param responseCode Http response code. {@code -1} if no code can be discerned. + * @param responseMessage Http response message + * @param url The url that was invoked + * @param cause The cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @see HttpURLConnection#getResponseCode() + * @see HttpURLConnection#getResponseMessage() + */ + public HttpException(String message, int responseCode, String responseMessage, String url, Throwable cause) { + super(message, cause); + this.responseCode = responseCode; + this.responseMessage = responseMessage; + this.url = url; + } + + /** + * @param message The detail message (which is saved for later retrieval + * by the {@link #getMessage()} method) + * @param responseCode Http response code. {@code -1} if no code can be discerned. + * @param responseMessage Http response message + * @param url The url that was invoked + * @param cause The cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @see HttpURLConnection#getResponseCode() + * @see HttpURLConnection#getResponseMessage() + */ + public HttpException(int responseCode, String responseMessage, String url, Throwable cause) { + super("Server returned HTTP response code: " + responseCode + ", message: '" + responseMessage + "'" + + " for URL: " + url, cause); + this.responseCode = responseCode; + this.responseMessage = responseMessage; + this.url = url; + } + + /** + * @param responseCode Http response code. {@code -1} if no code can be discerned. + * @param responseMessage Http response message + * @param url The url that was invoked + * @param cause The cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @see HttpURLConnection#getResponseCode() + * @see HttpURLConnection#getResponseMessage() + */ + public HttpException(int responseCode, String responseMessage, URL url, Throwable cause) { + this(responseCode, responseMessage, url == null ? null : url.toString(), cause); + } + + /** + * Http response code of the request that cause the exception + * + * @return {@code -1} if no code can be discerned. + */ + public int getResponseCode() { + return responseCode; + } + + /** + * Http response message of the request that cause the exception + * + * @return {@code null} if no response message can be discerned. + */ + public String getResponseMessage() { + return responseMessage; + } + + /** + * The http URL that caused the exception + * + * @return url + */ + public String getUrl() { + return url; + } + + @Override + public String getMessage() { + return super.getMessage(); + } +} diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index af4819c3a..4670b00a8 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -473,21 +473,33 @@ class Requester { } private T parse(Class type, T instance) throws IOException { - if (uc.getResponseCode()==304) - return null; // special case handling for 304 unmodified, as the content will be "" InputStreamReader r = null; + int responseCode = -1; + String responseMessage = null; try { + responseCode = uc.getResponseCode(); + responseMessage = uc.getResponseMessage(); + if (responseCode == 304) { + return null; // special case handling for 304 unmodified, as the content will be "" + } + r = new InputStreamReader(wrapStream(uc.getInputStream()), "UTF-8"); String data = IOUtils.toString(r); if (type!=null) try { return MAPPER.readValue(data,type); } catch (JsonMappingException e) { - throw (IOException)new IOException("Failed to deserialize "+data).initCause(e); + throw (IOException)new IOException("Failed to deserialize " +data).initCause(e); } if (instance!=null) return MAPPER.readerForUpdating(instance).readValue(data); return null; + } catch (FileNotFoundException e) { + // java.net.URLConnection handles 404 exception has FileNotFoundException, don't wrap exception in HttpException + // to preserve backward compatibility + throw e; + } catch (IOException e) { + throw new HttpException(responseCode, responseMessage, uc.getURL(), e); } finally { IOUtils.closeQuietly(r); } @@ -508,7 +520,15 @@ class Requester { * Handle API error by either throwing it or by returning normally to retry. */ /*package*/ void handleApiError(IOException e) throws IOException { - if (uc.getResponseCode() == 401) // Unauthorized == bad creds + int responseCode; + try { + responseCode = uc.getResponseCode(); + } catch (IOException e2) { + // likely to be a network exception (e.g. SSLHandshakeException), + // uc.getResponseCode() and any other getter on the response will cause an exception + throw e; + } + if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 / Unauthorized == bad creds throw e; if ("0".equals(uc.getHeaderField("X-RateLimit-Remaining"))) { From 56379bb3b99ea8c25cf85c0a3577fa633d2c5eec Mon Sep 17 00:00:00 2001 From: Cyrille Le Clerc Date: Mon, 7 Mar 2016 19:25:42 +0100 Subject: [PATCH 017/118] Fix broken log message in GitHub.java and cleanup code as recommended by @jglick --- src/main/java/org/kohsuke/github/GitHub.java | 3 ++- src/main/java/org/kohsuke/github/HttpException.java | 13 ++++++------- src/main/java/org/kohsuke/github/Requester.java | 9 ++++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index fe94840fd..850edaf53 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -463,7 +463,8 @@ public class GitHub { retrieve().to("/user", GHUser.class); return true; } catch (IOException e) { - logger.log(Level.FINEST, "Exception validating credentials on {0} with login {1}: {2}", new Object[]{this.apiUrl, this.login, e, e}); + if (logger.isLoggable(Level.FINE)) + logger.log(Level.FINE, "Exception validating credentials on " + this.apiUrl + " with login '" + this.login + "' " + e, e); return false; } } diff --git a/src/main/java/org/kohsuke/github/HttpException.java b/src/main/java/org/kohsuke/github/HttpException.java index 37c16f4a1..718642299 100644 --- a/src/main/java/org/kohsuke/github/HttpException.java +++ b/src/main/java/org/kohsuke/github/HttpException.java @@ -4,8 +4,12 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.URL; +import javax.annotation.CheckForNull; + /** - * Http exception + * {@link IOException} for http exceptions because {@link HttpURLConnection} throws un-discerned + * {@link IOException} and it can help to know the http response code to decide how to handle an + * http exceptions. * * @author Cyrille Le Clerc */ @@ -81,7 +85,7 @@ public class HttpException extends IOException { * @see HttpURLConnection#getResponseCode() * @see HttpURLConnection#getResponseMessage() */ - public HttpException(int responseCode, String responseMessage, URL url, Throwable cause) { + public HttpException(int responseCode, String responseMessage, @CheckForNull URL url, Throwable cause) { this(responseCode, responseMessage, url == null ? null : url.toString(), cause); } @@ -111,9 +115,4 @@ public class HttpException extends IOException { public String getUrl() { return url; } - - @Override - public String getMessage() { - return super.getMessage(); - } } diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 4670b00a8..6ac2a084c 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -48,6 +48,8 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; @@ -64,7 +66,9 @@ import static org.kohsuke.github.GitHub.*; */ class Requester { private static final List METHODS_WITHOUT_BODY = asList("GET", "DELETE"); - + + protected final transient Logger logger = Logger.getLogger(getClass().getName()); + private final GitHub root; private final List args = new ArrayList(); private final Map headers = new LinkedHashMap(); @@ -526,6 +530,9 @@ class Requester { } catch (IOException e2) { // likely to be a network exception (e.g. SSLHandshakeException), // uc.getResponseCode() and any other getter on the response will cause an exception + if (logger.isLoggable(Level.FINE)) + logger.log(Level.FINE, "Silently ignore exception retrieving response code for '" + uc.getURL() + "'" + + " handling exception " + e, e); throw e; } if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) // 401 / Unauthorized == bad creds From e09185fd0eb92d464ee44ce845db26dd889a5677 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 22:51:48 -0800 Subject: [PATCH 018/118] Logger should be static --- src/main/java/org/kohsuke/github/GitHub.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 850edaf53..4ac80c994 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -25,13 +25,13 @@ package org.kohsuke.github; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; +import static java.util.logging.Level.FINE; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; -import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.text.ParseException; @@ -56,7 +56,6 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import java.nio.charset.Charset; -import java.util.logging.Level; import java.util.logging.Logger; /** @@ -71,8 +70,6 @@ import java.util.logging.Logger; * @author Kohsuke Kawaguchi */ public class GitHub { - protected final transient Logger logger = Logger.getLogger(getClass().getName()); - /*package*/ final String login; /** @@ -463,8 +460,8 @@ public class GitHub { retrieve().to("/user", GHUser.class); return true; } catch (IOException e) { - if (logger.isLoggable(Level.FINE)) - logger.log(Level.FINE, "Exception validating credentials on " + this.apiUrl + " with login '" + this.login + "' " + e, e); + if (LOGGER.isLoggable(FINE)) + LOGGER.log(FINE, "Exception validating credentials on " + this.apiUrl + " with login '" + this.login + "' " + e, e); return false; } } @@ -611,4 +608,6 @@ public class GitHub { } /* package */ static final String GITHUB_URL = "https://api.github.com"; + + private static final Logger LOGGER = Logger.getLogger(GitHub.class.getName()); } From ae49166aa2f162a1e65322641ccc8247e6ca9a5b Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 22:55:44 -0800 Subject: [PATCH 019/118] No such parameter exists on this method --- src/main/java/org/kohsuke/github/HttpException.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/HttpException.java b/src/main/java/org/kohsuke/github/HttpException.java index 718642299..670cb491f 100644 --- a/src/main/java/org/kohsuke/github/HttpException.java +++ b/src/main/java/org/kohsuke/github/HttpException.java @@ -56,8 +56,6 @@ public class HttpException extends IOException { } /** - * @param message The detail message (which is saved for later retrieval - * by the {@link #getMessage()} method) * @param responseCode Http response code. {@code -1} if no code can be discerned. * @param responseMessage Http response message * @param url The url that was invoked From dba84a33b9702b0fde265dad9bdb3bec897a5ce0 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 22:55:58 -0800 Subject: [PATCH 020/118] Logger should be static --- src/main/java/org/kohsuke/github/Requester.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 6ac2a084c..311b3320b 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -48,7 +48,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; -import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -57,6 +56,7 @@ import java.util.zip.GZIPInputStream; import javax.annotation.WillClose; import static java.util.Arrays.asList; +import static java.util.logging.Level.FINE; import static org.kohsuke.github.GitHub.*; /** @@ -65,10 +65,6 @@ import static org.kohsuke.github.GitHub.*; * @author Kohsuke Kawaguchi */ class Requester { - private static final List METHODS_WITHOUT_BODY = asList("GET", "DELETE"); - - protected final transient Logger logger = Logger.getLogger(getClass().getName()); - private final GitHub root; private final List args = new ArrayList(); private final Map headers = new LinkedHashMap(); @@ -530,8 +526,8 @@ class Requester { } catch (IOException e2) { // likely to be a network exception (e.g. SSLHandshakeException), // uc.getResponseCode() and any other getter on the response will cause an exception - if (logger.isLoggable(Level.FINE)) - logger.log(Level.FINE, "Silently ignore exception retrieving response code for '" + uc.getURL() + "'" + + if (LOGGER.isLoggable(FINE)) + LOGGER.log(FINE, "Silently ignore exception retrieving response code for '" + uc.getURL() + "'" + " handling exception " + e, e); throw e; } @@ -557,4 +553,7 @@ class Requester { IOUtils.closeQuietly(es); } } + + private static final List METHODS_WITHOUT_BODY = asList("GET", "DELETE"); + private static final Logger LOGGER = Logger.getLogger(Requester.class.getName()); } From cd8d9556468475e8ed6108a6499f4cd119a0a899 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 23:06:21 -0800 Subject: [PATCH 021/118] Documenting what one gets --- src/main/java/org/kohsuke/github/GitHub.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 14e7b1336..10bb3ea09 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -502,6 +502,25 @@ public class GitHub { private boolean isPrivateModeEnabled() { try { HttpURLConnection connect = getConnector().connect(getApiURL("/")); + /* + $ curl -i https://github.mycompany.com/api/v3/ + HTTP/1.1 401 Unauthorized + Server: GitHub.com + Date: Sat, 05 Mar 2016 19:45:01 GMT + Content-Type: application/json; charset=utf-8 + Content-Length: 130 + Status: 401 Unauthorized + X-GitHub-Media-Type: github.v3 + X-XSS-Protection: 1; mode=block + X-Frame-Options: deny + Content-Security-Policy: default-src 'none' + Access-Control-Allow-Credentials: true + Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval + Access-Control-Allow-Origin: * + X-GitHub-Request-Id: dbc70361-b11d-4131-9a7f-674b8edd0411 + Strict-Transport-Security: max-age=31536000; includeSubdomains; preload + X-Content-Type-Options: nosniff + */ if (connect.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED && connect.getHeaderField("Server") != null && connect.getHeaderField("Server").equals("GitHub.com")) { From 10f55cc54926ab47da73da6d54dc3dd52f397add Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 23:10:41 -0800 Subject: [PATCH 022/118] Checking another header I think it's better to pick a header that's unique to GitHub. --- src/main/java/org/kohsuke/github/GitHub.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 10bb3ea09..b8673e453 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -25,6 +25,7 @@ package org.kohsuke.github; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; +import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; @@ -501,7 +502,7 @@ public class GitHub { */ private boolean isPrivateModeEnabled() { try { - HttpURLConnection connect = getConnector().connect(getApiURL("/")); + HttpURLConnection uc = getConnector().connect(getApiURL("/")); /* $ curl -i https://github.mycompany.com/api/v3/ HTTP/1.1 401 Unauthorized @@ -521,12 +522,8 @@ public class GitHub { Strict-Transport-Security: max-age=31536000; includeSubdomains; preload X-Content-Type-Options: nosniff */ - if (connect.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED - && connect.getHeaderField("Server") != null - && connect.getHeaderField("Server").equals("GitHub.com")) { - return true; - } - return false; + return uc.getResponseCode() == HTTP_UNAUTHORIZED + && uc.getHeaderField("X-GitHub-Media-Type") != null; } catch (IOException e) { return false; } From 3b764f9c9081df2a93922603506f5df976394182 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 23:11:22 -0800 Subject: [PATCH 023/118] Don't lose the original problem --- src/main/java/org/kohsuke/github/GitHub.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index b8673e453..cb94f1076 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -486,11 +486,11 @@ public class GitHub { public void checkApiUrlValidity() throws IOException { try { retrieve().to("/", GHApiInfo.class).check(apiUrl); - } catch (IOException ioe) { + } catch (IOException e) { if (isPrivateModeEnabled()) { - throw new IOException("GitHub Enterprise server (" + apiUrl + ") with private mode enabled"); + throw (IOException)new IOException("GitHub Enterprise server (" + apiUrl + ") with private mode enabled").initCause(e); } - throw ioe; + throw e; } } From 1954a9f3f8d998ad6a349c044960a33cd24bfd9a Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 23:12:50 -0800 Subject: [PATCH 024/118] This isn't just about API URL but it also checks the valid credential --- src/main/java/org/kohsuke/github/GitHub.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index cb94f1076..7aa928e78 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -477,7 +477,10 @@ public class GitHub { } /** - * Ensures that the API URL is valid. + * Tests the connection. + * + *

+ * Verify that the API URL and credentials are valid to access this GitHub. * *

* This method returns normally if the endpoint is reachable and verified to be GitHub API URL. From 7a78f9f5aac0d35d07cc7d958fe5d7ba8a5440ff Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 23:14:40 -0800 Subject: [PATCH 025/118] No need to require 1.6 --- pom.xml | 8 -------- src/main/java/org/kohsuke/github/HttpException.java | 6 ++++-- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index dde789075..0af43488f 100644 --- a/pom.xml +++ b/pom.xml @@ -46,14 +46,6 @@ - - org.apache.maven.plugins - maven-compiler-plugin - - 1.6 - 1.6 - - org.codehaus.mojo findbugs-maven-plugin diff --git a/src/main/java/org/kohsuke/github/HttpException.java b/src/main/java/org/kohsuke/github/HttpException.java index 670cb491f..16c8e68be 100644 --- a/src/main/java/org/kohsuke/github/HttpException.java +++ b/src/main/java/org/kohsuke/github/HttpException.java @@ -49,7 +49,8 @@ public class HttpException extends IOException { * @see HttpURLConnection#getResponseMessage() */ public HttpException(String message, int responseCode, String responseMessage, String url, Throwable cause) { - super(message, cause); + super(message); + initCause(cause); this.responseCode = responseCode; this.responseMessage = responseMessage; this.url = url; @@ -67,7 +68,8 @@ public class HttpException extends IOException { */ public HttpException(int responseCode, String responseMessage, String url, Throwable cause) { super("Server returned HTTP response code: " + responseCode + ", message: '" + responseMessage + "'" + - " for URL: " + url, cause); + " for URL: " + url); + initCause(cause); this.responseCode = responseCode; this.responseMessage = responseMessage; this.url = url; From c1c2a2735895622fafe69003c015a7b8a4285f50 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 23:21:07 -0800 Subject: [PATCH 026/118] Doc improvement --- src/main/java/org/kohsuke/github/GitHubBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GitHubBuilder.java b/src/main/java/org/kohsuke/github/GitHubBuilder.java index 42a0f2be6..2abe16f9c 100644 --- a/src/main/java/org/kohsuke/github/GitHubBuilder.java +++ b/src/main/java/org/kohsuke/github/GitHubBuilder.java @@ -15,7 +15,7 @@ import java.util.Map.Entry; import java.util.Properties; /** - * + * Configures connection details and produces {@link GitHub}. * * @since 1.59 */ From 14dcb37ee1ea225b73b548faae313ab512ae69a4 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 11 Mar 2016 23:29:58 -0800 Subject: [PATCH 027/118] Not all caller wants GET --- src/main/java/org/kohsuke/github/GHContent.java | 3 ++- src/main/java/org/kohsuke/github/Requester.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHContent.java b/src/main/java/org/kohsuke/github/GHContent.java index 895550521..88a551736 100644 --- a/src/main/java/org/kohsuke/github/GHContent.java +++ b/src/main/java/org/kohsuke/github/GHContent.java @@ -115,7 +115,8 @@ public class GHContent { * Retrieves the actual content stored here. */ public InputStream read() throws IOException { - return new Requester(root).asStream(getDownloadUrl()); + // if the download link is encoded with a token on the query string, the default behavior of POST will fail + return new Requester(root).method("GET").asStream(getDownloadUrl()); } /** diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index b30578759..4a9bf67ee 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -284,7 +284,6 @@ class Requester { public InputStream asStream(String tailApiUrl) throws IOException { while (true) {// loop while API rate limit is hit - method("GET"); // if the download link is encoded with a token on the query string, the default behavior of POST will fail setupConnection(root.getApiURL(tailApiUrl)); buildRequest(); From 906d9af7b757d6b4da5a7b6f15eb60bafe490120 Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Sat, 12 Mar 2016 21:48:50 +0100 Subject: [PATCH 028/118] Include the animal sniffer plugin 7a78f9f5aac0d35d07cc7d958fe5d7ba8a5440ff set the compiler level back to 5, but there are no guarantees that we don't accidentally use any features from newer class libraries. --- pom.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/pom.xml b/pom.xml index 0af43488f..63ff3acb0 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,27 @@ + + org.codehaus.mojo + animal-sniffer-maven-plugin + 1.15 + + + org.codehaus.mojo.signature + java15 + 1.0 + + + + + ensure-java-1.5-class-library + test + + check + + + + com.infradna.tool bridge-method-injector From 755d5f77ea0d990184d1068b5bcb450380b9d7d1 Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Sat, 12 Mar 2016 21:56:56 +0100 Subject: [PATCH 029/118] Java 5 doesn't have Arrays.copyOf() http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Arrays.html --- src/main/java/org/kohsuke/github/GHCompare.java | 10 ++++++---- .../org/kohsuke/github/GHPullRequestCommitDetail.java | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHCompare.java b/src/main/java/org/kohsuke/github/GHCompare.java index c9c882ba4..100753db0 100644 --- a/src/main/java/org/kohsuke/github/GHCompare.java +++ b/src/main/java/org/kohsuke/github/GHCompare.java @@ -4,8 +4,6 @@ import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.net.URL; -import java.util.Arrays; -import java.util.Date; /** * The model user for comparing 2 commits in the GitHub API. @@ -72,7 +70,9 @@ public class GHCompare { * @return A copy of the array being stored in the class. */ public Commit[] getCommits() { - return Arrays.copyOf(commits, commits.length); + Commit[] newValue = new Commit[commits.length]; + System.arraycopy(commits, 0, newValue, 0, commits.length); + return newValue; } /** @@ -80,7 +80,9 @@ public class GHCompare { * @return A copy of the array being stored in the class. */ public GHCommit.File[] getFiles() { - return Arrays.copyOf(files, files.length); + GHCommit.File[] newValue = new GHCommit.File[files.length]; + System.arraycopy(files, 0, newValue, 0, files.length); + return newValue; } public GHCompare wrap(GHRepository owner) { diff --git a/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java b/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java index d4b48da53..e6c558b9e 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java +++ b/src/main/java/org/kohsuke/github/GHPullRequestCommitDetail.java @@ -27,7 +27,6 @@ import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.net.URL; -import java.util.Arrays; /** * Commit detail inside a {@link GHPullRequest}. @@ -144,6 +143,8 @@ public class GHPullRequestCommitDetail { } public CommitPointer[] getParents() { - return Arrays.copyOf(parents, parents.length); + CommitPointer[] newValue = new CommitPointer[parents.length]; + System.arraycopy(parents, 0, newValue, 0, parents.length); + return newValue; } } From f9014dbab36bd8b48275ab49c127b6132d32969c Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Sat, 12 Mar 2016 21:58:27 +0100 Subject: [PATCH 030/118] Convert to legacy Throwable.initCause() --- src/main/java/org/kohsuke/github/GHRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index fbd64709a..c74d9095a 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -1152,7 +1152,7 @@ public class GHRepository extends GHObject { try { payload = content.getBytes("UTF-8"); } catch (UnsupportedEncodingException ex) { - throw new IOException("UTF-8 encoding is not supported", ex); + throw (IOException) new IOException("UTF-8 encoding is not supported").initCause(ex); } return createContent(payload, commitMessage, path, branch); } From 36d5b092d77660ab0d7b59f6f94ca37ba6f76d1a Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Sat, 12 Mar 2016 21:59:51 +0100 Subject: [PATCH 031/118] Java 5 doesn't have new String(byte[], Charset) http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html --- src/main/java/org/kohsuke/github/GitHub.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index d957212b2..6180f768b 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -57,7 +57,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; -import java.nio.charset.Charset; import java.util.logging.Logger; /** @@ -134,8 +133,8 @@ public class GitHub { } else { if (password!=null) { String authorization = (login + ':' + password); - Charset charset = Charsets.UTF_8; - encodedAuthorization = "Basic "+new String(Base64.encodeBase64(authorization.getBytes(charset)), charset); + String charsetName = Charsets.UTF_8.name(); + encodedAuthorization = "Basic "+new String(Base64.encodeBase64(authorization.getBytes(charsetName)), charsetName); } else {// anonymous access encodedAuthorization = null; } From 0cd5147e1ab2c4549c817db340d94bcdf51d02d3 Mon Sep 17 00:00:00 2001 From: Ruben Dijkstra Date: Sat, 12 Mar 2016 22:01:25 +0100 Subject: [PATCH 032/118] Java 5 doesn't have TimeUnit.HOURS http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/TimeUnit.html --- src/main/java/org/kohsuke/github/GitHub.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 6180f768b..22792a879 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -48,7 +48,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; -import java.util.concurrent.TimeUnit; import org.apache.commons.codec.Charsets; import org.apache.commons.codec.binary.Base64; @@ -264,7 +263,8 @@ public class GitHub { // see issue #78 GHRateLimit r = new GHRateLimit(); r.limit = r.remaining = 1000000; - r.reset = new Date(System.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)); + long hours = 1000L * 60 * 60; + r.reset = new Date(System.currentTimeMillis() + 1 * hours ); return r; } } From 397886d289cd4e2c1a5acabb7b2397c907d484be Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 18 Mar 2016 19:08:51 -0700 Subject: [PATCH 033/118] Excluding a flaky test --- src/test/java/org/kohsuke/github/GHContentIntegrationTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java b/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java index 7848143a8..8e3873708 100644 --- a/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java +++ b/src/test/java/org/kohsuke/github/GHContentIntegrationTest.java @@ -66,7 +66,8 @@ public class GHContentIntegrationTest extends AbstractGitHubApiTestBase { assertNotNull(updatedContentResponse.getCommit()); assertNotNull(updatedContentResponse.getContent()); - assertEquals("this is some new content\n", updatedContent.getContent()); + // due to what appears to be a cache propagation delay, this test is too flaky + // assertEquals("this is some new content\n", updatedContent.getContent()); GHContentUpdateResponse deleteResponse = updatedContent.delete("Enough of this foolishness!"); From a31395ed806aed032243672d3e4f1d796cefadd9 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 18 Mar 2016 19:15:52 -0700 Subject: [PATCH 034/118] Signature fix for Java5 --- .../java/org/kohsuke/github/GHContent.java | 4 ++-- .../java/org/kohsuke/github/GHRepository.java | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHContent.java b/src/main/java/org/kohsuke/github/GHContent.java index 88a551736..8b6f6fea5 100644 --- a/src/main/java/org/kohsuke/github/GHContent.java +++ b/src/main/java/org/kohsuke/github/GHContent.java @@ -78,7 +78,7 @@ public class GHContent { */ @SuppressFBWarnings("DM_DEFAULT_ENCODING") public String getContent() throws IOException { - return new String(DatatypeConverter.parseBase64Binary(getEncodedContent())); + return new String(Base64.decodeBase64(getEncodedContent())); } /** @@ -179,7 +179,7 @@ public class GHContent { } public GHContentUpdateResponse update(byte[] newContentBytes, String commitMessage, String branch) throws IOException { - String encodedContent = DatatypeConverter.printBase64Binary(newContentBytes); + String encodedContent = Base64.encodeBase64String(newContentBytes); Requester requester = new Requester(root) .with("path", path) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index c74d9095a..326564e52 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -26,9 +26,9 @@ package org.kohsuke.github; import com.fasterxml.jackson.annotation.JsonProperty; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; -import javax.xml.bind.DatatypeConverter; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; @@ -36,7 +36,19 @@ import java.io.InterruptedIOException; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.net.URL; -import java.util.*; +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; import static java.util.Arrays.asList; @@ -1165,7 +1177,7 @@ public class GHRepository extends GHObject { Requester requester = new Requester(root) .with("path", path) .with("message", commitMessage) - .with("content", DatatypeConverter.printBase64Binary(contentBytes)) + .with("content", Base64.encodeBase64String(contentBytes)) .method("PUT"); if (branch != null) { From 557ae4165c05b7c37d09e93ac5025cdae6b1db7b Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 18 Mar 2016 19:19:51 -0700 Subject: [PATCH 035/118] Not important --- src/main/java/org/kohsuke/github/Requester.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 4a9bf67ee..8f922b4ff 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -24,6 +24,7 @@ package org.kohsuke.github; import com.fasterxml.jackson.databind.JsonMappingException; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import org.apache.commons.io.IOUtils; import java.io.FileNotFoundException; @@ -138,7 +139,7 @@ class Requester { // by convention Java constant names are upper cases, but github uses // lower-case constants. GitHub also uses '-', which in Java we always // replace by '_' - return with(key, e.toString().toLowerCase(Locale.ENGLISH).replace('_','-')); + return with(key, e.toString().toLowerCase(Locale.ENGLISH).replace('_', '-')); } public Requester with(String key, String value) { @@ -216,9 +217,10 @@ class Requester { */ @Deprecated public T to(String tailApiUrl, Class type, String method) throws IOException { - return method(method).to(tailApiUrl,type); + return method(method).to(tailApiUrl, type); } + @SuppressFBWarnings("SBSC_USE_STRINGBUFFER_CONCATENATION") private T _to(String tailApiUrl, Class type, T instance) throws IOException { if (METHODS_WITHOUT_BODY.contains(method) && !args.isEmpty()) { boolean questionMarkFound = tailApiUrl.indexOf('?') != -1; From 255c9935488c4d64e9869703382e06934d826a8b Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 18 Mar 2016 19:22:34 -0700 Subject: [PATCH 036/118] [maven-release-plugin] prepare release github-api-1.74 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 63ff3acb0..af07ce2d5 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.74-SNAPSHOT + 1.74 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.74 From d30b0403ceb06c71dc9b099352fb9f03045772aa Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 18 Mar 2016 19:22:37 -0700 Subject: [PATCH 037/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index af07ce2d5..97139fb43 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.74 + 1.75-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.74 + HEAD From ce140460af99ad73da3136f7a9343f61e5f2129b Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Mon, 4 Apr 2016 17:30:48 +0200 Subject: [PATCH 038/118] [#269] Add reopen method on GHMilestone --- src/main/java/org/kohsuke/github/GHMilestone.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHMilestone.java b/src/main/java/org/kohsuke/github/GHMilestone.java index 0d1b43224..48f8364bb 100644 --- a/src/main/java/org/kohsuke/github/GHMilestone.java +++ b/src/main/java/org/kohsuke/github/GHMilestone.java @@ -72,12 +72,19 @@ public class GHMilestone extends GHObject { } /** - * Closes this issue. + * Closes this milestone. */ public void close() throws IOException { edit("state", "closed"); } + /** + * Reopens this milestone. + */ + public void reopen() throws IOException { + edit("state", "open"); + } + private void edit(String key, Object value) throws IOException { new Requester(root)._with(key, value).method("PATCH").to(getApiRoute()); } From 715192d26cca81fe118e91f36c53109068011fce Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 13 Apr 2016 13:07:58 -0700 Subject: [PATCH 039/118] [maven-release-plugin] prepare release github-api-1.75 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 97139fb43..399b8b56e 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.75-SNAPSHOT + 1.75 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.75 From 6b5ade3ca09bb53a5880dc227fd187fc51299f7c Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 13 Apr 2016 13:08:02 -0700 Subject: [PATCH 040/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 399b8b56e..437851005 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.75 + 1.76-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.75 + HEAD From beae9fd6ec1b94fd58fd6260a38a8c4eacf333bc Mon Sep 17 00:00:00 2001 From: noctarius Date: Thu, 14 Apr 2016 07:09:05 +0200 Subject: [PATCH 041/118] Added support for the extended stargazers API in Github V3 API --- .../java/org/kohsuke/github/GHRepository.java | 26 +++++++++- .../java/org/kohsuke/github/GHStargazer.java | 48 +++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/kohsuke/github/GHStargazer.java diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 326564e52..26cba1308 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -935,12 +935,36 @@ public class GHRepository extends GHObject { } /** - * Lists all the users who have starred this repo. + * Lists all the users who have starred this repo based on the old version of the API. For + * additional information, like date when the repository was starred, see {@link #listExtendedStargazers()} */ public PagedIterable listStargazers() { return listUsers("stargazers"); } + /** + * Lists all the users who have starred this repo based on new version of the API, having extended + * information like the time when the repository was starred. For compatibility with the old API + * see {@link #listStargazers()} + */ + public PagedIterable listExtendedStargazers() { + return new PagedIterable() { + @Override + public PagedIterator _iterator(int pageSize) { + Requester requester = root.retrieve(); + requester.setHeader("Accept", "application/vnd.github.v3.star+json"); + return new PagedIterator(requester.asIterator(getApiTailUrl("stargazers"), GHStargazer[].class, pageSize)) { + @Override + protected void wrapUp(GHStargazer[] page) { + for (GHStargazer c : page) { + c.wrapUp(GHRepository.this); + } + } + }; + } + }; + } + private PagedIterable listUsers(final String suffix) { return new PagedIterable() { public PagedIterator _iterator(int pageSize) { diff --git a/src/main/java/org/kohsuke/github/GHStargazer.java b/src/main/java/org/kohsuke/github/GHStargazer.java new file mode 100644 index 000000000..20b3ef8a7 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHStargazer.java @@ -0,0 +1,48 @@ +package org.kohsuke.github; + +import java.util.Date; + +/** + * A stargazer at a repository on GitHub. + * + * @author noctarius + */ +public class GHStargazer { + + private GHRepository repository; + private String starred_at; + private GHUser user; + + /** + * Gets the repository that is stargazed + * + * @return the starred repository + */ + public GHRepository getRepository() { + return repository; + } + + /** + * Gets the date when the repository was starred, however old stars before + * August 2012, will all show the date the API was changed to support starred_at. + * + * @return the date the stargazer was added + */ + public Date getStarredAt() { + return GitHub.parseDate(starred_at); + } + + /** + * Gets the user that starred the repository + * + * @return the stargazer user + */ + public GHUser getUser() { + return user; + } + + void wrapUp(GHRepository repository) { + this.repository = repository; + user.wrapUp(repository.root); + } +} From 007378c3a6f4d8ea87abd1dfd6a7f8cfc9feac80 Mon Sep 17 00:00:00 2001 From: thug-gamer Date: Fri, 29 Apr 2016 11:41:14 +0200 Subject: [PATCH 042/118] Add support to delete a team Add a method to delete a team. --- src/main/java/org/kohsuke/github/GHTeam.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index cf7dd1fc9..76555f6da 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -126,6 +126,13 @@ public class GHTeam { public void remove(GHRepository r) throws IOException { org.root.retrieve().method("DELETE").to(api("/repos/" + r.getOwnerName() + '/' + r.getName()), null); } + + /** + * Deletes this team. + */ + public void delete() throws IOException { + org.root.retrieve().method("DELETE").to(api("")); + } private String api(String tail) { return "/teams/"+id+tail; From baedad81240b75334a7ddf138a015ef6207de76b Mon Sep 17 00:00:00 2001 From: Konda Reddy Date: Sat, 30 Apr 2016 13:20:44 -0500 Subject: [PATCH 043/118] Updated Date was wrong --- src/main/java/org/kohsuke/github/GHPerson.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java index e9a750f2c..ef93dd75a 100644 --- a/src/main/java/org/kohsuke/github/GHPerson.java +++ b/src/main/java/org/kohsuke/github/GHPerson.java @@ -204,7 +204,7 @@ public abstract class GHPerson extends GHObject { public Date getUpdatedAt() throws IOException { populate(); - return super.getCreatedAt(); + return super.getUpdatedAt(); } /** From 35dec7a5ec3d1a8174176356e62b81746e085b7f Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Tue, 3 May 2016 18:19:57 -0400 Subject: [PATCH 044/118] Fixed broken link. --- src/main/java/org/kohsuke/github/GHEvent.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHEvent.java b/src/main/java/org/kohsuke/github/GHEvent.java index e8e79bb45..b33cb991e 100644 --- a/src/main/java/org/kohsuke/github/GHEvent.java +++ b/src/main/java/org/kohsuke/github/GHEvent.java @@ -5,10 +5,9 @@ import java.util.Locale; /** * Hook event type. * - * See http://developer.github.com/v3/events/types/ - * * @author Kohsuke Kawaguchi * @see GHEventInfo + * @see Event type reference */ public enum GHEvent { COMMIT_COMMENT, From d530b34073d575261974104ddb435798e5fb6b98 Mon Sep 17 00:00:00 2001 From: Andy Pemberton Date: Sat, 14 May 2016 08:58:42 -0400 Subject: [PATCH 045/118] Add Slug to GHTeam per v3 API: https://developer.github.com/v3/orgs/teams/ --- src/main/java/org/kohsuke/github/GHOrganization.java | 11 +++++++++++ src/main/java/org/kohsuke/github/GHTeam.java | 6 +++++- src/test/java/org/kohsuke/github/AppTest.java | 7 +++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index c4ae92e6d..0c62fd8a2 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -93,6 +93,17 @@ public class GHOrganization extends GHPerson { return null; } + /** + * Finds a team that has the given slug in its {@link GHTeam#getSlug()} + */ + public GHTeam getTeamBySlug(String slug) throws IOException { + for (GHTeam t : listTeams()) { + if(t.getSlug().equals(slug)) + return t; + } + return null; + } + /** * Checks if this organization has the specified user as a member. */ diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index cf7dd1fc9..e0cd33b8b 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -12,7 +12,7 @@ import java.util.TreeMap; * @author Kohsuke Kawaguchi */ public class GHTeam { - private String name,permission; + private String name,permission,slug; private int id; private GHOrganization organization; // populated by GET /user/teams where Teams+Orgs are returned together @@ -43,6 +43,10 @@ public class GHTeam { return permission; } + public String getSlug() { + return slug; + } + public int getId() { return id; } diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index c8d523cd8..905818981 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -335,6 +335,13 @@ public class AppTest extends AbstractGitHubApiTestBase { assertNotNull(e); } + @Test + public void testOrgTeamBySlug() throws Exception { + kohsuke(); + GHTeam e = gitHub.getOrganization("github-api-test-org").getTeamBySlug("core-developers"); + assertNotNull(e); + } + @Test public void testCommit() throws Exception { GHCommit commit = gitHub.getUser("jenkinsci").getRepository("jenkins").getCommit("08c1c9970af4d609ae754fbe803e06186e3206f7"); From 5f95987a487491aa9b1584051b3304c171d32bce Mon Sep 17 00:00:00 2001 From: Andy Pemberton Date: Sat, 14 May 2016 20:07:04 -0400 Subject: [PATCH 046/118] related to JENKINS-34834. updating test for similar condition --- src/test/java/org/kohsuke/github/AppTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index c8d523cd8..06ddabf44 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -221,10 +221,12 @@ public class AppTest extends AbstractGitHubApiTestBase { } @Test - public void testMyTeamsContainsAllMyOrganizations() throws IOException { + public void testMyOrganizationsContainMyTeams() throws IOException { Map> teams = gitHub.getMyTeams(); Map myOrganizations = gitHub.getMyOrganizations(); - assertEquals(teams.keySet(), myOrganizations.keySet()); + //GitHub no longer has default 'owners' team, so there may be organization memberships without a team + //https://help.github.com/articles/about-improved-organization-permissions/ + assertTrue(myOrganizations.keySet().containsAll(teams.keySet())); } @Test From 3c5592c1c8e77341a3c24213e779a464b77228c0 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Thu, 2 Jun 2016 22:05:24 -0700 Subject: [PATCH 047/118] Following the convention with GHMyself.getEmails2() This way the method is more discoverable with IDE auto-completion --- src/main/java/org/kohsuke/github/GHRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 26cba1308..3e7962b56 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -936,7 +936,7 @@ public class GHRepository extends GHObject { /** * Lists all the users who have starred this repo based on the old version of the API. For - * additional information, like date when the repository was starred, see {@link #listExtendedStargazers()} + * additional information, like date when the repository was starred, see {@link #listStargazers2()} */ public PagedIterable listStargazers() { return listUsers("stargazers"); @@ -947,7 +947,7 @@ public class GHRepository extends GHObject { * information like the time when the repository was starred. For compatibility with the old API * see {@link #listStargazers()} */ - public PagedIterable listExtendedStargazers() { + public PagedIterable listStargazers2() { return new PagedIterable() { @Override public PagedIterator _iterator(int pageSize) { From cde501af8de9b871dc53e656aac6b4bd22196dcb Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Thu, 2 Jun 2016 22:36:47 -0700 Subject: [PATCH 048/118] More meaningful toString() method Produce toString without dilligently adding it to every single class. Rely on heuristics to cut down the number of fields to show. --- src/main/java/org/kohsuke/github/GHIssue.java | 1 + .../java/org/kohsuke/github/GHObject.java | 40 +++++++++++++++++++ .../java/org/kohsuke/github/GHRepository.java | 8 +--- src/main/java/org/kohsuke/github/GHUser.java | 5 --- .../org/kohsuke/github/SkipFromToString.java | 16 ++++++++ src/test/java/org/kohsuke/github/AppTest.java | 13 ++++++ 6 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/SkipFromToString.java diff --git a/src/main/java/org/kohsuke/github/GHIssue.java b/src/main/java/org/kohsuke/github/GHIssue.java index 39e5c24b7..a5afad6d2 100644 --- a/src/main/java/org/kohsuke/github/GHIssue.java +++ b/src/main/java/org/kohsuke/github/GHIssue.java @@ -54,6 +54,7 @@ public class GHIssue extends GHObject { protected int number; protected String closed_at; protected int comments; + @SkipFromToString protected String body; // for backward compatibility with < 1.63, this collection needs to hold instances of Label, not GHLabel protected List

+ * Any exception thrown from this method will cause the request to fail, and the caller of github-api + * will receive an exception. If this method returns normally, another request will be attempted. + * For that to make sense, the implementation needs to wait for some time. + * + * @see API documentation from GitHub + * @param e + * Exception from Java I/O layer. If you decide to fail the processing, you can throw + * this exception (or wrap this exception into another exception and throw it.) + * @param uc + * Connection that resulted in an error. Useful for accessing other response headers. + */ + public abstract void onError(IOException e, HttpURLConnection uc) throws IOException; + + /** + * Wait until the API abuse "wait time" is passed. + */ + public static final AbuseLimitHandler WAIT = new AbuseLimitHandler() { + @Override + public void onError(IOException e, HttpURLConnection uc) throws IOException { + try { + Thread.sleep(parseWaitTime(uc)); + } catch (InterruptedException _) { + throw (InterruptedIOException)new InterruptedIOException().initCause(e); + } + } + + private long parseWaitTime(HttpURLConnection uc) { + String v = uc.getHeaderField("Retry-After"); + if (v==null) return 60 * 1000; // can't tell, return 1 min + + return Math.max(1000, Long.parseLong(v)*1000); + } + }; + + /** + * Fail immediately. + */ + public static final AbuseLimitHandler FAIL = new AbuseLimitHandler() { + @Override + public void onError(IOException e, HttpURLConnection uc) throws IOException { + throw (IOException)new IOException("Abust limit reached").initCause(e); + } + }; +} diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 47388c93f..297596d87 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -83,7 +83,7 @@ public class GitHub { private final String apiUrl; /*package*/ final RateLimitHandler rateLimitHandler; - /*package*/ final RateLimitHandler abuseLimitHandler; + /*package*/ final AbuseLimitHandler abuseLimitHandler; private HttpConnector connector = HttpConnector.DEFAULT; @@ -123,7 +123,7 @@ public class GitHub { * @param connector * HttpConnector to use. Pass null to use default connector. */ - /* package */ GitHub(String apiUrl, String login, String oauthAccessToken, String password, HttpConnector connector, RateLimitHandler rateLimitHandler, RateLimitHandler abuseLimitHandler) throws IOException { + /* package */ GitHub(String apiUrl, String login, String oauthAccessToken, String password, HttpConnector connector, RateLimitHandler rateLimitHandler, AbuseLimitHandler abuseLimitHandler) throws IOException { if (apiUrl.endsWith("/")) apiUrl = apiUrl.substring(0, apiUrl.length()-1); // normalize this.apiUrl = apiUrl; if (null != connector) this.connector = connector; diff --git a/src/main/java/org/kohsuke/github/GitHubBuilder.java b/src/main/java/org/kohsuke/github/GitHubBuilder.java index 9ff603e19..62a99a627 100644 --- a/src/main/java/org/kohsuke/github/GitHubBuilder.java +++ b/src/main/java/org/kohsuke/github/GitHubBuilder.java @@ -30,7 +30,7 @@ public class GitHubBuilder { private HttpConnector connector; private RateLimitHandler rateLimitHandler = RateLimitHandler.WAIT; - private RateLimitHandler abuseLimitHandler = RateLimitHandler.ABUSE; + private AbuseLimitHandler abuseLimitHandler = AbuseLimitHandler.WAIT; public GitHubBuilder() { } @@ -179,6 +179,10 @@ public class GitHubBuilder { this.rateLimitHandler = handler; return this; } + public GitHubBuilder withAbuseLimitHandler(AbuseLimitHandler handler) { + this.abuseLimitHandler = handler; + return this; + } /** * Configures {@linkplain #withConnector(HttpConnector) connector} diff --git a/src/main/java/org/kohsuke/github/RateLimitHandler.java b/src/main/java/org/kohsuke/github/RateLimitHandler.java index 8ff47a5ab..053fd783e 100644 --- a/src/main/java/org/kohsuke/github/RateLimitHandler.java +++ b/src/main/java/org/kohsuke/github/RateLimitHandler.java @@ -9,6 +9,7 @@ import java.net.HttpURLConnection; * * @author Kohsuke Kawaguchi * @see GitHubBuilder#withRateLimitHandler(RateLimitHandler) + * @see AbuseLimitHandler */ public abstract class RateLimitHandler { /** @@ -48,27 +49,6 @@ public abstract class RateLimitHandler { return Math.max(10000, Long.parseLong(v)*1000 - System.currentTimeMillis()); } }; - - /** - * Wait until the API abuse "wait time" is passed. - */ - public static final RateLimitHandler ABUSE = new RateLimitHandler() { - @Override - public void onError(IOException e, HttpURLConnection uc) throws IOException { - try { - Thread.sleep(parseWaitTime(uc)); - } catch (InterruptedException _) { - throw (InterruptedIOException)new InterruptedIOException().initCause(e); - } - } - - private long parseWaitTime(HttpURLConnection uc) { - String v = uc.getHeaderField("Retry-After"); - if (v==null) return 60 * 1000; // can't tell, return 1 min - - return Math.max(1000, Long.parseLong(v)*1000); - } - }; /** * Fail immediately. diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index a0d5e2719..43c4e0769 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -572,10 +572,9 @@ class Requester { root.rateLimitHandler.onError(e,uc); return; } - - // Check to see whether we hit a 403, and the Retry-After field is - // available. - if (responseCode == HttpURLConnection.HTTP_FORBIDDEN && + + // Retry-After is not documented but apparently that field exists + if (responseCode == HttpURLConnection.HTTP_FORBIDDEN && uc.getHeaderField("Retry-After") != null) { this.root.abuseLimitHandler.onError(e,uc); return; From d82397a173cb0d576edc0bf02505dcefebac43ae Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:00:05 -0700 Subject: [PATCH 066/118] doc fix --- src/main/java/org/kohsuke/github/AbuseLimitHandler.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java b/src/main/java/org/kohsuke/github/AbuseLimitHandler.java index 1a158ee14..4cb6bfe6c 100644 --- a/src/main/java/org/kohsuke/github/AbuseLimitHandler.java +++ b/src/main/java/org/kohsuke/github/AbuseLimitHandler.java @@ -14,14 +14,14 @@ import java.net.HttpURLConnection; */ public abstract class AbuseLimitHandler { /** - * Called when the library encounters HTTP error indicating that the API rate limit is reached. + * Called when the library encounters HTTP error indicating that the API abuse limit is reached. * *

* Any exception thrown from this method will cause the request to fail, and the caller of github-api * will receive an exception. If this method returns normally, another request will be attempted. * For that to make sense, the implementation needs to wait for some time. * - * @see API documentation from GitHub + * @see API documentation from GitHub * @param e * Exception from Java I/O layer. If you decide to fail the processing, you can throw * this exception (or wrap this exception into another exception and throw it.) From bb1cecb95bf24577ccebaaf321022caab5605fa2 Mon Sep 17 00:00:00 2001 From: Duncan Dickinson Date: Fri, 5 Aug 2016 20:11:33 -0700 Subject: [PATCH 067/118] PR-284: license API support Had to do git-diff | git-apply to avoid whitespe changes to GHRepository --- .../java/org/kohsuke/github/GHLicense.java | 110 +++++++++ .../org/kohsuke/github/GHLicenseBase.java | 107 +++++++++ .../java/org/kohsuke/github/GHRepository.java | 48 ++++ src/main/java/org/kohsuke/github/GitHub.java | 28 +++ .../github/extras/PreviewHttpConnector.java | 67 ++++++ .../org/kohsuke/github/GHLicenseTest.java | 220 ++++++++++++++++++ 6 files changed, 580 insertions(+) create mode 100644 src/main/java/org/kohsuke/github/GHLicense.java create mode 100644 src/main/java/org/kohsuke/github/GHLicenseBase.java create mode 100644 src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java create mode 100644 src/test/java/org/kohsuke/github/GHLicenseTest.java diff --git a/src/main/java/org/kohsuke/github/GHLicense.java b/src/main/java/org/kohsuke/github/GHLicense.java new file mode 100644 index 000000000..baeb6c3d7 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHLicense.java @@ -0,0 +1,110 @@ +/* + * The MIT License + * + * Copyright (c) 2016, Duncan Dickinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.kohsuke.github; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +/** + * The GitHub Preview API's license information + *

+ * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * + * @author Duncan Dickinson + * @see GitHub#getLicense(String) + * @see GHRepository#getFullLicense() + * @see https://developer.github.com/v3/licenses/ + */ +@SuppressWarnings({"UnusedDeclaration"}) +@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", + "NP_UNWRITTEN_FIELD"}, justification = "JSON API") +public class GHLicense extends GHLicenseBase { + + protected String html_url, description, category, implementation, body; + + protected List required = new ArrayList(); + protected List permitted = new ArrayList(); + protected List forbidden = new ArrayList(); + + public URL getHtmlUrl() { + return GitHub.parseURL(html_url); + } + + public String getDescription() { + return description; + } + + public String getCategory() { + return category; + } + + public String getImplementation() { + return implementation; + } + + public List getRequired() { + return required; + } + + public List getPermitted() { + return permitted; + } + + public List getForbidden() { + return forbidden; + } + + public String getBody() { + return body; + } + + @Override + public String toString() { + return "GHLicense{" + + "html_url='" + html_url + '\'' + + ", description='" + description + '\'' + + ", category='" + category + '\'' + + ", implementation='" + implementation + '\'' + + ", body='" + body + '\'' + + ", required=" + required + + ", permitted=" + permitted + + ", forbidden=" + forbidden + + ", htmlUrl=" + getHtmlUrl() + + "} " + super.toString(); + } + + @Override + public boolean equals(Object o) { + return super.equals(o); + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/org/kohsuke/github/GHLicenseBase.java b/src/main/java/org/kohsuke/github/GHLicenseBase.java new file mode 100644 index 000000000..e6c92359d --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHLicenseBase.java @@ -0,0 +1,107 @@ +/* + * The MIT License + * + * Copyright (c) 2016, Duncan Dickinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.kohsuke.github; + +import com.infradna.tool.bridge_method_injector.WithBridgeMethods; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +import java.net.URL; + +/** + * The basic information for GitHub API licenses - as use in a number of + * API calls that only return the basic details + *

+ * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * + * @author Duncan Dickinson + * @see https://developer.github.com/v3/licenses/ + * @see GitHub#listLicenses() + * @see GHRepository#getLicense() + * @see GHLicense GHLicense subclass for the more comprehensive listing of properties + */ +@SuppressWarnings({"UnusedDeclaration"}) +@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", + "NP_UNWRITTEN_FIELD"}, justification = "JSON API") +public class GHLicenseBase { + + protected String key, name, url; + protected Boolean featured; + + /** + * @return a mnemonic for the license + */ + public String getKey() { + return key; + } + + /** + * @return the license name + */ + public String getName() { + return name; + } + + /** + * @return API URL of this object. + */ + @WithBridgeMethods(value = String.class, adapterMethod = "urlToString") + public URL getUrl() { + return GitHub.parseURL(url); + } + + /** + * Featured licenses are bold in the new repository drop-down + * + * @return True if the license is featured, false otherwise + */ + public Boolean isFeatured() { + return featured; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof GHLicenseBase)) return false; + + GHLicenseBase that = (GHLicenseBase) o; + + return getUrl().toString().equals(that.getUrl().toString()); + } + + @Override + public int hashCode() { + return getUrl().toString().hashCode(); + } + + @Override + public String toString() { + return "GHLicenseBase{" + + "key='" + key + '\'' + + ", name='" + name + '\'' + + ", url='" + url + '\'' + + ", featured=" + featured + + '}'; + } +} diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 41a44e9da..0b7424311 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -65,6 +65,16 @@ public class GHRepository extends GHObject { private String description, homepage, name, full_name; private String html_url; // this is the UI + /* + * The license information makes use of the preview API. + * + * See: https://developer.github.com/v3/licenses/ + */ + /** + * The basic license details as returned from {@link GitHub#getRepository(String)} + */ + private GHLicenseBase license; + private String git_url, ssh_url, clone_url, svn_url, mirror_url; private GHUser owner; // not fully populated. beware. private boolean has_issues, has_wiki, fork, has_downloads; @@ -839,6 +849,44 @@ public class GHRepository extends GHObject { } }; } + * Gets the basic license details for the repository. + *

+ * This is a preview item and requires you to use {@link org.kohsuke.github.extras.PreviewHttpConnector} + *

+ * Warning: Only returns the basic license details. Use {@link GitHub#getLicense(String)} + * to get the full license information (hint: pass it {@link GHLicenseBase#getKey()}). + * + * @throws IOException as usual but also if you don't use the preview connector + */ + public GHLicenseBase getLicense() { + return license; + } + + /** + * Access the full license details - makes an additional API call + *

+ * This is a preview item and requires you to use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * + * @return the license details + * @throws IOException as usual but also if you don't use the preview connector + */ + public GHLicense getFullLicense() throws IOException { + return root.getLicense(license.getKey()); + } + + /** + * Retrieves the contents of the repository's license file - makes an additional API call + *

+ * This is a preview item and requires you to use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * + * @return details regarding the license contents + * @throws IOException as usual but also if you don't use the preview connector + */ + public GHContent getLicenseContent() throws IOException { + return root.retrieve().to(getApiTailUrl("license"), GHContent.class).wrap(this); + } + + /** /** * Lists all the commit statues attached to the given commit, newer ones first. diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 297596d87..dd1e3593e 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -56,6 +56,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; + import java.util.logging.Logger; /** @@ -339,6 +340,33 @@ public class GitHub { String[] tokens = name.split("/"); return retrieve().to("/repos/" + tokens[0] + '/' + tokens[1], GHRepository.class).wrap(this); } + * Returns a list of popular open source licenses + * + * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * + * @see GitHub API - Licenses + * + * @return a list of popular open source licenses + * @throws IOException if the HttpConnector doesn't pass in the preview header or other IO issue + */ + public List listLicenses() throws IOException { + return Arrays.asList(retrieve().to("/licenses", GHLicenseBase[].class)); + } + + /** + * Returns the full details for a license + * + * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * + * @param key The license key provided from the API + * @return The license details + * @throws IOException + */ + public GHLicense getLicense(String key) throws IOException { + return retrieve().to("/licenses/" + key, GHLicense.class); + } + + /** /** * This method returns a shallowly populated organizations. diff --git a/src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java b/src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java new file mode 100644 index 000000000..e1be7855f --- /dev/null +++ b/src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java @@ -0,0 +1,67 @@ +/* + * Copyright $year slavinson + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.kohsuke.github.extras; + +import org.kohsuke.github.HttpConnector; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; + +public class PreviewHttpConnector implements HttpConnector { + private final HttpConnector base; + private final int readTimeout, connectTimeout; + + /** + * @param connectTimeout HTTP connection timeout in milliseconds + * @param readTimeout HTTP read timeout in milliseconds + */ + public PreviewHttpConnector(HttpConnector base, int connectTimeout, int readTimeout) { + this.base = base; + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; + } + + public PreviewHttpConnector(HttpConnector base, int timeout) { + this(base, timeout, timeout); + } + + public PreviewHttpConnector(HttpConnector base) { + this(base, ImpatientHttpConnector.CONNECT_TIMEOUT, ImpatientHttpConnector.READ_TIMEOUT); + } + + public PreviewHttpConnector() { + this(new HttpConnector() { + public HttpURLConnection connect(URL url) throws IOException { + return (HttpURLConnection) url.openConnection(); + } + }, ImpatientHttpConnector.CONNECT_TIMEOUT, ImpatientHttpConnector.READ_TIMEOUT); + } + + public HttpURLConnection connect(URL url) throws IOException { + HttpURLConnection con = base.connect(url); + con.setConnectTimeout(connectTimeout); + con.setReadTimeout(readTimeout); + con.addRequestProperty("Accept", PREVIEW_MEDIA_TYPE); + return con; + } + + /** + * Default connection timeout in milliseconds + */ + public static final String PREVIEW_MEDIA_TYPE = "application/vnd.github.drax-preview+json"; +} diff --git a/src/test/java/org/kohsuke/github/GHLicenseTest.java b/src/test/java/org/kohsuke/github/GHLicenseTest.java new file mode 100644 index 000000000..e27f8057c --- /dev/null +++ b/src/test/java/org/kohsuke/github/GHLicenseTest.java @@ -0,0 +1,220 @@ +/* + * The MIT License + * + * Copyright (c) 2016, Duncan Dickinson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.kohsuke.github; + +import org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.kohsuke.github.extras.PreviewHttpConnector; + +import java.io.IOException; +import java.net.URL; +import java.util.List; + +/** + * @author Duncan Dickinson + */ +public class GHLicenseTest extends Assert { + private GitHub gitHub; + + @Before + public void setUp() throws Exception { + gitHub = new GitHubBuilder() + .fromCredentials() + .withConnector(new PreviewHttpConnector()) + .build(); + } + + /** + * Basic test to ensure that the list of licenses from {@link GitHub#listLicenses()} is returned + * + * @throws IOException + */ + @Test + public void listLicenses() throws IOException { + List licenses = gitHub.listLicenses(); + assertTrue(licenses.size() > 0); + } + + /** + * Tests that {@link GitHub#listLicenses()} returns the MIT license + * in the expected manner. + * + * @throws IOException + */ + @Test + public void listLicensesCheckIndividualLicense() throws IOException { + List licenses = gitHub.listLicenses(); + for (GHLicenseBase lic : licenses) { + if (lic.getKey().equals("mit")) { + assertTrue(lic.getUrl().equals(new URL("https://api.github.com/licenses/mit"))); + return; + } + } + fail("The MIT license was not found"); + } + + /** + * Checks that the request for an individual license using {@link GitHub#getLicense(String)} + * returns expected values (not all properties are checked) + * + * @throws IOException + */ + @Test + public void getLicense() throws IOException { + String key = "mit"; + GHLicense license = gitHub.getLicense(key); + assertNotNull(license); + assertTrue("The name is correct", license.getName().equals("MIT License")); + assertTrue("The HTML URL is correct", license.getHtmlUrl().equals(new URL("http://choosealicense.com/licenses/mit/"))); + } + + /** + * Attempts to list the licenses with a non-preview connection + * + * @throws IOException is expected to be thrown + */ + @Test(expected = IOException.class) + public void ListLicensesWithoutPreviewConnection() throws IOException { + GitHub.connect().listLicenses(); + } + + /** + * Accesses the 'kohsuke/github-api' repo using {@link GitHub#getRepository(String)} + * and checks that the license is correct + * + * @throws IOException + */ + @Test + public void checkRepositoryLicense() throws IOException { + GHRepository repo = gitHub.getRepository("kohsuke/github-api"); + GHLicenseBase license = repo.getLicense(); + assertNotNull("The license is populated", license); + assertTrue("The key is correct", license.getKey().equals("mit")); + assertTrue("The name is correct", license.getName().equals("MIT License")); + assertTrue("The URL is correct", license.getUrl().equals(new URL("https://api.github.com/licenses/mit"))); + } + + /** + * Accesses the 'atom/atom' repo using {@link GitHub#getRepository(String)} + * and checks that the license is correct + * + * @throws IOException + */ + @Test + public void checkRepositoryLicenseAtom() throws IOException { + GHRepository repo = gitHub.getRepository("atom/atom"); + GHLicenseBase license = repo.getLicense(); + assertNotNull("The license is populated", license); + assertTrue("The key is correct", license.getKey().equals("mit")); + assertTrue("The name is correct", license.getName().equals("MIT License")); + assertTrue("The URL is correct", license.getUrl().equals(new URL("https://api.github.com/licenses/mit"))); + } + + /** + * Accesses the 'pomes/pomes' repo using {@link GitHub#getRepository(String)} + * and checks that the license is correct + * + * @throws IOException + */ + @Test + public void checkRepositoryLicensePomes() throws IOException { + GHRepository repo = gitHub.getRepository("pomes/pomes"); + GHLicenseBase license = repo.getLicense(); + assertNotNull("The license is populated", license); + assertTrue("The key is correct", license.getKey().equals("apache-2.0")); + assertTrue("The name is correct", license.getName().equals("Apache License 2.0")); + assertTrue("The URL is correct", license.getUrl().equals(new URL("https://api.github.com/licenses/apache-2.0"))); + } + + /** + * Accesses the 'dedickinson/test-repo' repo using {@link GitHub#getRepository(String)} + * and checks that *no* license is returned as the repo doesn't have one + * + * @throws IOException + */ + @Test + public void checkRepositoryWithoutLicense() throws IOException { + GHRepository repo = gitHub.getRepository("dedickinson/test-repo"); + GHLicenseBase license = repo.getLicense(); + assertNull("There is no license", license); + } + + /** + * Accesses the 'kohsuke/github-api' repo using {@link GitHub#getRepository(String)} + * and then calls {@link GHRepository#getFullLicense()} and checks that certain + * properties are correct + * + * @throws IOException + */ + @Test + public void checkRepositoryFullLicense() throws IOException { + GHRepository repo = gitHub.getRepository("kohsuke/github-api"); + GHLicense license = repo.getFullLicense(); + assertNotNull("The license is populated", license); + assertTrue("The key is correct", license.getKey().equals("mit")); + assertTrue("The name is correct", license.getName().equals("MIT License")); + assertTrue("The URL is correct", license.getUrl().equals(new URL("https://api.github.com/licenses/mit"))); + assertTrue("The HTML URL is correct", license.getHtmlUrl().equals(new URL("http://choosealicense.com/licenses/mit/"))); + } + + /** + * Accesses the 'pomes/pomes' repo using {@link GitHub#getRepository(String)} + * and then calls {@link GHRepository#getLicenseContent()} and checks that certain + * properties are correct + * + * @throws IOException + */ + @Test + public void checkRepositoryLicenseContent() throws IOException { + GHRepository repo = gitHub.getRepository("pomes/pomes"); + GHContent content = repo.getLicenseContent(); + assertNotNull("The license content is populated", content); + assertTrue("The type is 'file'", content.getType().equals("file")); + assertTrue("The license file is 'LICENSE'", content.getName().equals("LICENSE")); + + if (content.getEncoding().equals("base64")) { + String licenseText = new String(IOUtils.toByteArray(content.read())); + assertTrue("The license appears to be an Apache License", licenseText.contains("Apache License")); + } else { + fail("Expected the license to be Base64 encoded but instead it was " + content.getEncoding()); + } + } + + /** + * Accesses the 'kohsuke/github-api' repo using {@link GitHub#getRepository(String)} + * but without using {@link PreviewHttpConnector} and ensures that the {@link GHRepository#getLicense()} + * call just returns null rather than raising an exception. This should indicate that + * non-preview connection requests aren't affected by the change in functionality + * + * @throws IOException + */ + @Test + public void checkRepositoryLicenseWithoutPreviewConnection() throws IOException { + GHRepository repo = GitHub.connect().getRepository("kohsuke/github-api"); + assertNull(repo.getLicense()); + } +} From 1de02a509948d2d0dea8a38b135a4bc83709217d Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:19:36 -0700 Subject: [PATCH 068/118] Added a marker for preview APIs --- src/main/java/org/kohsuke/github/GHBranch.java | 3 +++ src/main/java/org/kohsuke/github/Preview.java | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/main/java/org/kohsuke/github/Preview.java diff --git a/src/main/java/org/kohsuke/github/GHBranch.java b/src/main/java/org/kohsuke/github/GHBranch.java index 1de47a156..f4e90f655 100644 --- a/src/main/java/org/kohsuke/github/GHBranch.java +++ b/src/main/java/org/kohsuke/github/GHBranch.java @@ -53,6 +53,7 @@ public class GHBranch { /** * Disables branch protection and allows anyone with push access to push changes. */ + @Preview @Deprecated public void disableProtection() throws IOException { BranchProtection bp = new BranchProtection(); bp.enabled = false; @@ -64,6 +65,7 @@ public class GHBranch { * * @see GHCommitStatus#getContext() */ + @Preview @Deprecated public void enableProtection(EnforcementLevel level, Collection contexts) throws IOException { BranchProtection bp = new BranchProtection(); bp.enabled = true; @@ -73,6 +75,7 @@ public class GHBranch { setProtection(bp); } + @Preview @Deprecated public void enableProtection(EnforcementLevel level, String... contexts) throws IOException { enableProtection(level, Arrays.asList(contexts)); } diff --git a/src/main/java/org/kohsuke/github/Preview.java b/src/main/java/org/kohsuke/github/Preview.java new file mode 100644 index 000000000..2eeed6045 --- /dev/null +++ b/src/main/java/org/kohsuke/github/Preview.java @@ -0,0 +1,18 @@ +package org.kohsuke.github; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Indicates that the method/class/etc marked maps to GitHub API in the preview period. + * + * These APIs are subject to change and not a part of the backward compatibility commitment. + * Always used in conjunction with 'deprecated' to raise awareness to clients. + * + * @author Kohsuke Kawaguchi + */ +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Preview { +} From 0cf4211aa54b74a489e49ca1b6c53b7c61c1b04b Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:36:46 -0700 Subject: [PATCH 069/118] Merged GHLicense & GHLicenseBase Elsewhere in this library, whenever there are multiple forms of the same object, we map that to the same class and use lazy data retrieval to fill missing fields. --- .../kohsuke/github/GHContentWithLicense.java | 19 ++++ .../java/org/kohsuke/github/GHLicense.java | 103 ++++++++++++----- .../org/kohsuke/github/GHLicenseBase.java | 107 ------------------ .../java/org/kohsuke/github/GHObject.java | 2 +- .../java/org/kohsuke/github/GHRepository.java | 27 ++--- src/main/java/org/kohsuke/github/GitHub.java | 12 +- .../org/kohsuke/github/GHLicenseTest.java | 18 +-- 7 files changed, 123 insertions(+), 165 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHContentWithLicense.java delete mode 100644 src/main/java/org/kohsuke/github/GHLicenseBase.java diff --git a/src/main/java/org/kohsuke/github/GHContentWithLicense.java b/src/main/java/org/kohsuke/github/GHContentWithLicense.java new file mode 100644 index 000000000..a7dfa843d --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHContentWithLicense.java @@ -0,0 +1,19 @@ +package org.kohsuke.github; + +/** + * {@link GHContent} with license information. + * + * @author Kohsuke Kawaguchi + * @see documentation + * @see GHRepository#getLicense() + */ +@Preview @Deprecated +class GHContentWithLicense extends GHContent { + GHLicense license; + + @Override + GHContentWithLicense wrap(GHRepository owner) { + super.wrap(owner); + return this; + } +} diff --git a/src/main/java/org/kohsuke/github/GHLicense.java b/src/main/java/org/kohsuke/github/GHLicense.java index baeb6c3d7..24ca8bbba 100644 --- a/src/main/java/org/kohsuke/github/GHLicense.java +++ b/src/main/java/org/kohsuke/github/GHLicense.java @@ -24,8 +24,10 @@ package org.kohsuke.github; +import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.List; @@ -33,17 +35,25 @@ import java.util.List; /** * The GitHub Preview API's license information *

- * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * WARNING: This uses a PREVIEW API - subject to change. * * @author Duncan Dickinson * @see GitHub#getLicense(String) - * @see GHRepository#getFullLicense() + * @see GHRepository#getLicense() * @see https://developer.github.com/v3/licenses/ */ +@Preview @Deprecated @SuppressWarnings({"UnusedDeclaration"}) @SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"}, justification = "JSON API") -public class GHLicense extends GHLicenseBase { +public class GHLicense extends GHObject { + /*package almost final*/ GitHub root; + + // these fields are always present, even in the short form + protected String key, name; + + // the rest is only after populated + protected Boolean featured; protected String html_url, description, category, implementation, body; @@ -51,60 +61,101 @@ public class GHLicense extends GHLicenseBase { protected List permitted = new ArrayList(); protected List forbidden = new ArrayList(); - public URL getHtmlUrl() { + /** + * @return a mnemonic for the license + */ + public String getKey() { + return key; + } + + /** + * @return the license name + */ + public String getName() { + return name; + } + + /** + * @return API URL of this object. + */ + @WithBridgeMethods(value = String.class, adapterMethod = "urlToString") + public URL getUrl() { + return GitHub.parseURL(url); + } + + /** + * Featured licenses are bold in the new repository drop-down + * + * @return True if the license is featured, false otherwise + */ + public Boolean isFeatured() throws IOException { + populate(); + return featured; + } + + public URL getHtmlUrl() throws IOException { + populate(); return GitHub.parseURL(html_url); } - public String getDescription() { + public String getDescription() throws IOException { + populate(); return description; } - public String getCategory() { + public String getCategory() throws IOException { + populate(); return category; } - public String getImplementation() { + public String getImplementation() throws IOException { + populate(); return implementation; } - public List getRequired() { + public List getRequired() throws IOException { + populate(); return required; } - public List getPermitted() { + public List getPermitted() throws IOException { + populate(); return permitted; } - public List getForbidden() { + public List getForbidden() throws IOException { + populate(); return forbidden; } - public String getBody() { + public String getBody() throws IOException { + populate(); return body; } - @Override - public String toString() { - return "GHLicense{" + - "html_url='" + html_url + '\'' + - ", description='" + description + '\'' + - ", category='" + category + '\'' + - ", implementation='" + implementation + '\'' + - ", body='" + body + '\'' + - ", required=" + required + - ", permitted=" + permitted + - ", forbidden=" + forbidden + - ", htmlUrl=" + getHtmlUrl() + - "} " + super.toString(); + /** + * Fully populate the data by retrieving missing data. + * + * Depending on the original API call where this object is created, it may not contain everything. + */ + protected synchronized void populate() throws IOException { + if (description!=null) return; // already populated + + root.retrieve().to(url, this); } @Override public boolean equals(Object o) { - return super.equals(o); + if (this == o) return true; + if (!(o instanceof GHLicense)) return false; + + GHLicense that = (GHLicense) o; + return this.url.equals(that.url); } @Override public int hashCode() { - return super.hashCode(); + return url.hashCode(); } + } diff --git a/src/main/java/org/kohsuke/github/GHLicenseBase.java b/src/main/java/org/kohsuke/github/GHLicenseBase.java deleted file mode 100644 index e6c92359d..000000000 --- a/src/main/java/org/kohsuke/github/GHLicenseBase.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2016, Duncan Dickinson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package org.kohsuke.github; - -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - -import java.net.URL; - -/** - * The basic information for GitHub API licenses - as use in a number of - * API calls that only return the basic details - *

- * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} - * - * @author Duncan Dickinson - * @see https://developer.github.com/v3/licenses/ - * @see GitHub#listLicenses() - * @see GHRepository#getLicense() - * @see GHLicense GHLicense subclass for the more comprehensive listing of properties - */ -@SuppressWarnings({"UnusedDeclaration"}) -@SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", - "NP_UNWRITTEN_FIELD"}, justification = "JSON API") -public class GHLicenseBase { - - protected String key, name, url; - protected Boolean featured; - - /** - * @return a mnemonic for the license - */ - public String getKey() { - return key; - } - - /** - * @return the license name - */ - public String getName() { - return name; - } - - /** - * @return API URL of this object. - */ - @WithBridgeMethods(value = String.class, adapterMethod = "urlToString") - public URL getUrl() { - return GitHub.parseURL(url); - } - - /** - * Featured licenses are bold in the new repository drop-down - * - * @return True if the license is featured, false otherwise - */ - public Boolean isFeatured() { - return featured; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof GHLicenseBase)) return false; - - GHLicenseBase that = (GHLicenseBase) o; - - return getUrl().toString().equals(that.getUrl().toString()); - } - - @Override - public int hashCode() { - return getUrl().toString().hashCode(); - } - - @Override - public String toString() { - return "GHLicenseBase{" + - "key='" + key + '\'' + - ", name='" + name + '\'' + - ", url='" + url + '\'' + - ", featured=" + featured + - '}'; - } -} diff --git a/src/main/java/org/kohsuke/github/GHObject.java b/src/main/java/org/kohsuke/github/GHObject.java index 323e72cd2..a81d913a5 100644 --- a/src/main/java/org/kohsuke/github/GHObject.java +++ b/src/main/java/org/kohsuke/github/GHObject.java @@ -51,7 +51,7 @@ public abstract class GHObject { * URL of this object for humans, which renders some HTML. */ @WithBridgeMethods(value=String.class, adapterMethod="urlToString") - public abstract URL getHtmlUrl(); + public abstract URL getHtmlUrl() throws IOException; /** * When was this resource last updated? diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 0b7424311..543060336 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -70,10 +70,7 @@ public class GHRepository extends GHObject { * * See: https://developer.github.com/v3/licenses/ */ - /** - * The basic license details as returned from {@link GitHub#getRepository(String)} - */ - private GHLicenseBase license; + private GHLicense license; private String git_url, ssh_url, clone_url, svn_url, mirror_url; private GHUser owner; // not fully populated. beware. @@ -849,6 +846,8 @@ public class GHRepository extends GHObject { } }; } + + /** * Gets the basic license details for the repository. *

* This is a preview item and requires you to use {@link org.kohsuke.github.extras.PreviewHttpConnector} @@ -858,20 +857,12 @@ public class GHRepository extends GHObject { * * @throws IOException as usual but also if you don't use the preview connector */ - public GHLicenseBase getLicense() { - return license; - } - - /** - * Access the full license details - makes an additional API call - *

- * This is a preview item and requires you to use {@link org.kohsuke.github.extras.PreviewHttpConnector} - * - * @return the license details - * @throws IOException as usual but also if you don't use the preview connector - */ - public GHLicense getFullLicense() throws IOException { - return root.getLicense(license.getKey()); + @Preview @Deprecated + public GHLicense getLicense() throws IOException{ + return root.retrieve() + .withHeader("Accept","application/vnd.github.drax-preview+json") + .to(getApiTailUrl("license"), GHContentWithLicense.class) + .wrap(this).license; } /** diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index dd1e3593e..a630e1f6d 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -340,28 +340,32 @@ public class GitHub { String[] tokens = name.split("/"); return retrieve().to("/repos/" + tokens[0] + '/' + tokens[1], GHRepository.class).wrap(this); } + /** * Returns a list of popular open source licenses * - * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * WARNING: This uses a PREVIEW API. * * @see GitHub API - Licenses * * @return a list of popular open source licenses * @throws IOException if the HttpConnector doesn't pass in the preview header or other IO issue */ - public List listLicenses() throws IOException { - return Arrays.asList(retrieve().to("/licenses", GHLicenseBase[].class)); + @Preview @Deprecated + public List listLicenses() throws IOException { + return Arrays.asList(retrieve().to("/licenses", GHLicense[].class)); } /** * Returns the full details for a license * - * WARNING: This uses a PREVIEW API - you must use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * WARNING: This uses a PREVIEW API. * * @param key The license key provided from the API * @return The license details * @throws IOException + * @see GHLicense#getKey() */ + @Preview @Deprecated public GHLicense getLicense(String key) throws IOException { return retrieve().to("/licenses/" + key, GHLicense.class); } diff --git a/src/test/java/org/kohsuke/github/GHLicenseTest.java b/src/test/java/org/kohsuke/github/GHLicenseTest.java index e27f8057c..43a97b5ed 100644 --- a/src/test/java/org/kohsuke/github/GHLicenseTest.java +++ b/src/test/java/org/kohsuke/github/GHLicenseTest.java @@ -55,7 +55,7 @@ public class GHLicenseTest extends Assert { */ @Test public void listLicenses() throws IOException { - List licenses = gitHub.listLicenses(); + List licenses = gitHub.listLicenses(); assertTrue(licenses.size() > 0); } @@ -67,8 +67,8 @@ public class GHLicenseTest extends Assert { */ @Test public void listLicensesCheckIndividualLicense() throws IOException { - List licenses = gitHub.listLicenses(); - for (GHLicenseBase lic : licenses) { + List licenses = gitHub.listLicenses(); + for (GHLicense lic : licenses) { if (lic.getKey().equals("mit")) { assertTrue(lic.getUrl().equals(new URL("https://api.github.com/licenses/mit"))); return; @@ -111,7 +111,7 @@ public class GHLicenseTest extends Assert { @Test public void checkRepositoryLicense() throws IOException { GHRepository repo = gitHub.getRepository("kohsuke/github-api"); - GHLicenseBase license = repo.getLicense(); + GHLicense license = repo.getLicense(); assertNotNull("The license is populated", license); assertTrue("The key is correct", license.getKey().equals("mit")); assertTrue("The name is correct", license.getName().equals("MIT License")); @@ -127,7 +127,7 @@ public class GHLicenseTest extends Assert { @Test public void checkRepositoryLicenseAtom() throws IOException { GHRepository repo = gitHub.getRepository("atom/atom"); - GHLicenseBase license = repo.getLicense(); + GHLicense license = repo.getLicense(); assertNotNull("The license is populated", license); assertTrue("The key is correct", license.getKey().equals("mit")); assertTrue("The name is correct", license.getName().equals("MIT License")); @@ -143,7 +143,7 @@ public class GHLicenseTest extends Assert { @Test public void checkRepositoryLicensePomes() throws IOException { GHRepository repo = gitHub.getRepository("pomes/pomes"); - GHLicenseBase license = repo.getLicense(); + GHLicense license = repo.getLicense(); assertNotNull("The license is populated", license); assertTrue("The key is correct", license.getKey().equals("apache-2.0")); assertTrue("The name is correct", license.getName().equals("Apache License 2.0")); @@ -159,13 +159,13 @@ public class GHLicenseTest extends Assert { @Test public void checkRepositoryWithoutLicense() throws IOException { GHRepository repo = gitHub.getRepository("dedickinson/test-repo"); - GHLicenseBase license = repo.getLicense(); + GHLicense license = repo.getLicense(); assertNull("There is no license", license); } /** * Accesses the 'kohsuke/github-api' repo using {@link GitHub#getRepository(String)} - * and then calls {@link GHRepository#getFullLicense()} and checks that certain + * and then calls {@link GHRepository#getLicense()} and checks that certain * properties are correct * * @throws IOException @@ -173,7 +173,7 @@ public class GHLicenseTest extends Assert { @Test public void checkRepositoryFullLicense() throws IOException { GHRepository repo = gitHub.getRepository("kohsuke/github-api"); - GHLicense license = repo.getFullLicense(); + GHLicense license = repo.getLicense(); assertNotNull("The license is populated", license); assertTrue("The key is correct", license.getKey().equals("mit")); assertTrue("The name is correct", license.getName().equals("MIT License")); From 80aa75aab1af674d8e1662ec074c0fbc026ce290 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:40:23 -0700 Subject: [PATCH 070/118] Added the wrap() method for a backpointer --- src/main/java/org/kohsuke/github/GHContentWithLicense.java | 2 ++ src/main/java/org/kohsuke/github/GHLicense.java | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHContentWithLicense.java b/src/main/java/org/kohsuke/github/GHContentWithLicense.java index a7dfa843d..bbd115e64 100644 --- a/src/main/java/org/kohsuke/github/GHContentWithLicense.java +++ b/src/main/java/org/kohsuke/github/GHContentWithLicense.java @@ -14,6 +14,8 @@ class GHContentWithLicense extends GHContent { @Override GHContentWithLicense wrap(GHRepository owner) { super.wrap(owner); + if (license!=null) + license.wrap(owner.root); return this; } } diff --git a/src/main/java/org/kohsuke/github/GHLicense.java b/src/main/java/org/kohsuke/github/GHLicense.java index 24ca8bbba..b4dec87d3 100644 --- a/src/main/java/org/kohsuke/github/GHLicense.java +++ b/src/main/java/org/kohsuke/github/GHLicense.java @@ -158,4 +158,8 @@ public class GHLicense extends GHObject { return url.hashCode(); } + /*package*/ GHLicense wrap(GitHub root) { + this.root = root; + return this; + } } From 07b527a0f297e4ae909ba7c324e7d9c09df53e48 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:40:34 -0700 Subject: [PATCH 071/118] Enumeration in GitHub should be PagedIterable --- src/main/java/org/kohsuke/github/GitHub.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index a630e1f6d..8466ae6d5 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -348,11 +348,20 @@ public class GitHub { * @see GitHub API - Licenses * * @return a list of popular open source licenses - * @throws IOException if the HttpConnector doesn't pass in the preview header or other IO issue */ @Preview @Deprecated - public List listLicenses() throws IOException { - return Arrays.asList(retrieve().to("/licenses", GHLicense[].class)); + public PagedIterable listLicenses() throws IOException { + return new PagedIterable() { + public PagedIterator _iterator(int pageSize) { + return new PagedIterator(retrieve().asIterator("/licenses", GHLicense[].class, pageSize)) { + @Override + protected void wrapUp(GHLicense[] page) { + for (GHLicense c : page) + c.wrap(GitHub.this); + } + }; + } + }; } /** From 70f0f5714a6bb1fa92ba6a52fa3692e87c02bea8 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:44:10 -0700 Subject: [PATCH 072/118] While a use of custom HttpConnector is clever, it doesn't fit the current idiom of this library. --- .../github/extras/PreviewHttpConnector.java | 67 ------------------- .../org/kohsuke/github/GHLicenseTest.java | 15 ----- 2 files changed, 82 deletions(-) delete mode 100644 src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java diff --git a/src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java b/src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java deleted file mode 100644 index e1be7855f..000000000 --- a/src/main/java/org/kohsuke/github/extras/PreviewHttpConnector.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright $year slavinson - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.kohsuke.github.extras; - -import org.kohsuke.github.HttpConnector; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.URL; - -public class PreviewHttpConnector implements HttpConnector { - private final HttpConnector base; - private final int readTimeout, connectTimeout; - - /** - * @param connectTimeout HTTP connection timeout in milliseconds - * @param readTimeout HTTP read timeout in milliseconds - */ - public PreviewHttpConnector(HttpConnector base, int connectTimeout, int readTimeout) { - this.base = base; - this.connectTimeout = connectTimeout; - this.readTimeout = readTimeout; - } - - public PreviewHttpConnector(HttpConnector base, int timeout) { - this(base, timeout, timeout); - } - - public PreviewHttpConnector(HttpConnector base) { - this(base, ImpatientHttpConnector.CONNECT_TIMEOUT, ImpatientHttpConnector.READ_TIMEOUT); - } - - public PreviewHttpConnector() { - this(new HttpConnector() { - public HttpURLConnection connect(URL url) throws IOException { - return (HttpURLConnection) url.openConnection(); - } - }, ImpatientHttpConnector.CONNECT_TIMEOUT, ImpatientHttpConnector.READ_TIMEOUT); - } - - public HttpURLConnection connect(URL url) throws IOException { - HttpURLConnection con = base.connect(url); - con.setConnectTimeout(connectTimeout); - con.setReadTimeout(readTimeout); - con.addRequestProperty("Accept", PREVIEW_MEDIA_TYPE); - return con; - } - - /** - * Default connection timeout in milliseconds - */ - public static final String PREVIEW_MEDIA_TYPE = "application/vnd.github.drax-preview+json"; -} diff --git a/src/test/java/org/kohsuke/github/GHLicenseTest.java b/src/test/java/org/kohsuke/github/GHLicenseTest.java index 43a97b5ed..5335e1a9d 100644 --- a/src/test/java/org/kohsuke/github/GHLicenseTest.java +++ b/src/test/java/org/kohsuke/github/GHLicenseTest.java @@ -44,7 +44,6 @@ public class GHLicenseTest extends Assert { public void setUp() throws Exception { gitHub = new GitHubBuilder() .fromCredentials() - .withConnector(new PreviewHttpConnector()) .build(); } @@ -203,18 +202,4 @@ public class GHLicenseTest extends Assert { fail("Expected the license to be Base64 encoded but instead it was " + content.getEncoding()); } } - - /** - * Accesses the 'kohsuke/github-api' repo using {@link GitHub#getRepository(String)} - * but without using {@link PreviewHttpConnector} and ensures that the {@link GHRepository#getLicense()} - * call just returns null rather than raising an exception. This should indicate that - * non-preview connection requests aren't affected by the change in functionality - * - * @throws IOException - */ - @Test - public void checkRepositoryLicenseWithoutPreviewConnection() throws IOException { - GHRepository repo = GitHub.connect().getRepository("kohsuke/github-api"); - assertNull(repo.getLicense()); - } } From 6a356c82a5129df674be98c2a73d5c1edf08b1bb Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:44:45 -0700 Subject: [PATCH 073/118] Fixed up tests --- src/main/java/org/kohsuke/github/GHRepository.java | 8 +++----- src/test/java/org/kohsuke/github/GHLicenseTest.java | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 543060336..2ee35b4f7 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -850,10 +850,7 @@ public class GHRepository extends GHObject { /** * Gets the basic license details for the repository. *

- * This is a preview item and requires you to use {@link org.kohsuke.github.extras.PreviewHttpConnector} - *

- * Warning: Only returns the basic license details. Use {@link GitHub#getLicense(String)} - * to get the full license information (hint: pass it {@link GHLicenseBase#getKey()}). + * This is a preview item and subject to change. * * @throws IOException as usual but also if you don't use the preview connector */ @@ -868,11 +865,12 @@ public class GHRepository extends GHObject { /** * Retrieves the contents of the repository's license file - makes an additional API call *

- * This is a preview item and requires you to use {@link org.kohsuke.github.extras.PreviewHttpConnector} + * This is a preview item and subject to change. * * @return details regarding the license contents * @throws IOException as usual but also if you don't use the preview connector */ + @Preview @Deprecated public GHContent getLicenseContent() throws IOException { return root.retrieve().to(getApiTailUrl("license"), GHContent.class).wrap(this); } diff --git a/src/test/java/org/kohsuke/github/GHLicenseTest.java b/src/test/java/org/kohsuke/github/GHLicenseTest.java index 5335e1a9d..d32325f11 100644 --- a/src/test/java/org/kohsuke/github/GHLicenseTest.java +++ b/src/test/java/org/kohsuke/github/GHLicenseTest.java @@ -28,11 +28,9 @@ import org.apache.commons.io.IOUtils; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.kohsuke.github.extras.PreviewHttpConnector; import java.io.IOException; import java.net.URL; -import java.util.List; /** * @author Duncan Dickinson @@ -54,8 +52,8 @@ public class GHLicenseTest extends Assert { */ @Test public void listLicenses() throws IOException { - List licenses = gitHub.listLicenses(); - assertTrue(licenses.size() > 0); + Iterable licenses = gitHub.listLicenses(); + assertTrue(licenses.iterator().hasNext()); } /** @@ -66,7 +64,7 @@ public class GHLicenseTest extends Assert { */ @Test public void listLicensesCheckIndividualLicense() throws IOException { - List licenses = gitHub.listLicenses(); + PagedIterable licenses = gitHub.listLicenses(); for (GHLicense lic : licenses) { if (lic.getKey().equals("mit")) { assertTrue(lic.getUrl().equals(new URL("https://api.github.com/licenses/mit"))); From 59324b008267ee9e3fdb3e5d7dc88a4c69bfd3e0 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:47:08 -0700 Subject: [PATCH 074/118] Add preview media type header explicitly --- src/main/java/org/kohsuke/github/GHLicense.java | 4 +++- src/main/java/org/kohsuke/github/GHRepository.java | 14 +++++++++----- src/main/java/org/kohsuke/github/GitHub.java | 8 ++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHLicense.java b/src/main/java/org/kohsuke/github/GHLicense.java index b4dec87d3..283a60edf 100644 --- a/src/main/java/org/kohsuke/github/GHLicense.java +++ b/src/main/java/org/kohsuke/github/GHLicense.java @@ -141,7 +141,9 @@ public class GHLicense extends GHObject { protected synchronized void populate() throws IOException { if (description!=null) return; // already populated - root.retrieve().to(url, this); + root.retrieve() + .withHeader("Accept","application/vnd.github.drax-preview+json") + .to(url, this); } @Override diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 2ee35b4f7..a4a739f89 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -856,10 +856,7 @@ public class GHRepository extends GHObject { */ @Preview @Deprecated public GHLicense getLicense() throws IOException{ - return root.retrieve() - .withHeader("Accept","application/vnd.github.drax-preview+json") - .to(getApiTailUrl("license"), GHContentWithLicense.class) - .wrap(this).license; + return getLicenseContent_().license; } /** @@ -872,7 +869,14 @@ public class GHRepository extends GHObject { */ @Preview @Deprecated public GHContent getLicenseContent() throws IOException { - return root.retrieve().to(getApiTailUrl("license"), GHContent.class).wrap(this); + return getLicenseContent_(); + } + + @Preview @Deprecated + private GHContentWithLicense getLicenseContent_() throws IOException { + return root.retrieve() + .withHeader("Accept","application/vnd.github.drax-preview+json") + .to(getApiTailUrl("license"), GHContentWithLicense.class).wrap(this); } /** diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 8466ae6d5..dff5f5914 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -353,7 +353,9 @@ public class GitHub { public PagedIterable listLicenses() throws IOException { return new PagedIterable() { public PagedIterator _iterator(int pageSize) { - return new PagedIterator(retrieve().asIterator("/licenses", GHLicense[].class, pageSize)) { + return new PagedIterator(retrieve() + .withHeader("Accept","application/vnd.github.drax-preview+json") + .asIterator("/licenses", GHLicense[].class, pageSize)) { @Override protected void wrapUp(GHLicense[] page) { for (GHLicense c : page) @@ -376,7 +378,9 @@ public class GitHub { */ @Preview @Deprecated public GHLicense getLicense(String key) throws IOException { - return retrieve().to("/licenses/" + key, GHLicense.class); + return retrieve() + .withHeader("Accept","application/vnd.github.drax-preview+json") + .to("/licenses/" + key, GHLicense.class); } /** From cabbbf7f0203c4f22f8e0fd1baad488b623d83c8 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:50:39 -0700 Subject: [PATCH 075/118] Handle 404 that represents "no license" --- .../java/org/kohsuke/github/GHRepository.java | 16 +++++++++++----- .../java/org/kohsuke/github/GHLicenseTest.java | 10 ---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index a4a739f89..04e2b8510 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -853,10 +853,12 @@ public class GHRepository extends GHObject { * This is a preview item and subject to change. * * @throws IOException as usual but also if you don't use the preview connector + * @return null if there's no license. */ @Preview @Deprecated public GHLicense getLicense() throws IOException{ - return getLicenseContent_().license; + GHContentWithLicense lic = getLicenseContent_(); + return lic!=null ? lic.license : null; } /** @@ -864,7 +866,7 @@ public class GHRepository extends GHObject { *

* This is a preview item and subject to change. * - * @return details regarding the license contents + * @return details regarding the license contents, or null if there's no license. * @throws IOException as usual but also if you don't use the preview connector */ @Preview @Deprecated @@ -874,9 +876,13 @@ public class GHRepository extends GHObject { @Preview @Deprecated private GHContentWithLicense getLicenseContent_() throws IOException { - return root.retrieve() - .withHeader("Accept","application/vnd.github.drax-preview+json") - .to(getApiTailUrl("license"), GHContentWithLicense.class).wrap(this); + try { + return root.retrieve() + .withHeader("Accept","application/vnd.github.drax-preview+json") + .to(getApiTailUrl("license"), GHContentWithLicense.class).wrap(this); + } catch (FileNotFoundException e) { + return null; + } } /** diff --git a/src/test/java/org/kohsuke/github/GHLicenseTest.java b/src/test/java/org/kohsuke/github/GHLicenseTest.java index d32325f11..b2cc73f92 100644 --- a/src/test/java/org/kohsuke/github/GHLicenseTest.java +++ b/src/test/java/org/kohsuke/github/GHLicenseTest.java @@ -89,16 +89,6 @@ public class GHLicenseTest extends Assert { assertTrue("The HTML URL is correct", license.getHtmlUrl().equals(new URL("http://choosealicense.com/licenses/mit/"))); } - /** - * Attempts to list the licenses with a non-preview connection - * - * @throws IOException is expected to be thrown - */ - @Test(expected = IOException.class) - public void ListLicensesWithoutPreviewConnection() throws IOException { - GitHub.connect().listLicenses(); - } - /** * Accesses the 'kohsuke/github-api' repo using {@link GitHub#getRepository(String)} * and checks that the license is correct From a9fb4546e19e453766a46256c43232ed2ea35e6a Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 20:56:11 -0700 Subject: [PATCH 076/118] Constants for preview media types --- src/main/java/org/kohsuke/github/GHBranch.java | 6 +++--- src/main/java/org/kohsuke/github/GHLicense.java | 6 +++--- src/main/java/org/kohsuke/github/GHRepository.java | 3 ++- src/main/java/org/kohsuke/github/GitHub.java | 9 +++------ src/main/java/org/kohsuke/github/Previews.java | 9 +++++++++ src/main/java/org/kohsuke/github/Requester.java | 4 ++++ 6 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/Previews.java diff --git a/src/main/java/org/kohsuke/github/GHBranch.java b/src/main/java/org/kohsuke/github/GHBranch.java index f4e90f655..4c80db9ef 100644 --- a/src/main/java/org/kohsuke/github/GHBranch.java +++ b/src/main/java/org/kohsuke/github/GHBranch.java @@ -7,6 +7,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.Collection; +import static org.kohsuke.github.Previews.LOKI; + /** * A branch in a repository. * @@ -81,9 +83,7 @@ public class GHBranch { } private void setProtection(BranchProtection bp) throws IOException { - new Requester(root).method("PATCH") - .withHeader("Accept","application/vnd.github.loki-preview+json") - ._with("protection",bp).to(getApiRoute()); + new Requester(root).method("PATCH").withPreview(LOKI)._with("protection",bp).to(getApiRoute()); } String getApiRoute() { diff --git a/src/main/java/org/kohsuke/github/GHLicense.java b/src/main/java/org/kohsuke/github/GHLicense.java index 283a60edf..47bec0f71 100644 --- a/src/main/java/org/kohsuke/github/GHLicense.java +++ b/src/main/java/org/kohsuke/github/GHLicense.java @@ -32,6 +32,8 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import static org.kohsuke.github.Previews.DRAX; + /** * The GitHub Preview API's license information *

@@ -141,9 +143,7 @@ public class GHLicense extends GHObject { protected synchronized void populate() throws IOException { if (description!=null) return; // already populated - root.retrieve() - .withHeader("Accept","application/vnd.github.drax-preview+json") - .to(url, this); + root.retrieve().withPreview(DRAX).to(url, this); } @Override diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 04e2b8510..472adf41e 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -51,6 +51,7 @@ import java.util.Set; import java.util.TreeMap; import static java.util.Arrays.asList; +import static org.kohsuke.github.Previews.DRAX; /** * A repository on GitHub. @@ -878,7 +879,7 @@ public class GHRepository extends GHObject { private GHContentWithLicense getLicenseContent_() throws IOException { try { return root.retrieve() - .withHeader("Accept","application/vnd.github.drax-preview+json") + .withPreview(DRAX) .to(getApiTailUrl("license"), GHContentWithLicense.class).wrap(this); } catch (FileNotFoundException e) { return null; diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index dff5f5914..e5bf16b1d 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -27,6 +27,7 @@ import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; import static java.util.logging.Level.FINE; import static java.net.HttpURLConnection.HTTP_UNAUTHORIZED; +import static org.kohsuke.github.Previews.DRAX; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; @@ -353,9 +354,7 @@ public class GitHub { public PagedIterable listLicenses() throws IOException { return new PagedIterable() { public PagedIterator _iterator(int pageSize) { - return new PagedIterator(retrieve() - .withHeader("Accept","application/vnd.github.drax-preview+json") - .asIterator("/licenses", GHLicense[].class, pageSize)) { + return new PagedIterator(retrieve().withPreview(DRAX).asIterator("/licenses", GHLicense[].class, pageSize)) { @Override protected void wrapUp(GHLicense[] page) { for (GHLicense c : page) @@ -378,9 +377,7 @@ public class GitHub { */ @Preview @Deprecated public GHLicense getLicense(String key) throws IOException { - return retrieve() - .withHeader("Accept","application/vnd.github.drax-preview+json") - .to("/licenses/" + key, GHLicense.class); + return retrieve().withPreview(DRAX).to("/licenses/" + key, GHLicense.class); } /** diff --git a/src/main/java/org/kohsuke/github/Previews.java b/src/main/java/org/kohsuke/github/Previews.java new file mode 100644 index 000000000..a5d061cbd --- /dev/null +++ b/src/main/java/org/kohsuke/github/Previews.java @@ -0,0 +1,9 @@ +package org.kohsuke.github; + +/** + * @author Kohsuke Kawaguchi + */ +/*package*/ class Previews { + static final String LOKI = "application/vnd.github.loki-preview+json"; + static final String DRAX = "application/vnd.github.drax-preview+json"; +} diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 43c4e0769..ac492579c 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -110,6 +110,10 @@ class Requester { return this; } + /*package*/ Requester withPreview(String name) { + return withHeader("Accept",name); + } + /** * Makes a request with authentication credential. */ From 63f500ad7fff182662f35e3588f1cee4b3e72e2d Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 21:11:00 -0700 Subject: [PATCH 077/118] Fixed issue #286 List commit API (https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository) already populates short info, and so populate() call could be excessive. It's possible that the short info is always available and therefore there's never a need to call populate(), but that assumption is hard to test, so I'm leaving that in --- src/main/java/org/kohsuke/github/GHCommit.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index 91510fc88..6e606ef60 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -179,7 +179,8 @@ public class GHCommit { public ShortInfo getCommitShortInfo() throws IOException { - populate(); + if (commit==null) + populate(); return commit; } From 4f15b7c9fac50bfc280f7fad2aa11467aab63ca5 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 21:19:32 -0700 Subject: [PATCH 078/118] NPE fix. type can be null --- src/main/java/org/kohsuke/github/Requester.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index ac492579c..6175191ea 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -516,7 +516,7 @@ class Requester { if (responseCode == 304) { return null; // special case handling for 304 unmodified, as the content will be "" } - if (responseCode == 204 && type.isArray()) { + if (responseCode == 204 && type!=null && type.isArray()) { // no content return type.cast(Array.newInstance(type.getComponentType(),0)); } From e2a1630cf4d555d9ecc3d07ec49f5315c2d24dc5 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 21:28:54 -0700 Subject: [PATCH 079/118] findbug taming --- src/main/java/org/kohsuke/github/GHLicense.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/kohsuke/github/GHLicense.java b/src/main/java/org/kohsuke/github/GHLicense.java index 47bec0f71..2c5c4299c 100644 --- a/src/main/java/org/kohsuke/github/GHLicense.java +++ b/src/main/java/org/kohsuke/github/GHLicense.java @@ -49,6 +49,7 @@ import static org.kohsuke.github.Previews.DRAX; @SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"}, justification = "JSON API") public class GHLicense extends GHObject { + @SuppressFBWarnings("IS2_INCONSISTENT_SYNC") // root is set before the object is returned to the app /*package almost final*/ GitHub root; // these fields are always present, even in the short form From e9368fb04eaaa58ecaa6c3863140647b0a3f6f4f Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 21:32:10 -0700 Subject: [PATCH 080/118] [maven-release-plugin] prepare release github-api-1.77 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index fa6bbacf9..3a637f222 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.77-SNAPSHOT + 1.77 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.77 From df963cb71cd0495a255ad1dda74358c3cfb5b7e5 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Fri, 5 Aug 2016 21:32:15 -0700 Subject: [PATCH 081/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3a637f222..e24d8f174 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.77 + 1.78-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.77 + HEAD From 38983df42dc43ba9b02917af1202ad87ef900e6e Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Mon, 19 Sep 2016 09:48:23 -0700 Subject: [PATCH 082/118] If we are a returning a collection of all things, we might as well use the maximum page size to minimize HTTP requests. --- src/main/java/org/kohsuke/github/GHOrganization.java | 2 +- src/main/java/org/kohsuke/github/GHPerson.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHOrganization.java b/src/main/java/org/kohsuke/github/GHOrganization.java index 0c62fd8a2..f174decf2 100644 --- a/src/main/java/org/kohsuke/github/GHOrganization.java +++ b/src/main/java/org/kohsuke/github/GHOrganization.java @@ -220,7 +220,7 @@ public class GHOrganization extends GHPerson { */ public List getRepositoriesWithOpenPullRequests() throws IOException { List r = new ArrayList(); - for (GHRepository repository : listRepositories()) { + for (GHRepository repository : listRepositories(100)) { repository.wrap(root); List pullRequests = repository.getPullRequests(GHIssueState.OPEN); if (pullRequests.size() > 0) { diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java index ef93dd75a..f8aae9a48 100644 --- a/src/main/java/org/kohsuke/github/GHPerson.java +++ b/src/main/java/org/kohsuke/github/GHPerson.java @@ -52,7 +52,7 @@ public abstract class GHPerson extends GHObject { */ public synchronized Map getRepositories() throws IOException { Map repositories = new TreeMap(); - for (GHRepository r : listRepositories()) { + for (GHRepository r : listRepositories(100)) { repositories.put(r.getName(),r); } return Collections.unmodifiableMap(repositories); From 5334cb8688aa627c3ada1186902ec9e5ff342f92 Mon Sep 17 00:00:00 2001 From: Ben Sheats Date: Fri, 21 Oct 2016 11:40:01 -0400 Subject: [PATCH 083/118] url encode hashes in ref names --- src/main/java/org/kohsuke/github/GHRepository.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 472adf41e..beba889f5 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -765,6 +765,8 @@ public class GHRepository extends GHObject { * invalid ref type being requested */ public GHRef getRef(String refName) throws IOException { + // hashes in branch names must be replaced with the url encoded equivalent or this call will fail + refName = refName.replaceAll("#", "%23"); return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refName), GHRef.class).wrap(root); } /** From 50b47fb73b538d4e7b80c9414c3410e727f0ace3 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Mon, 24 Oct 2016 21:12:56 +0100 Subject: [PATCH 084/118] Expose the commit dates --- .../java/org/kohsuke/github/GHCommit.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index 6e606ef60..587223356 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -2,12 +2,12 @@ package org.kohsuke.github; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; 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; /** @@ -42,11 +42,19 @@ public class GHCommit { return author; } + public Date getAuthoredDate() { + return GitHub.parseDate(author.date); + } + @WithBridgeMethods(value = GHAuthor.class, castRequired = true) public GitUser getCommitter() { return committer; } + public Date getCommitDate() { + return GitHub.parseDate(author.date); + } + /** * Commit message. */ @@ -63,6 +71,7 @@ public class GHCommit { * @deprecated Use {@link GitUser} instead. */ public static class GHAuthor extends GitUser { + private String date; } public static class Stats { @@ -272,10 +281,29 @@ public class GHCommit { return resolveUser(author); } + /** + * Gets the date the change was authored on. + * @return the date the change was authored on. + * @throws IOException if the information was not already fetched and an attempt at fetching the information failed. + */ + public Date getAuthoredDate() throws IOException { + return getCommitShortInfo().getAuthoredDate(); + } + public GHUser getCommitter() throws IOException { return resolveUser(committer); } + /** + * Gets the date the change was committed on. + * + * @return the date the change was committed on. + * @throws IOException if the information was not already fetched and an attempt at fetching the information failed. + */ + public Date getCommitDate() throws IOException { + return getCommitShortInfo().getCommitDate(); + } + private GHUser resolveUser(User author) throws IOException { if (author==null || author.login==null) return null; return owner.root.getUser(author.login); From b0df93bbcb5a27fa7268e2d778f708a66b100e69 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 24 Oct 2016 14:10:30 -0700 Subject: [PATCH 085/118] [maven-release-plugin] prepare release github-api-1.78 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e24d8f174..25340a1c2 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.78-SNAPSHOT + 1.78 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.78 From 0d92d4ba618e49cfceda589650f01b5f5a7ca202 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 24 Oct 2016 14:10:35 -0700 Subject: [PATCH 086/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 25340a1c2..1f673f276 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.78 + 1.79-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.78 + HEAD From 87fbb8ec987a68271adc0f43bd65593eeb91d2c1 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 24 Oct 2016 19:07:32 -0700 Subject: [PATCH 087/118] Copy/paste error --- src/main/java/org/kohsuke/github/GHCommit.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHCommit.java b/src/main/java/org/kohsuke/github/GHCommit.java index 587223356..374077848 100644 --- a/src/main/java/org/kohsuke/github/GHCommit.java +++ b/src/main/java/org/kohsuke/github/GHCommit.java @@ -52,7 +52,7 @@ public class GHCommit { } public Date getCommitDate() { - return GitHub.parseDate(author.date); + return GitHub.parseDate(committer.date); } /** From 4965fd5f4cdf90e1dc8ded82f214a3ddf2479c6d Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 24 Oct 2016 19:15:38 -0700 Subject: [PATCH 088/118] Noting possible TODO for the future --- src/main/java/org/kohsuke/github/GHRepository.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index beba889f5..2a16feb2f 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -766,6 +766,8 @@ public class GHRepository extends GHObject { */ public GHRef getRef(String refName) throws IOException { // hashes in branch names must be replaced with the url encoded equivalent or this call will fail + // FIXME: how about other URL unsafe characters, like space, @, : etc? do we need to be using URLEncoder.encode()? + // OTOH, '/' need no escaping refName = refName.replaceAll("#", "%23"); return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refName), GHRef.class).wrap(root); } From 5d5c6cf71cd12517d4d3aff92506dc8131ea4035 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 24 Oct 2016 19:23:14 -0700 Subject: [PATCH 089/118] [maven-release-plugin] prepare release github-api-1.79 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 1f673f276..9e3d54993 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.79-SNAPSHOT + 1.79 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.79 From fa3d0887efc52c36ca799923bad6c84601307843 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 24 Oct 2016 19:23:18 -0700 Subject: [PATCH 090/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9e3d54993..8d018c1a2 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.79 + 1.80-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.79 + HEAD From 955e9899af32d1eaac4ceb57465005eb03589ac5 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Fri, 4 Nov 2016 00:09:59 +0800 Subject: [PATCH 091/118] Fix fields of GHRepository --- .../java/org/kohsuke/github/GHRepository.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 2a16feb2f..f595bf632 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -75,10 +75,10 @@ public class GHRepository extends GHObject { private String git_url, ssh_url, clone_url, svn_url, mirror_url; private GHUser owner; // not fully populated. beware. - private boolean has_issues, has_wiki, fork, has_downloads; + private boolean has_issues, has_wiki, fork, has_downloads, has_pages; @JsonProperty("private") private boolean _private; - private int watchers,forks,open_issues,size,network_count,subscribers_count; + private int forks_count, stargazers_count, watchers_count, size, open_issues_count, subscribers_count; private String pushed_at; private Map milestones = new HashMap(); @@ -358,8 +358,12 @@ public class GHRepository extends GHObject { * Returns the number of all forks of this repository. * This not only counts direct forks, but also forks of forks, and so on. */ - public int getForks() { - return forks; + public int getForksCount() { + return forks_count; + } + + public int getStargazersCount() { + return stargazers_count; } public boolean isPrivate() { @@ -370,16 +374,16 @@ public class GHRepository extends GHObject { return has_downloads; } - public int getWatchers() { - return watchers; + public boolean hasPages() { + return has_pages; + } + + public int getWatchersCount() { + return watchers_count; } public int getOpenIssueCount() { - return open_issues; - } - - public int getNetworkCount() { - return network_count; + return open_issues_count; } public int getSubscribersCount() { From 4daf6ba0579a081cf189a8e68d7c194f63a28596 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Nov 2016 12:56:52 +0000 Subject: [PATCH 092/118] Add offline support to the API to make parsing events easier - When we receive events from a webhook, it is non-trivial to determine which GitHub instance the event came from or for that matter even if the event actually came from GitHub or GitHub Enterprise. - In order to ensure that the logic for parsing events does not get replicated in clients, we need to be able to call GitHub.parseEventPayload(Reader,Class) without knowing which GitHub the event originates from and without the resulting objects triggering API calls back to a GitHub - Thus we add GitHub.offline() to provide an off-line connection - Thus we modify some of the object classes to return best-effort objects when off-line - Add support for more of the event types into GHEventPayload - Add tests of the event payload and accessing critical fields when using GitHub.offline() --- .../org/kohsuke/github/GHCommitComment.java | 7 +- .../org/kohsuke/github/GHEventPayload.java | 373 +++++++++++++++ .../org/kohsuke/github/GHIssueComment.java | 4 +- .../java/org/kohsuke/github/GHPerson.java | 8 +- .../org/kohsuke/github/GHPullRequest.java | 4 +- .../java/org/kohsuke/github/GHRepository.java | 5 +- src/main/java/org/kohsuke/github/GitHub.java | 26 + .../org/kohsuke/github/HttpConnector.java | 9 + .../kohsuke/github/GHEventPayloadTest.java | 245 ++++++++++ .../java/org/kohsuke/github/GitHubTest.java | 14 + src/test/java/org/kohsuke/github/Payload.java | 12 + .../java/org/kohsuke/github/PayloadRule.java | 87 ++++ .../GHEventPayloadTest/commit_comment.json | 140 ++++++ .../github/GHEventPayloadTest/create.json | 113 +++++ .../github/GHEventPayloadTest/delete.json | 111 +++++ .../github/GHEventPayloadTest/deployment.json | 142 ++++++ .../GHEventPayloadTest/deployment_status.json | 172 +++++++ .../github/GHEventPayloadTest/fork.json | 196 ++++++++ .../github/GHEventPayloadTest/gollum.json | 118 +++++ .../GHEventPayloadTest/issue_comment.json | 182 +++++++ .../github/GHEventPayloadTest/issues.json | 156 ++++++ .../github/GHEventPayloadTest/label.json | 129 +++++ .../github/GHEventPayloadTest/member.json | 128 +++++ .../github/GHEventPayloadTest/membership.json | 61 +++ .../github/GHEventPayloadTest/milestone.json | 160 +++++++ .../github/GHEventPayloadTest/page_build.json | 139 ++++++ .../github/GHEventPayloadTest/public.json | 108 +++++ .../GHEventPayloadTest/pull_request.json | 412 ++++++++++++++++ .../pull_request_review.json | 440 +++++++++++++++++ .../pull_request_review_comment.json | 446 ++++++++++++++++++ .../github/GHEventPayloadTest/push.json | 174 +++++++ .../github/GHEventPayloadTest/release.json | 147 ++++++ .../github/GHEventPayloadTest/repository.json | 119 +++++ .../github/GHEventPayloadTest/status.json | 205 ++++++++ .../github/GHEventPayloadTest/team_add.json | 129 +++++ .../github/GHEventPayloadTest/watch.json | 109 +++++ 36 files changed, 5022 insertions(+), 8 deletions(-) create mode 100644 src/test/java/org/kohsuke/github/GHEventPayloadTest.java create mode 100644 src/test/java/org/kohsuke/github/Payload.java create mode 100644 src/test/java/org/kohsuke/github/PayloadRule.java create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/commit_comment.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/create.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/delete.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment_status.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/fork.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/gollum.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/issue_comment.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/issues.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/label.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/member.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/membership.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/milestone.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/page_build.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/public.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review_comment.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/release.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/repository.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/status.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/team_add.json create mode 100644 src/test/resources/org/kohsuke/github/GHEventPayloadTest/watch.json diff --git a/src/main/java/org/kohsuke/github/GHCommitComment.java b/src/main/java/org/kohsuke/github/GHCommitComment.java index 7020f9b98..64b658d2f 100644 --- a/src/main/java/org/kohsuke/github/GHCommitComment.java +++ b/src/main/java/org/kohsuke/github/GHCommitComment.java @@ -21,7 +21,7 @@ public class GHCommitComment extends GHObject { String body, html_url, commit_id; Integer line; String path; - User user; + GHUser user; // not fully populated. beware. static class User { // TODO: what if someone who doesn't have an account on GitHub makes a commit? @@ -76,7 +76,7 @@ public class GHCommitComment extends GHObject { * Gets the user who put this comment. */ public GHUser getUser() throws IOException { - return owner.root.getUser(user.login); + return owner == null || owner.root.isOffline() ? user : owner.root.getUser(user.login); } /** @@ -110,6 +110,9 @@ public class GHCommitComment extends GHObject { GHCommitComment wrap(GHRepository owner) { this.owner = owner; + if (owner.root.isOffline()) { + user.wrapUp(owner.root); + } return this; } } diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index 08b112880..7e5464648 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -1,5 +1,7 @@ package org.kohsuke.github; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.Reader; import java.util.List; @@ -14,11 +16,28 @@ import java.util.List; public abstract class GHEventPayload { protected GitHub root; + private GHUser sender; + /*package*/ GHEventPayload() { } + /** + * Gets the sender or {@code null} if accessed via the events API. + * @return the sender or {@code null} if accessed via the events API. + */ + public GHUser getSender() { + return sender; + } + + public void setSender(GHUser sender) { + this.sender = sender; + } + /*package*/ void wrapUp(GitHub root) { this.root = root; + if (sender != null) { + sender.wrapUp(root); + } } /** @@ -120,6 +139,290 @@ public abstract class GHEventPayload { } } + /** + * A comment was added to a commit + * + * @see authoritative source + */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" }, + justification = "Constructed by JSON deserialization") + public static class CommitComment extends GHEventPayload { + private String action; + private GHCommitComment comment; + private GHRepository repository; + + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization") + public String getAction() { + return action; + } + + public GHCommitComment getComment() { + return comment; + } + + public void setComment(GHCommitComment comment) { + this.comment = comment; + } + + public GHRepository getRepository() { + return repository; + } + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + if (repository != null) { + repository.wrap(root); + comment.wrap(repository); + } + } + } + + /** + * A repository, branch, or tag was created + * + * @see authoritative source + */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" }, + justification = "Constructed by JSON deserialization") + public static class Create extends GHEventPayload { + private String ref; + @JsonProperty("ref_type") + private String refType; + @JsonProperty("master_branch") + private String masterBranch; + private String description; + private GHRepository repository; + + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization") + public String getRef() { + return ref; + } + + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization") + public String getRefType() { + return refType; + } + + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization") + public String getMasterBranch() { + return masterBranch; + } + + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization") + public String getDescription() { + return description; + } + + public GHRepository getRepository() { + return repository; + } + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + if (repository != null) { + repository.wrap(root); + } + } + } + + /** + * A branch, or tag was deleted + * + * @see authoritative source + */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" }, + justification = "Constructed by JSON deserialization") + public static class Delete extends GHEventPayload { + private String ref; + @JsonProperty("ref_type") + private String refType; + private GHRepository repository; + + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization") + public String getRef() { + return ref; + } + + @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "Comes from JSON deserialization") + public String getRefType() { + return refType; + } + + public GHRepository getRepository() { + return repository; + } + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + if (repository != null) { + repository.wrap(root); + } + } + } + + /** + * A deployment + * + * @see authoritative source + */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" }, + justification = "Constructed by JSON deserialization") + public static class Deployment extends GHEventPayload { + private GHDeployment deployment; + private GHRepository repository; + + public GHDeployment getDeployment() { + return deployment; + } + + public void setDeployment(GHDeployment deployment) { + this.deployment = deployment; + } + + public GHRepository getRepository() { + return repository; + } + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + if (repository != null) { + repository.wrap(root); + deployment.wrap(repository); + } + } + } + + /** + * A deployment + * + * @see authoritative source + */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" }, + justification = "Constructed by JSON deserialization") + public static class DeploymentStatus extends GHEventPayload { + @JsonProperty("deployment_status") + private GHDeploymentStatus deploymentStatus; + private GHDeployment deployment; + private GHRepository repository; + + public GHDeploymentStatus getDeploymentStatus() { + return deploymentStatus; + } + + public void setDeploymentStatus(GHDeploymentStatus deploymentStatus) { + this.deploymentStatus = deploymentStatus; + } + + public GHDeployment getDeployment() { + return deployment; + } + + public void setDeployment(GHDeployment deployment) { + this.deployment = deployment; + } + + public GHRepository getRepository() { + return repository; + } + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + if (repository != null) { + repository.wrap(root); + deployment.wrap(repository); + deploymentStatus.wrap(repository); + } + } + } + + /** + * A user forked a repository + * + * @see authoritative source + */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD" }, + justification = "Constructed by JSON deserialization") + public static class Fork extends GHEventPayload { + private GHRepository forkee; + private GHRepository repository; + + + public GHRepository getForkee() { + return forkee; + } + + public void setForkee(GHRepository forkee) { + this.forkee = forkee; + } + + public GHRepository getRepository() { + return repository; + } + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + forkee.wrap(root); + if (repository != null) { + repository.wrap(root); + } + } + } + + /** + * A repository was made public. + * + * @see authoritative source + */ + public static class Public extends GHEventPayload { + private GHRepository repository; + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + public GHRepository getRepository() { + return repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + if (repository!=null) + repository.wrap(root); + } + + } + /** * A commit was pushed. * @@ -127,6 +430,7 @@ public abstract class GHEventPayload { */ public static class Push extends GHEventPayload { private String head, before; + private boolean created, deleted, forced; private String ref; private int size; private List commits; @@ -147,6 +451,11 @@ public abstract class GHEventPayload { return before; } + @JsonSetter // alias + private void setAfter(String after) { + head = after; + } + /** * The full Git ref that was pushed. Example: “refs/heads/master” */ @@ -185,13 +494,19 @@ public abstract class GHEventPayload { */ public static class PushCommit { private GitUser author; + private GitUser committer; private String url, sha, message; private boolean distinct; + private List added, removed, modified; public GitUser getAuthor() { return author; } + public GitUser getCommitter() { + return committer; + } + /** * Points to the commit API resource. */ @@ -203,6 +518,11 @@ public abstract class GHEventPayload { return sha; } + @JsonSetter + private void setId(String id) { + sha = id; + } + public String getMessage() { return message; } @@ -213,6 +533,59 @@ public abstract class GHEventPayload { public boolean isDistinct() { return distinct; } + + public List getAdded() { + return added; + } + + public List getRemoved() { + return removed; + } + + public List getModified() { + return modified; + } } } + + /** + * A repository was created, deleted, made public, or made private. + * + * @see authoritative source + */ + public static class Repository extends GHEventPayload { + private String action; + private GHRepository repository; + private GHOrganization organization; + + public String getAction() { + return action; + } + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + public GHRepository getRepository() { + return repository; + } + + public GHOrganization getOrganization() { + return organization; + } + + public void setOrganization(GHOrganization organization) { + this.organization = organization; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + repository.wrap(root); + if (organization != null) { + organization.wrapUp(root); + } + } + + } } diff --git a/src/main/java/org/kohsuke/github/GHIssueComment.java b/src/main/java/org/kohsuke/github/GHIssueComment.java index 3179fa93a..18d08bc7f 100644 --- a/src/main/java/org/kohsuke/github/GHIssueComment.java +++ b/src/main/java/org/kohsuke/github/GHIssueComment.java @@ -35,7 +35,7 @@ public class GHIssueComment extends GHObject { GHIssue owner; private String body, gravatar_id; - private GHUser user; + private GHUser user; // not fully populated. beware. /*package*/ GHIssueComment wrapUp(GHIssue owner) { this.owner = owner; @@ -68,7 +68,7 @@ public class GHIssueComment extends GHObject { * Gets the user who posted this comment. */ public GHUser getUser() throws IOException { - return owner.root.getUser(user.getLogin()); + return owner == null || owner.root.isOffline() ? user : owner.root.getUser(user.getLogin()); } /** diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java index f8aae9a48..67e157173 100644 --- a/src/main/java/org/kohsuke/github/GHPerson.java +++ b/src/main/java/org/kohsuke/github/GHPerson.java @@ -38,8 +38,12 @@ public abstract class GHPerson extends GHObject { * Depending on the original API call where this object is created, it may not contain everything. */ protected synchronized void populate() throws IOException { - if (created_at!=null) return; // already populated - + if (created_at!=null) { + return; // already populated + } + if (root.isOffline()) { + return; // cannot populate, will have to live with what we have + } root.retrieve().to(url, this); } diff --git a/src/main/java/org/kohsuke/github/GHPullRequest.java b/src/main/java/org/kohsuke/github/GHPullRequest.java index dd3d93b75..a6becf495 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequest.java +++ b/src/main/java/org/kohsuke/github/GHPullRequest.java @@ -201,7 +201,9 @@ public class GHPullRequest extends GHIssue { */ private void populate() throws IOException { if (merged_by!=null) return; // already populated - + if (root.isOffline()) { + return; // cannot populate, will have to live with what we have + } root.retrieve().to(url, this).wrapUp(owner); } diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index 2a16feb2f..a26d8e75a 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -232,7 +232,7 @@ public class GHRepository extends GHObject { } public GHUser getOwner() throws IOException { - return root.getUser(owner.login); // because 'owner' isn't fully populated + return root.isOffline() ? owner : root.getUser(owner.login); // because 'owner' isn't fully populated } public GHIssue getIssue(int id) throws IOException { @@ -1153,6 +1153,9 @@ public class GHRepository extends GHObject { /*package*/ GHRepository wrap(GitHub root) { this.root = root; + if (root.isOffline()) { + owner.wrapUp(root); + } return this; } diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index e5bf16b1d..04b3efefd 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -215,6 +215,24 @@ public class GitHub { return new GitHubBuilder().withEndpoint(apiUrl).build(); } + /** + * An off-line only {@link GitHub} useful for parsing event notification from an unknown source. + * + * All operations that require a connection will fail. + * + * @return An off-line only {@link GitHub}. + */ + public static GitHub offline() { + try { + return new GitHubBuilder() + .withEndpoint("https://api.github.invalid") + .withConnector(HttpConnector.OFFLINE) + .build(); + } catch (IOException e) { + throw new IllegalStateException("The offline implementation constructor should not connect", e); + } + } + /** * Is this an anonymous connection * @return {@code true} if operations that require authentication will fail. @@ -223,6 +241,14 @@ public class GitHub { return login==null && encodedAuthorization==null; } + /** + * Is this an always offline "connection". + * @return {@code true} if this is an always offline "connection". + */ + public boolean isOffline() { + return connector == HttpConnector.OFFLINE; + } + public HttpConnector getConnector() { return connector; } diff --git a/src/main/java/org/kohsuke/github/HttpConnector.java b/src/main/java/org/kohsuke/github/HttpConnector.java index 549626856..72f7ce5b0 100644 --- a/src/main/java/org/kohsuke/github/HttpConnector.java +++ b/src/main/java/org/kohsuke/github/HttpConnector.java @@ -29,4 +29,13 @@ public interface HttpConnector { return (HttpURLConnection) url.openConnection(); } }); + + /** + * Stub implementation that is always off-line. + */ + HttpConnector OFFLINE = new HttpConnector() { + public HttpURLConnection connect(URL url) throws IOException { + throw new IOException("Offline"); + } + }; } diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java new file mode 100644 index 000000000..f414b6e7b --- /dev/null +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -0,0 +1,245 @@ +package org.kohsuke.github; + +import org.junit.Rule; +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.junit.Assert.assertThat; + +public class GHEventPayloadTest { + + @Rule + public final PayloadRule payload = new PayloadRule(".json"); + + @Test + public void commit_comment() throws Exception { + GHEventPayload.CommitComment event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.CommitComment.class); + assertThat(event.getAction(), is("created")); + assertThat(event.getComment().getSHA1(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b")); + assertThat(event.getComment().getUser().getLogin(), is("baxterthehacker")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + + @Test + public void create() throws Exception { + GHEventPayload.Create event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Create.class); + assertThat(event.getRef(), is("0.0.1")); + assertThat(event.getRefType(), is("tag")); + assertThat(event.getMasterBranch(), is("master")); + assertThat(event.getDescription(), is("")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + + @Test + public void delete() throws Exception { + GHEventPayload.Delete event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Delete.class); + assertThat(event.getRef(), is("simple-tag")); + assertThat(event.getRefType(), is("tag")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + + @Test + public void deployment() throws Exception { + GHEventPayload.Deployment event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Deployment.class); + assertThat(event.getDeployment().getSha(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b")); + assertThat(event.getDeployment().getEnvironment(), is("production")); + assertThat(event.getDeployment().getCreator().getLogin(), is("baxterthehacker")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + + @Test + public void deployment_status() throws Exception { + GHEventPayload.DeploymentStatus event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.DeploymentStatus.class); + assertThat(event.getDeploymentStatus().getState(), is(GHDeploymentState.SUCCESS)); + assertThat(event.getDeploymentStatus().getTargetUrl(), nullValue()); + assertThat(event.getDeployment().getSha(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b")); + assertThat(event.getDeployment().getEnvironment(), is("production")); + assertThat(event.getDeployment().getCreator().getLogin(), is("baxterthehacker")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + + @Test + public void fork() throws Exception { + GHEventPayload.Fork event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Fork.class); + assertThat(event.getForkee().getName(), is("public-repo")); + assertThat(event.getForkee().getOwner().getLogin(), is("baxterandthehackers")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterandthehackers")); + } + +// TODO uncomment when we have GHPage implemented +// @Test +// public void gollum() throws Exception { +// GHEventPayload.Gollum event = +// GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Gollum.class); +// assertThat(event.getPages().size(), is(1)); +// GHPage page = event.getPages().get(0); +// assertThat(page.getName(), is("Home")); +// assertThat(page.getTitle(), is("Home")); +// assertThat(page.getSummary(), nullValue()); +// assertThat(page.getAction(), is("created")); +// assertThat(page.getSha(), is("91ea1bd42aa2ba166b86e8aefe049e9837214e67")); +// assertThat(page.getHtmlUrl(), is("https://github.com/baxterthehacker/public-repo/wiki/Home")); +// assertThat(event.getRepository().getName(), is("public-repo")); +// assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); +// assertThat(event.getSender().getLogin(), is("baxterthehacker")); +// } + + @Test + public void issue_comment() throws Exception { + GHEventPayload.IssueComment event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.IssueComment.class); + assertThat(event.getAction(), is("created")); + assertThat(event.getIssue().getNumber(), is(2)); + assertThat(event.getIssue().getTitle(), is("Spelling error in the README file")); + assertThat(event.getIssue().getState(), is(GHIssueState.OPEN)); + assertThat(event.getIssue().getLabels().size(), is(1)); + assertThat(event.getIssue().getLabels().iterator().next().getName(), is("bug")); + assertThat(event.getComment().getUser().getLogin(), is("baxterthehacker")); + assertThat(event.getComment().getBody(), is("You are totally right! I'll get this fixed right away.")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + +// TODO implement support classes and write test +// @Test +// public void issues() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void label() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void member() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void membership() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void milestone() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void page_build() throws Exception {} + + @Test + @Payload("public") + public void public_() throws Exception { + GHEventPayload.Public event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Public.class); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + + @Test + public void pull_request() throws Exception { + GHEventPayload.PullRequest event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.PullRequest.class); + assertThat(event.getAction(), is("opened")); + assertThat(event.getNumber(), is(1)); + assertThat(event.getPullRequest().getNumber(), is(1)); + assertThat(event.getPullRequest().getTitle(), is("Update the README with new information")); + assertThat(event.getPullRequest().getBody(), is("This is a pretty simple change that we need to pull into " + + "master.")); + assertThat(event.getPullRequest().getUser().getLogin(), is("baxterthehacker")); + assertThat(event.getPullRequest().getHead().getUser().getLogin(), is("baxterthehacker")); + assertThat(event.getPullRequest().getHead().getRef(), is("changes")); + assertThat(event.getPullRequest().getHead().getLabel(), is("baxterthehacker:changes")); + assertThat(event.getPullRequest().getHead().getSha(), is("0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c")); + assertThat(event.getPullRequest().getBase().getUser().getLogin(), is("baxterthehacker")); + assertThat(event.getPullRequest().getBase().getRef(), is("master")); + assertThat(event.getPullRequest().getBase().getLabel(), is("baxterthehacker:master")); + assertThat(event.getPullRequest().getBase().getSha(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b")); + assertThat(event.getPullRequest().isMerged(), is(false)); + assertThat(event.getPullRequest().getMergeable(), nullValue()); + assertThat(event.getPullRequest().getMergeableState(), is("unknown")); + assertThat(event.getPullRequest().getMergedBy(), nullValue()); + assertThat(event.getPullRequest().getCommentsCount(), is(0)); + assertThat(event.getPullRequest().getReviewComments(), is(0)); + assertThat(event.getPullRequest().getAdditions(), is(1)); + assertThat(event.getPullRequest().getDeletions(), is(1)); + assertThat(event.getPullRequest().getChangedFiles(), is(1)); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + +// TODO implement support classes and write test +// @Test +// public void pull_request_review() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void pull_request_review_comment() throws Exception {} + + @Test + public void push() throws Exception { + GHEventPayload.Push event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Push.class); + assertThat(event.getRef(), is("refs/heads/changes")); + assertThat(event.getBefore(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b")); + assertThat(event.getHead(), is("0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c")); + assertThat(event.getCommits().size(), is(1)); + assertThat(event.getCommits().get(0).getSha(), is("0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c")); + assertThat(event.getCommits().get(0).getAuthor().getEmail(), is("baxterthehacker@users.noreply.github.com")); + assertThat(event.getCommits().get(0).getCommitter().getEmail(), is("baxterthehacker@users.noreply.github.com")); + assertThat(event.getCommits().get(0).getAdded().size(), is(0)); + assertThat(event.getCommits().get(0).getRemoved().size(), is(0)); + assertThat(event.getCommits().get(0).getModified().size(), is(1)); + assertThat(event.getCommits().get(0).getModified().get(0), is("README.md")); + assertThat(event.getRepository().getName(), is("public-repo")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + +// TODO implement support classes and write test +// @Test +// public void release() throws Exception {} + + @Test + public void repository() throws Exception { + GHEventPayload.Repository event = + GitHub.offline().parseEventPayload(payload.asReader(), GHEventPayload.Repository.class); + assertThat(event.getAction(), is("created")); + assertThat(event.getRepository().getName(), is("new-repository")); + assertThat(event.getRepository().getOwner().getLogin(), is("baxterandthehackers")); + assertThat(event.getOrganization().getLogin(), is("baxterandthehackers")); + assertThat(event.getSender().getLogin(), is("baxterthehacker")); + } + +// TODO implement support classes and write test +// @Test +// public void status() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void team_add() throws Exception {} + +// TODO implement support classes and write test +// @Test +// public void watch() throws Exception {} + +} diff --git a/src/test/java/org/kohsuke/github/GitHubTest.java b/src/test/java/org/kohsuke/github/GitHubTest.java index b8ae4ff0d..fe6faefac 100644 --- a/src/test/java/org/kohsuke/github/GitHubTest.java +++ b/src/test/java/org/kohsuke/github/GitHubTest.java @@ -13,6 +13,7 @@ import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -20,6 +21,19 @@ import static org.mockito.Mockito.when; * Unit test for {@link GitHub}. */ public class GitHubTest { + @Test + public void testOffline() throws Exception { + GitHub hub = GitHub.offline(); + assertEquals("https://api.github.invalid/test", hub.getApiURL("/test").toString()); + assertTrue(hub.isAnonymous()); + try { + hub.getRateLimit(); + fail("Offline instance should always fail"); + } catch (IOException e) { + assertEquals("Offline", e.getMessage()); + } + } + @Test public void testGitHubServerWithHttp() throws Exception { GitHub hub = GitHub.connectToEnterprise("http://enterprise.kohsuke.org/api/v3", "bogus","bogus"); diff --git a/src/test/java/org/kohsuke/github/Payload.java b/src/test/java/org/kohsuke/github/Payload.java new file mode 100644 index 000000000..7365468d2 --- /dev/null +++ b/src/test/java/org/kohsuke/github/Payload.java @@ -0,0 +1,12 @@ +package org.kohsuke.github; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Payload { + String value(); +} diff --git a/src/test/java/org/kohsuke/github/PayloadRule.java b/src/test/java/org/kohsuke/github/PayloadRule.java new file mode 100644 index 000000000..7f9364fdb --- /dev/null +++ b/src/test/java/org/kohsuke/github/PayloadRule.java @@ -0,0 +1,87 @@ +package org.kohsuke.github; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import org.apache.commons.io.IOUtils; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +/** + * @author Stephen Connolly + */ +public class PayloadRule implements TestRule { + + private final String type; + + private Class testClass; + + private String resourceName; + + public PayloadRule(String type) { + this.type = type; + } + + public Statement apply(final Statement base, final Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + Payload payload = description.getAnnotation(Payload.class); + resourceName = payload == null ? description.getMethodName() : payload.value(); + testClass = description.getTestClass(); + try { + base.evaluate(); + } finally { + resourceName = null; + } + } + }; + } + + public InputStream asInputStream() throws FileNotFoundException { + String name = resourceName.startsWith("/") + ? resourceName + type + : testClass.getSimpleName() + "/" + resourceName + type; + InputStream stream = testClass.getResourceAsStream(name); + if (stream == null) { + throw new FileNotFoundException(String.format("Resource %s from class %s", name, testClass)); + } + return stream; + } + + public byte[] asBytes() throws IOException { + InputStream input = asInputStream(); + try { + return IOUtils.toByteArray(input); + } finally { + IOUtils.closeQuietly(input); + } + } + + public String asString(Charset encoding) throws IOException { + return new String(asBytes(), encoding.name()); + } + + public String asString(String encoding) throws IOException { + return new String(asBytes(), encoding); + } + + public String asString() throws IOException { + return new String(asBytes(), Charset.defaultCharset().name()); + } + + public Reader asReader() throws FileNotFoundException { + return new InputStreamReader(asInputStream(), Charset.defaultCharset()); + } + + public Reader asReader(String encoding) throws IOException { + return new InputStreamReader(asInputStream(), encoding); + } + public Reader asReader(Charset encoding) throws FileNotFoundException { + return new InputStreamReader(asInputStream(), encoding); + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/commit_comment.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/commit_comment.json new file mode 100644 index 000000000..bcf70894c --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/commit_comment.json @@ -0,0 +1,140 @@ +{ + "action": "created", + "comment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/comments/11056394", + "html_url": "https://github.com/baxterthehacker/public-repo/commit/9049f1265b7d61be4a8904a9a27120d2064dab3b#commitcomment-11056394", + "id": 11056394, + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "position": null, + "line": null, + "path": null, + "commit_id": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "created_at": "2015-05-05T23:40:29Z", + "updated_at": "2015-05-05T23:40:29Z", + "body": "This is a really good change! :+1:" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/create.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/create.json new file mode 100644 index 000000000..51d690c37 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/create.json @@ -0,0 +1,113 @@ +{ + "ref": "0.0.1", + "ref_type": "tag", + "master_branch": "master", + "description": "", + "pusher_type": "user", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/delete.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/delete.json new file mode 100644 index 000000000..0759bcd04 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/delete.json @@ -0,0 +1,111 @@ +{ + "ref": "simple-tag", + "ref_type": "tag", + "pusher_type": "user", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:40Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment.json new file mode 100644 index 000000000..9f2ca9668 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment.json @@ -0,0 +1,142 @@ +{ + "deployment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692", + "id": 710692, + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "ref": "master", + "task": "deploy", + "payload": { + }, + "environment": "production", + "description": null, + "creator": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2015-05-05T23:40:38Z", + "updated_at": "2015-05-05T23:40:38Z", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692/statuses", + "repository_url": "https://api.github.com/repos/baxterthehacker/public-repo" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment_status.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment_status.json new file mode 100644 index 000000000..e1dcd0706 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/deployment_status.json @@ -0,0 +1,172 @@ +{ + "deployment_status": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692/statuses/1115122", + "id": 1115122, + "state": "success", + "creator": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "description": null, + "target_url": null, + "created_at": "2015-05-05T23:40:39Z", + "updated_at": "2015-05-05T23:40:39Z", + "deployment_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692", + "repository_url": "https://api.github.com/repos/baxterthehacker/public-repo" + }, + "deployment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692", + "id": 710692, + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "ref": "master", + "task": "deploy", + "payload": { + }, + "environment": "production", + "description": null, + "creator": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2015-05-05T23:40:38Z", + "updated_at": "2015-05-05T23:40:38Z", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments/710692/statuses", + "repository_url": "https://api.github.com/repos/baxterthehacker/public-repo" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/fork.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/fork.json new file mode 100644 index 000000000..e01d3c50f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/fork.json @@ -0,0 +1,196 @@ +{ + "forkee": { + "id": 35129393, + "name": "public-repo", + "full_name": "baxterandthehackers/public-repo", + "owner": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterandthehackers/public-repo", + "description": "", + "fork": true, + "url": "https://api.github.com/repos/baxterandthehackers/public-repo", + "forks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:30Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterandthehackers/public-repo.git", + "ssh_url": "git@github.com:baxterandthehackers/public-repo.git", + "clone_url": "https://github.com/baxterandthehackers/public-repo.git", + "svn_url": "https://github.com/baxterandthehackers/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": false, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master", + "public": true + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 1, + "mirror_url": null, + "open_issues_count": 2, + "forks": 1, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/gollum.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/gollum.json new file mode 100644 index 000000000..79527b91c --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/gollum.json @@ -0,0 +1,118 @@ +{ + "pages": [ + { + "page_name": "Home", + "title": "Home", + "summary": null, + "action": "created", + "sha": "91ea1bd42aa2ba166b86e8aefe049e9837214e67", + "html_url": "https://github.com/baxterthehacker/public-repo/wiki/Home" + } + ], + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:17Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "jasonrudolph", + "id": 2988, + "avatar_url": "https://avatars.githubusercontent.com/u/2988?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/jasonrudolph", + "html_url": "https://github.com/jasonrudolph", + "followers_url": "https://api.github.com/users/jasonrudolph/followers", + "following_url": "https://api.github.com/users/jasonrudolph/following{/other_user}", + "gists_url": "https://api.github.com/users/jasonrudolph/gists{/gist_id}", + "starred_url": "https://api.github.com/users/jasonrudolph/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/jasonrudolph/subscriptions", + "organizations_url": "https://api.github.com/users/jasonrudolph/orgs", + "repos_url": "https://api.github.com/users/jasonrudolph/repos", + "events_url": "https://api.github.com/users/jasonrudolph/events{/privacy}", + "received_events_url": "https://api.github.com/users/jasonrudolph/received_events", + "type": "User", + "site_admin": true + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/issue_comment.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/issue_comment.json new file mode 100644 index 000000000..6f6e7d897 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/issue_comment.json @@ -0,0 +1,182 @@ +{ + "action": "created", + "issue": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/labels{/name}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/comments", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/events", + "html_url": "https://github.com/baxterthehacker/public-repo/issues/2", + "id": 73464126, + "number": 2, + "title": "Spelling error in the README file", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/labels/bug", + "name": "bug", + "color": "fc2929" + } + ], + "state": "open", + "locked": false, + "assignee": null, + "milestone": null, + "comments": 1, + "created_at": "2015-05-05T23:40:28Z", + "updated_at": "2015-05-05T23:40:28Z", + "closed_at": null, + "body": "It looks like you accidently spelled 'commit' with two 't's." + }, + "comment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments/99262140", + "html_url": "https://github.com/baxterthehacker/public-repo/issues/2#issuecomment-99262140", + "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2", + "id": 99262140, + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "created_at": "2015-05-05T23:40:28Z", + "updated_at": "2015-05-05T23:40:28Z", + "body": "You are totally right! I'll get this fixed right away." + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/issues.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/issues.json new file mode 100644 index 000000000..5e0c52b0c --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/issues.json @@ -0,0 +1,156 @@ +{ + "action": "opened", + "issue": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/labels{/name}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/comments", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/2/events", + "html_url": "https://github.com/baxterthehacker/public-repo/issues/2", + "id": 73464126, + "number": 2, + "title": "Spelling error in the README file", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "labels": [ + { + "id": 208045946, + "url": "https://api.github.com/repos/baxterthehacker/public-repo/labels/bug", + "name": "bug", + "color": "fc2929", + "default": true + } + ], + "state": "open", + "locked": false, + "assignee": null, + "milestone": null, + "comments": 0, + "created_at": "2015-05-05T23:40:28Z", + "updated_at": "2015-05-05T23:40:28Z", + "closed_at": null, + "body": "It looks like you accidently spelled 'commit' with two 't's." + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/label.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/label.json new file mode 100644 index 000000000..f85f636f8 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/label.json @@ -0,0 +1,129 @@ +{ + "action": "created", + "label": { + "url": "https://api.github.com/repos/baxterandthehackers/public-repo/labels/blocked", + "name": "blocked", + "color": "ff0000" + }, + "repository": { + "id": 67075329, + "name": "public-repo", + "full_name": "baxterandthehackers/public-repo", + "owner": { + "login": "baxterandthehackers", + "id": 4312013, + "avatar_url": "https://avatars.githubusercontent.com/u/4312013?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": true, + "html_url": "https://github.com/baxterandthehackers/public-repo", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/baxterandthehackers/public-repo", + "forks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/public-repo/notifications{?since,all, + participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/public-repo/releases{/id}", + "deployments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/deployments", + "created_at": "2016-08-31T21:38:51Z", + "updated_at": "2016-08-31T21:38:51Z", + "pushed_at": "2016-08-31T21:38:51Z", + "git_url": "git://github.com/baxterandthehackers/public-repo.git", + "ssh_url": "git@github.com:baxterandthehackers/public-repo.git", + "clone_url": "https://github.com/baxterandthehackers/public-repo.git", + "svn_url": "https://github.com/baxterandthehackers/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "organization": { + "login": "baxterandthehackers", + "id": 4312013, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "hooks_url": "https://api.github.com/orgs/baxterandthehackers/hooks", + "issues_url": "https://api.github.com/orgs/baxterandthehackers/issues", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/4312013?v=3", + "description": "" + }, + "sender": { + "login": "baxterthehacker", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": true + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/member.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/member.json new file mode 100644 index 000000000..20305670e --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/member.json @@ -0,0 +1,128 @@ +{ + "action": "added", + "member": { + "login": "octocat", + "id": 583231, + "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:40Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/membership.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/membership.json new file mode 100644 index 000000000..612d967f6 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/membership.json @@ -0,0 +1,61 @@ +{ + "action": "added", + "scope": "team", + "member": { + "login": "kdaigle", + "id": 2501, + "avatar_url": "https://avatars.githubusercontent.com/u/2501?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/kdaigle", + "html_url": "https://github.com/kdaigle", + "followers_url": "https://api.github.com/users/kdaigle/followers", + "following_url": "https://api.github.com/users/kdaigle/following{/other_user}", + "gists_url": "https://api.github.com/users/kdaigle/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kdaigle/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kdaigle/subscriptions", + "organizations_url": "https://api.github.com/users/kdaigle/orgs", + "repos_url": "https://api.github.com/users/kdaigle/repos", + "events_url": "https://api.github.com/users/kdaigle/events{/privacy}", + "received_events_url": "https://api.github.com/users/kdaigle/received_events", + "type": "User", + "site_admin": true + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=2", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "team": { + "name": "Contractors", + "id": 123456, + "slug": "contractors", + "permission": "admin", + "url": "https://api.github.com/teams/123456", + "members_url": "https://api.github.com/teams/123456/members{/member}", + "repositories_url": "https://api.github.com/teams/123456/repos" + }, + "organization": { + "login": "baxterandthehackers", + "id": 7649605, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=2" + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/milestone.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/milestone.json new file mode 100644 index 000000000..7f262abd5 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/milestone.json @@ -0,0 +1,160 @@ +{ + "action": "created", + "milestone": { + "url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones/3", + "html_url": "https://github.com/baxterandthehackers/public-repo/milestones/Test%20milestone%20creation%20webhook + %20from%20command%20line2", + "labels_url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones/3/labels", + "id": 2055681, + "number": 3, + "title": "I am a milestone", + "description": null, + "creator": { + "login": "baxterthehacker", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": true + }, + "open_issues": 0, + "closed_issues": 0, + "state": "open", + "created_at": "2016-10-07T19:26:08Z", + "updated_at": "2016-10-07T19:26:08Z", + "due_on": null, + "closed_at": null + }, + "repository": { + "id": 70275481, + "name": "public-repo", + "full_name": "baxterandthehackers/public-repo", + "owner": { + "login": "baxterandthehackers", + "id": 4312013, + "avatar_url": "https://avatars.githubusercontent.com/u/4312013?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": true, + "html_url": "https://github.com/baxterandthehackers/public-repo", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/baxterandthehackers/public-repo", + "forks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/public-repo/notifications{?since,all, + participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/public-repo/releases{/id}", + "deployments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/deployments", + "created_at": "2016-10-07T19:10:12Z", + "updated_at": "2016-10-07T19:10:12Z", + "pushed_at": "2016-10-07T19:10:13Z", + "git_url": "git://github.com/baxterandthehackers/public-repo.git", + "ssh_url": "git@github.com:baxterandthehackers/public-repo.git", + "clone_url": "https://github.com/baxterandthehackers/public-repo.git", + "svn_url": "https://github.com/baxterandthehackers/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "organization": { + "login": "baxterandthehackers", + "id": 4312013, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "hooks_url": "https://api.github.com/orgs/baxterandthehackers/hooks", + "issues_url": "https://api.github.com/orgs/baxterandthehackers/issues", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/4312013?v=3", + "description": "" + }, + "sender": { + "login": "baxterthehacker", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": true + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/page_build.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/page_build.json new file mode 100644 index 000000000..80962c016 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/page_build.json @@ -0,0 +1,139 @@ +{ + "id": 15995382, + "build": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pages/builds/15995382", + "status": "built", + "error": { + "message": null + }, + "pusher": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "commit": "053b99542c83021d6b202d1a1f5ecd5ef7084e55", + "duration": 3790, + "created_at": "2015-05-05T23:40:13Z", + "updated_at": "2015-05-05T23:40:17Z" + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:17Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/public.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/public.json new file mode 100644 index 000000000..f596a5428 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/public.json @@ -0,0 +1,108 @@ +{ + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:41Z", + "pushed_at": "2015-05-05T23:40:40Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request.json new file mode 100644 index 000000000..316cc4e8f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request.json @@ -0,0 +1,412 @@ +{ + "action": "opened", + "number": 1, + "pull_request": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", + "id": 34778301, + "html_url": "https://github.com/baxterthehacker/public-repo/pull/1", + "diff_url": "https://github.com/baxterthehacker/public-repo/pull/1.diff", + "patch_url": "https://github.com/baxterthehacker/public-repo/pull/1.patch", + "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into master.", + "created_at": "2015-05-05T23:40:27Z", + "updated_at": "2015-05-05T23:40:27Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": null, + "assignee": null, + "milestone": null, + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "head": { + "label": "baxterthehacker:changes", + "ref": "changes", + "sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:26Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "base": { + "label": "baxterthehacker:master", + "ref": "master", + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:26Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c" + } + }, + "merged": false, + "mergeable": null, + "mergeable_state": "unknown", + "merged_by": null, + "comments": 0, + "review_comments": 0, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:26Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review.json new file mode 100644 index 000000000..82c839608 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review.json @@ -0,0 +1,440 @@ +{ + "action": "submitted", + "review": { + "id": 2626884, + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "body": "Looks great!", + "submitted_at": "2016-10-03T23:39:09Z", + "state": "approved", + "html_url": "https://github.com/baxterthehacker/public-repo/pull/8#pullrequestreview-2626884", + "pull_request_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8", + "_links": { + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/8#pullrequestreview-2626884" + }, + "pull_request": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8" + } + } + }, + "pull_request": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8", + "id": 87811438, + "html_url": "https://github.com/baxterthehacker/public-repo/pull/8", + "diff_url": "https://github.com/baxterthehacker/public-repo/pull/8.diff", + "patch_url": "https://github.com/baxterthehacker/public-repo/pull/8.patch", + "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/8", + "number": 8, + "state": "open", + "locked": false, + "title": "Add a README description", + "user": { + "login": "skalnik", + "id": 2546, + "avatar_url": "https://avatars.githubusercontent.com/u/2546?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/skalnik", + "html_url": "https://github.com/skalnik", + "followers_url": "https://api.github.com/users/skalnik/followers", + "following_url": "https://api.github.com/users/skalnik/following{/other_user}", + "gists_url": "https://api.github.com/users/skalnik/gists{/gist_id}", + "starred_url": "https://api.github.com/users/skalnik/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/skalnik/subscriptions", + "organizations_url": "https://api.github.com/users/skalnik/orgs", + "repos_url": "https://api.github.com/users/skalnik/repos", + "events_url": "https://api.github.com/users/skalnik/events{/privacy}", + "received_events_url": "https://api.github.com/users/skalnik/received_events", + "type": "User", + "site_admin": true + }, + "body": "Just a few more details", + "created_at": "2016-10-03T23:37:43Z", + "updated_at": "2016-10-03T23:39:09Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "faea154a7decef6819754aab0f8c0e232e6c8b4f", + "assignee": null, + "assignees": [], + "milestone": null, + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8/commits", + "review_comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8/comments", + "review_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/8/comments", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/b7a1f9c27caa4e03c14a88feb56e2d4f7500aa63", + "head": { + "label": "skalnik:patch-2", + "ref": "patch-2", + "sha": "b7a1f9c27caa4e03c14a88feb56e2d4f7500aa63", + "user": { + "login": "skalnik", + "id": 2546, + "avatar_url": "https://avatars.githubusercontent.com/u/2546?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/skalnik", + "html_url": "https://github.com/skalnik", + "followers_url": "https://api.github.com/users/skalnik/followers", + "following_url": "https://api.github.com/users/skalnik/following{/other_user}", + "gists_url": "https://api.github.com/users/skalnik/gists{/gist_id}", + "starred_url": "https://api.github.com/users/skalnik/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/skalnik/subscriptions", + "organizations_url": "https://api.github.com/users/skalnik/orgs", + "repos_url": "https://api.github.com/users/skalnik/repos", + "events_url": "https://api.github.com/users/skalnik/events{/privacy}", + "received_events_url": "https://api.github.com/users/skalnik/received_events", + "type": "User", + "site_admin": true + }, + "repo": { + "id": 69919152, + "name": "public-repo", + "full_name": "skalnik/public-repo", + "owner": { + "login": "skalnik", + "id": 2546, + "avatar_url": "https://avatars.githubusercontent.com/u/2546?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/skalnik", + "html_url": "https://github.com/skalnik", + "followers_url": "https://api.github.com/users/skalnik/followers", + "following_url": "https://api.github.com/users/skalnik/following{/other_user}", + "gists_url": "https://api.github.com/users/skalnik/gists{/gist_id}", + "starred_url": "https://api.github.com/users/skalnik/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/skalnik/subscriptions", + "organizations_url": "https://api.github.com/users/skalnik/orgs", + "repos_url": "https://api.github.com/users/skalnik/repos", + "events_url": "https://api.github.com/users/skalnik/events{/privacy}", + "received_events_url": "https://api.github.com/users/skalnik/received_events", + "type": "User", + "site_admin": true + }, + "private": false, + "html_url": "https://github.com/skalnik/public-repo", + "description": null, + "fork": true, + "url": "https://api.github.com/repos/skalnik/public-repo", + "forks_url": "https://api.github.com/repos/skalnik/public-repo/forks", + "keys_url": "https://api.github.com/repos/skalnik/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/skalnik/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/skalnik/public-repo/teams", + "hooks_url": "https://api.github.com/repos/skalnik/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/skalnik/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/skalnik/public-repo/events", + "assignees_url": "https://api.github.com/repos/skalnik/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/skalnik/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/skalnik/public-repo/tags", + "blobs_url": "https://api.github.com/repos/skalnik/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/skalnik/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/skalnik/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/skalnik/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/skalnik/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/skalnik/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/skalnik/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/skalnik/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/skalnik/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/skalnik/public-repo/subscription", + "commits_url": "https://api.github.com/repos/skalnik/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/skalnik/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/skalnik/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/skalnik/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/skalnik/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/skalnik/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/skalnik/public-repo/merges", + "archive_url": "https://api.github.com/repos/skalnik/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/skalnik/public-repo/downloads", + "issues_url": "https://api.github.com/repos/skalnik/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/skalnik/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/skalnik/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/skalnik/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/skalnik/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/skalnik/public-repo/releases{/id}", + "deployments_url": "https://api.github.com/repos/skalnik/public-repo/deployments", + "created_at": "2016-10-03T23:23:31Z", + "updated_at": "2016-08-15T17:19:01Z", + "pushed_at": "2016-10-03T23:36:52Z", + "git_url": "git://github.com/skalnik/public-repo.git", + "ssh_url": "git@github.com:skalnik/public-repo.git", + "clone_url": "https://github.com/skalnik/public-repo.git", + "svn_url": "https://github.com/skalnik/public-repo", + "homepage": null, + "size": 233, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": false, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + } + }, + "base": { + "label": "baxterthehacker:master", + "ref": "master", + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "deployments_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2016-08-15T17:19:01Z", + "pushed_at": "2016-10-03T23:37:43Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 233, + "stargazers_count": 2, + "watchers_count": 2, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 2, + "mirror_url": null, + "open_issues_count": 5, + "forks": 2, + "open_issues": 5, + "watchers": 2, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/8" + }, + "issue": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/8" + }, + "comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/8/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/8/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/b7a1f9c27caa4e03c14a88feb56e2d4f7500aa63" + } + } + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "deployments_url": "https://api.github.com/repos/baxterthehacker/public-repo/deployments", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2016-08-15T17:19:01Z", + "pushed_at": "2016-10-03T23:37:43Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 233, + "stargazers_count": 2, + "watchers_count": 2, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 2, + "mirror_url": null, + "open_issues_count": 5, + "forks": 2, + "open_issues": 5, + "watchers": 2, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review_comment.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review_comment.json new file mode 100644 index 000000000..a89b6b547 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/pull_request_review_comment.json @@ -0,0 +1,446 @@ +{ + "action": "created", + "comment": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments/29724692", + "id": 29724692, + "diff_hunk": "@@ -1 +1 @@\n-# public-repo", + "path": "README.md", + "position": 1, + "original_position": 1, + "commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "original_commit_id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "body": "Maybe you should use more emojji on this line.", + "created_at": "2015-05-05T23:40:27Z", + "updated_at": "2015-05-05T23:40:27Z", + "html_url": "https://github.com/baxterthehacker/public-repo/pull/1#discussion_r29724692", + "pull_request_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments/29724692" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/1#discussion_r29724692" + }, + "pull_request": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" + } + } + }, + "pull_request": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1", + "id": 34778301, + "html_url": "https://github.com/baxterthehacker/public-repo/pull/1", + "diff_url": "https://github.com/baxterthehacker/public-repo/pull/1.diff", + "patch_url": "https://github.com/baxterthehacker/public-repo/pull/1.patch", + "issue_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1", + "number": 1, + "state": "open", + "locked": false, + "title": "Update the README with new information", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into master.", + "created_at": "2015-05-05T23:40:27Z", + "updated_at": "2015-05-05T23:40:27Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": "18721552ba489fb84e12958c1b5694b5475f7991", + "assignee": null, + "milestone": null, + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits", + "review_comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments", + "review_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "head": { + "label": "baxterthehacker:changes", + "ref": "changes", + "sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "base": { + "label": "baxterthehacker:master", + "ref": "master", + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "user": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1" + }, + "html": { + "href": "https://github.com/baxterthehacker/public-repo/pull/1" + }, + "issue": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1" + }, + "comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/issues/1/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/pulls/1/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c" + } + } + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 1, + "forks": 0, + "open_issues": 1, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json new file mode 100644 index 000000000..44ba0bbdb --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json @@ -0,0 +1,174 @@ +{ + "ref": "refs/heads/changes", + "before": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "after": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "created": false, + "deleted": false, + "forced": false, + "base_ref": null, + "compare": "https://github.com/baxterthehacker/public-repo/compare/9049f1265b7d...0d1a26e67d8f", + "commits": [ + { + "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "tree_id": "f9d2a07e9488b91af2641b26b9407fe22a451433", + "distinct": true, + "message": "Update README.md", + "timestamp": "2015-05-05T19:40:15-04:00", + "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "author": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "committer": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "added": [ + ], + "removed": [ + ], + "modified": [ + "README.md" + ] + } + ], + "head_commit": { + "id": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "tree_id": "f9d2a07e9488b91af2641b26b9407fe22a451433", + "distinct": true, + "message": "Update README.md", + "timestamp": "2015-05-05T19:40:15-04:00", + "url": "https://github.com/baxterthehacker/public-repo/commit/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "author": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "committer": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "username": "baxterthehacker" + }, + "added": [ + ], + "removed": [ + ], + "modified": [ + "README.md" + ] + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://github.com/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": 1430869212, + "updated_at": "2015-05-05T23:40:12Z", + "pushed_at": 1430869217, + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master", + "stargazers": 0, + "master_branch": "master" + }, + "pusher": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/release.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/release.json new file mode 100644 index 000000000..35de2f33e --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/release.json @@ -0,0 +1,147 @@ +{ + "action": "published", + "release": { + "url": "https://api.github.com/repos/baxterthehacker/public-repo/releases/1261438", + "assets_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases/1261438/assets", + "upload_url": "https://uploads.github.com/repos/baxterthehacker/public-repo/releases/1261438/assets{?name}", + "html_url": "https://github.com/baxterthehacker/public-repo/releases/tag/0.0.1", + "id": 1261438, + "tag_name": "0.0.1", + "target_commitish": "master", + "name": null, + "draft": false, + "author": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "prerelease": false, + "created_at": "2015-05-05T23:40:12Z", + "published_at": "2015-05-05T23:40:38Z", + "assets": [ + ], + "tarball_url": "https://api.github.com/repos/baxterthehacker/public-repo/tarball/0.0.1", + "zipball_url": "https://api.github.com/repos/baxterthehacker/public-repo/zipball/0.0.1", + "body": null + }, + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:38Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/repository.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/repository.json new file mode 100644 index 000000000..d22386c3f --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/repository.json @@ -0,0 +1,119 @@ +{ + "action": "created", + "repository": { + "id": 27496774, + "name": "new-repository", + "full_name": "baxterandthehackers/new-repository", + "owner": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": true, + "html_url": "https://github.com/baxterandthehackers/new-repository", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterandthehackers/new-repository", + "forks_url": "https://api.github.com/repos/baxterandthehackers/new-repository/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/new-repository/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/new-repository/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/new-repository/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/new-repository/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/new-repository/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/new-repository/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/new-repository/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/new-repository/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/new-repository/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/new-repository/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/new-repository/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/new-repository/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/new-repository/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/new-repository/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/new-repository/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/new-repository/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/new-repository/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/new-repository/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/new-repository/issues/comments/{number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/new-repository/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/new-repository/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/new-repository/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/new-repository/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/new-repository/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/new-repository/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/new-repository/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/new-repository/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/new-repository/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/new-repository/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/new-repository/releases{/id}", + "created_at": "2014-12-03T16:39:25Z", + "updated_at": "2014-12-03T16:39:25Z", + "pushed_at": "2014-12-03T16:39:25Z", + "git_url": "git://github.com/baxterandthehackers/new-repository.git", + "ssh_url": "git@github.com:baxterandthehackers/new-repository.git", + "clone_url": "https://github.com/baxterandthehackers/new-repository.git", + "svn_url": "https://github.com/baxterandthehackers/new-repository", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": false, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "organization": { + "login": "baxterandthehackers", + "id": 7649605, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=2" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=2", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/status.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/status.json new file mode 100644 index 000000000..82f5a0996 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/status.json @@ -0,0 +1,205 @@ +{ + "id": 214015194, + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "name": "baxterthehacker/public-repo", + "target_url": null, + "context": "default", + "description": null, + "state": "success", + "commit": { + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "commit": { + "author": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "date": "2015-05-05T23:40:12Z" + }, + "committer": { + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com", + "date": "2015-05-05T23:40:12Z" + }, + "message": "Initial commit", + "tree": { + "sha": "02b49ad0ba4f1acd9f06531b21e16a4ac5d341d0", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees/02b49ad0ba4f1acd9f06531b21e16a4ac5d341d0" + }, + "url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b", + "comment_count": 1 + }, + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b", + "html_url": "https://github.com/baxterthehacker/public-repo/commit/9049f1265b7d61be4a8904a9a27120d2064dab3b", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b/comments", + "author": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "committer": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "parents": [ + ] + }, + "branches": [ + { + "name": "master", + "commit": { + "sha": "9049f1265b7d61be4a8904a9a27120d2064dab3b", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/9049f1265b7d61be4a8904a9a27120d2064dab3b" + } + }, + { + "name": "changes", + "commit": { + "sha": "0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c" + } + }, + { + "name": "gh-pages", + "commit": { + "sha": "b11bb7545ac14abafc6191a0481b0d961e7793c6", + "url": "https://api.github.com/repos/baxterthehacker/public-repo/commits/b11bb7545ac14abafc6191a0481b0d961e7793c6" + } + } + ], + "created_at": "2015-05-05T23:40:39Z", + "updated_at": "2015-05-05T23:40:39Z", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:39Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/team_add.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/team_add.json new file mode 100644 index 000000000..bd4256bc0 --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/team_add.json @@ -0,0 +1,129 @@ +{ + "team": { + "name": "github", + "id": 836012, + "slug": "github", + "description": "", + "permission": "pull", + "url": "https://api.github.com/teams/836012", + "members_url": "https://api.github.com/teams/836012/members{/member}", + "repositories_url": "https://api.github.com/teams/836012/repos" + }, + "repository": { + "id": 35129393, + "name": "public-repo", + "full_name": "baxterandthehackers/public-repo", + "owner": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterandthehackers/public-repo", + "description": "", + "fork": true, + "url": "https://api.github.com/repos/baxterandthehackers/public-repo", + "forks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterandthehackers/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterandthehackers/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterandthehackers/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterandthehackers/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterandthehackers/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterandthehackers/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterandthehackers/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterandthehackers/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterandthehackers/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterandthehackers/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterandthehackers/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterandthehackers/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterandthehackers/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterandthehackers/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterandthehackers/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterandthehackers/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterandthehackers/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterandthehackers/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterandthehackers/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterandthehackers/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterandthehackers/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterandthehackers/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:30Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterandthehackers/public-repo.git", + "ssh_url": "git@github.com:baxterandthehackers/public-repo.git", + "clone_url": "https://github.com/baxterandthehackers/public-repo.git", + "svn_url": "https://github.com/baxterandthehackers/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": false, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 0, + "forks": 0, + "open_issues": 0, + "watchers": 0, + "default_branch": "master" + }, + "organization": { + "login": "baxterandthehackers", + "id": 7649605, + "url": "https://api.github.com/orgs/baxterandthehackers", + "repos_url": "https://api.github.com/orgs/baxterandthehackers/repos", + "events_url": "https://api.github.com/orgs/baxterandthehackers/events", + "members_url": "https://api.github.com/orgs/baxterandthehackers/members{/member}", + "public_members_url": "https://api.github.com/orgs/baxterandthehackers/public_members{/member}", + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "description": null + }, + "sender": { + "login": "baxterandthehackers", + "id": 7649605, + "avatar_url": "https://avatars.githubusercontent.com/u/7649605?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterandthehackers", + "html_url": "https://github.com/baxterandthehackers", + "followers_url": "https://api.github.com/users/baxterandthehackers/followers", + "following_url": "https://api.github.com/users/baxterandthehackers/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterandthehackers/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterandthehackers/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterandthehackers/subscriptions", + "organizations_url": "https://api.github.com/users/baxterandthehackers/orgs", + "repos_url": "https://api.github.com/users/baxterandthehackers/repos", + "events_url": "https://api.github.com/users/baxterandthehackers/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterandthehackers/received_events", + "type": "Organization", + "site_admin": false + } +} diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/watch.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/watch.json new file mode 100644 index 000000000..88bc71d0a --- /dev/null +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/watch.json @@ -0,0 +1,109 @@ +{ + "action": "started", + "repository": { + "id": 35129377, + "name": "public-repo", + "full_name": "baxterthehacker/public-repo", + "owner": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + }, + "private": false, + "html_url": "https://github.com/baxterthehacker/public-repo", + "description": "", + "fork": false, + "url": "https://api.github.com/repos/baxterthehacker/public-repo", + "forks_url": "https://api.github.com/repos/baxterthehacker/public-repo/forks", + "keys_url": "https://api.github.com/repos/baxterthehacker/public-repo/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/baxterthehacker/public-repo/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/baxterthehacker/public-repo/teams", + "hooks_url": "https://api.github.com/repos/baxterthehacker/public-repo/hooks", + "issue_events_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/events{/number}", + "events_url": "https://api.github.com/repos/baxterthehacker/public-repo/events", + "assignees_url": "https://api.github.com/repos/baxterthehacker/public-repo/assignees{/user}", + "branches_url": "https://api.github.com/repos/baxterthehacker/public-repo/branches{/branch}", + "tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/tags", + "blobs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/baxterthehacker/public-repo/statuses/{sha}", + "languages_url": "https://api.github.com/repos/baxterthehacker/public-repo/languages", + "stargazers_url": "https://api.github.com/repos/baxterthehacker/public-repo/stargazers", + "contributors_url": "https://api.github.com/repos/baxterthehacker/public-repo/contributors", + "subscribers_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscribers", + "subscription_url": "https://api.github.com/repos/baxterthehacker/public-repo/subscription", + "commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/baxterthehacker/public-repo/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/baxterthehacker/public-repo/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/baxterthehacker/public-repo/contents/{+path}", + "compare_url": "https://api.github.com/repos/baxterthehacker/public-repo/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/baxterthehacker/public-repo/merges", + "archive_url": "https://api.github.com/repos/baxterthehacker/public-repo/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/baxterthehacker/public-repo/downloads", + "issues_url": "https://api.github.com/repos/baxterthehacker/public-repo/issues{/number}", + "pulls_url": "https://api.github.com/repos/baxterthehacker/public-repo/pulls{/number}", + "milestones_url": "https://api.github.com/repos/baxterthehacker/public-repo/milestones{/number}", + "notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}", + "releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}", + "created_at": "2015-05-05T23:40:12Z", + "updated_at": "2015-05-05T23:40:30Z", + "pushed_at": "2015-05-05T23:40:27Z", + "git_url": "git://github.com/baxterthehacker/public-repo.git", + "ssh_url": "git@github.com:baxterthehacker/public-repo.git", + "clone_url": "https://github.com/baxterthehacker/public-repo.git", + "svn_url": "https://github.com/baxterthehacker/public-repo", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "open_issues_count": 2, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "baxterthehacker", + "id": 6752317, + "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/baxterthehacker", + "html_url": "https://github.com/baxterthehacker", + "followers_url": "https://api.github.com/users/baxterthehacker/followers", + "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", + "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", + "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", + "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", + "repos_url": "https://api.github.com/users/baxterthehacker/repos", + "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", + "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", + "type": "User", + "site_admin": false + } +} From 5b92d4b88cafcc6050f875fea6d5116880fa04f8 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Nov 2016 15:04:02 +0000 Subject: [PATCH 093/118] Fix findbugs false alarms --- src/main/java/org/kohsuke/github/GHCommitComment.java | 10 ---------- src/main/java/org/kohsuke/github/GHEventPayload.java | 4 ++++ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHCommitComment.java b/src/main/java/org/kohsuke/github/GHCommitComment.java index 64b658d2f..79f19a6e6 100644 --- a/src/main/java/org/kohsuke/github/GHCommitComment.java +++ b/src/main/java/org/kohsuke/github/GHCommitComment.java @@ -23,16 +23,6 @@ public class GHCommitComment extends GHObject { String path; GHUser user; // not fully populated. beware. - static class User { - // TODO: what if someone who doesn't have an account on GitHub makes a commit? - @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now") - String url,avatar_url,gravatar_id; - @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "We don't provide it in API now") - int id; - - String login; - } - public GHRepository getOwner() { return owner; } diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index 7e5464648..2dfbe61db 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -428,6 +428,8 @@ public abstract class GHEventPayload { * * @see authoritative source */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD", "UUF_UNUSED_FIELD"}, + justification = "Constructed by JSON deserialization") public static class Push extends GHEventPayload { private String head, before; private boolean created, deleted, forced; @@ -553,6 +555,8 @@ public abstract class GHEventPayload { * * @see authoritative source */ + @SuppressFBWarnings(value = {"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "NP_UNWRITTEN_FIELD", "UWF_UNWRITTEN_FIELD"}, + justification = "Constructed by JSON deserialization") public static class Repository extends GHEventPayload { private String action; private GHRepository repository; From ce3f74232e669dc3ec09b50ef18de8632d86c020 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Nov 2016 15:11:35 +0000 Subject: [PATCH 094/118] Ensure a use case required by github-plugin is valid --- src/test/java/org/kohsuke/github/GHEventPayloadTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java index f414b6e7b..7cdc46cf8 100644 --- a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -212,6 +212,7 @@ public class GHEventPayloadTest { assertThat(event.getCommits().get(0).getModified().get(0), is("README.md")); assertThat(event.getRepository().getName(), is("public-repo")); assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getRepository().getUrl().toExternalForm(), is("https://github.com/baxterthehacker/public-repo")); assertThat(event.getSender().getLogin(), is("baxterthehacker")); } From 7bf8621afe616c20060b070f01c3fb9cf734e291 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Nov 2016 15:14:42 +0000 Subject: [PATCH 095/118] Need the pusher details for github-plugin --- .../org/kohsuke/github/GHEventPayload.java | 29 +++++++++++++++++++ .../kohsuke/github/GHEventPayloadTest.java | 2 ++ 2 files changed, 31 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index 2dfbe61db..7f1f4618c 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -437,6 +437,7 @@ public abstract class GHEventPayload { private int size; private List commits; private GHRepository repository; + private Pusher pusher; /** * The SHA of the HEAD commit on the repository @@ -484,6 +485,14 @@ public abstract class GHEventPayload { return repository; } + public Pusher getPusher() { + return pusher; + } + + public void setPusher(Pusher pusher) { + this.pusher = pusher; + } + @Override void wrapUp(GitHub root) { super.wrapUp(root); @@ -491,6 +500,26 @@ public abstract class GHEventPayload { repository.wrap(root); } + public static class Pusher { + private String name, email; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + } + /** * Commit in a push */ diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java index 7cdc46cf8..456ea2316 100644 --- a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -213,6 +213,8 @@ public class GHEventPayloadTest { assertThat(event.getRepository().getName(), is("public-repo")); assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); assertThat(event.getRepository().getUrl().toExternalForm(), is("https://github.com/baxterthehacker/public-repo")); + assertThat(event.getPusher().getName(), is("baxterthehacker")); + assertThat(event.getPusher().getEmail(), is("baxterthehacker@users.noreply.github.com")); assertThat(event.getSender().getLogin(), is("baxterthehacker")); } From 66145e1d232be7324ea72d93186d9ce4f014736b Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Nov 2016 15:26:33 +0000 Subject: [PATCH 096/118] Seems there is an undocumented but important PING event used by github-plugin --- .../org/kohsuke/github/GHEventPayload.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index 7f1f4618c..bc326fcf2 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -398,6 +398,29 @@ public abstract class GHEventPayload { } } + /** + * A ping. + */ + public static class Ping extends GHEventPayload { + private GHRepository repository; + + public void setRepository(GHRepository repository) { + this.repository = repository; + } + + public GHRepository getRepository() { + return repository; + } + + @Override + void wrapUp(GitHub root) { + super.wrapUp(root); + if (repository!=null) + repository.wrap(root); + } + + } + /** * A repository was made public. * From 7dc620a3ba6b9cee23a077f24f438fa2c1b92333 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Nov 2016 15:29:27 +0000 Subject: [PATCH 097/118] More details emerge on the PingEvent payload --- src/main/java/org/kohsuke/github/GHEventPayload.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index bc326fcf2..d1ffa97fb 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -403,6 +403,7 @@ public abstract class GHEventPayload { */ public static class Ping extends GHEventPayload { private GHRepository repository; + private GHOrganization organization; public void setRepository(GHRepository repository) { this.repository = repository; @@ -412,11 +413,22 @@ public abstract class GHEventPayload { return repository; } + public GHOrganization getOrganization() { + return organization; + } + + public void setOrganization(GHOrganization organization) { + this.organization = organization; + } + @Override void wrapUp(GitHub root) { super.wrapUp(root); if (repository!=null) repository.wrap(root); + if (organization != null) { + organization.wrapUp(root); + } } } From 498d63ea0067621d2271df3592a03c8e24a0443f Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Tue, 8 Nov 2016 15:48:39 +0000 Subject: [PATCH 098/118] Typos spotted by Jesse --- src/main/java/org/kohsuke/github/GitHub.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 04b3efefd..8f2e65ade 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -216,11 +216,11 @@ public class GitHub { } /** - * An off-line only {@link GitHub} useful for parsing event notification from an unknown source. + * An offline-only {@link GitHub} useful for parsing event notification from an unknown source. * * All operations that require a connection will fail. * - * @return An off-line only {@link GitHub}. + * @return An offline-only {@link GitHub}. */ public static GitHub offline() { try { From d36e145d066466ab0ee7373db1734b744f94aafd Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Fri, 11 Nov 2016 14:18:47 +0000 Subject: [PATCH 099/118] Need to be able to tell if this is a creation / deletion of a ref for multibranch projects --- src/main/java/org/kohsuke/github/GHEventPayload.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHEventPayload.java b/src/main/java/org/kohsuke/github/GHEventPayload.java index d1ffa97fb..29f69bb3e 100644 --- a/src/main/java/org/kohsuke/github/GHEventPayload.java +++ b/src/main/java/org/kohsuke/github/GHEventPayload.java @@ -509,6 +509,18 @@ public abstract class GHEventPayload { return size; } + public boolean isCreated() { + return created; + } + + public boolean isDeleted() { + return deleted; + } + + public boolean isForced() { + return forced; + } + /** * The list of pushed commits. */ From 9988a090acd96c345d61a24b947e078cca000760 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Fri, 11 Nov 2016 14:27:09 +0000 Subject: [PATCH 100/118] Add some more tests --- src/test/java/org/kohsuke/github/GHEventPayloadTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java index 456ea2316..356a5a77d 100644 --- a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -202,6 +202,9 @@ public class GHEventPayloadTest { assertThat(event.getRef(), is("refs/heads/changes")); assertThat(event.getBefore(), is("9049f1265b7d61be4a8904a9a27120d2064dab3b")); assertThat(event.getHead(), is("0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c")); + assertThat(event.isCreated(), is(false)); + assertThat(event.isDeleted(), is(false)); + assertThat(event.isForced(), is(false)); assertThat(event.getCommits().size(), is(1)); assertThat(event.getCommits().get(0).getSha(), is("0d1a26e67d8f5eaf1f6ba5c57fc3c7d91ac0fd1c")); assertThat(event.getCommits().get(0).getAuthor().getEmail(), is("baxterthehacker@users.noreply.github.com")); From 24f48f668c326910008cba1227ba53c8b8d4bfe9 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 11 Nov 2016 16:56:03 +0200 Subject: [PATCH 101/118] Add portion of auth/application API. (#307) * Add portion of auth/application API. Signed-off-by: Kanstantsin Shautsou * fixup --- .../org/kohsuke/github/GHAuthorization.java | 18 +++++++++ src/main/java/org/kohsuke/github/GitHub.java | 37 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHAuthorization.java b/src/main/java/org/kohsuke/github/GHAuthorization.java index b8b7aff19..ead866bb0 100644 --- a/src/main/java/org/kohsuke/github/GHAuthorization.java +++ b/src/main/java/org/kohsuke/github/GHAuthorization.java @@ -36,9 +36,14 @@ public class GHAuthorization extends GHObject { private GitHub root; private List scopes; private String token; + private String token_last_eight; + private String hashed_token; private App app; private String note; private String note_url; + private String fingerprint; + //TODO add some user class for https://developer.github.com/v3/oauth_authorizations/#check-an-authorization ? + //private GHUser user; public GitHub getRoot() { return root; @@ -52,6 +57,14 @@ public class GHAuthorization extends GHObject { return token; } + public String getTokenLastEight() { + return token_last_eight; + } + + public String getHashedToken() { + return hashed_token; + } + public URL getAppUrl() { return GitHub.parseURL(app.url); } @@ -82,6 +95,10 @@ public class GHAuthorization extends GHObject { return GitHub.parseURL(note_url); } + public String getFingerprint() { + return fingerprint; + } + /*package*/ GHAuthorization wrap(GitHub root) { this.root = root; return this; @@ -92,5 +109,6 @@ public class GHAuthorization extends GHObject { private static class App { private String url; private String name; + private String client_id; } } diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index e5bf16b1d..9dcce5fc8 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -58,6 +58,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.introspect.VisibilityChecker.Std; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; +import javax.annotation.Nonnull; import java.util.logging.Logger; /** @@ -497,6 +498,42 @@ public class GitHub { return requester.method("POST").to("/authorizations", GHAuthorization.class).wrap(this); } + /** + * @see docs + */ + public GHAuthorization createOrGetAuth(String clientId, String clientSecret, List scopes, String note, + String note_url) + throws IOException { + Requester requester = new Requester(this) + .with("client_secret", clientSecret) + .with("scopes", scopes) + .with("note", note) + .with("note_url", note_url); + + return requester.method("PUT").to("/authorizations/clients/" + clientId, GHAuthorization.class); + } + + /** + * @see Delete an authorization + */ + public void deleteAuth(long id) throws IOException { + retrieve().method("DELETE").to("/authorizations/" + id); + } + + /** + * @see Check an authorization + */ + public GHAuthorization checkAuth(@Nonnull String clientId, @Nonnull String accessToken) throws IOException { + return retrieve().to("/applications/" + clientId + "/tokens/" + accessToken, GHAuthorization.class); + } + + /** + * @see Reset an authorization + */ + public GHAuthorization resetAuth(@Nonnull String clientId, @Nonnull String accessToken) throws IOException { + return retrieve().method("POST").to("/applications/" + clientId + "/tokens/" + accessToken, GHAuthorization.class); + } + /** * Ensures that the credential is valid. */ From e544c7a65ae65ff03d45fca4baae1ccaaeed6583 Mon Sep 17 00:00:00 2001 From: Stephen Connolly Date: Mon, 14 Nov 2016 12:52:22 +0000 Subject: [PATCH 102/118] Fix the push event payload --- .../java/org/kohsuke/github/GHRepository.java | 44 ++++++++++--------- .../kohsuke/github/GHEventPayloadTest.java | 2 +- .../github/GHEventPayloadTest/push.json | 19 +------- 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index a26d8e75a..3cdaab07e 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -232,7 +232,7 @@ public class GHRepository extends GHObject { } public GHUser getOwner() throws IOException { - return root.isOffline() ? owner : root.getUser(owner.login); // because 'owner' isn't fully populated + return root.isOffline() ? owner : root.getUser(getOwnerName()); // because 'owner' isn't fully populated } public GHIssue getIssue(int id) throws IOException { @@ -339,7 +339,11 @@ public class GHRepository extends GHObject { } public String getOwnerName() { - return owner.login; + // consistency of the GitHub API is super... some serialized forms of GHRepository populate + // a full GHUser while others populate only the owner and email. This later form is super helpful + // in putting the login in owner.name not owner.login... thankfully we can easily identify this + // second set because owner.login will be null + return owner.login != null ? owner.login : owner.name; } public boolean hasIssues() { @@ -467,7 +471,7 @@ public class GHRepository extends GHObject { * If this repository belongs to an organization, return a set of teams. */ public Set getTeams() throws IOException { - return Collections.unmodifiableSet(new HashSet(Arrays.asList(GHTeam.wrapUp(root.retrieve().to(getApiTailUrl("teams"), GHTeam[].class), root.getOrganization(owner.login))))); + return Collections.unmodifiableSet(new HashSet(Arrays.asList(GHTeam.wrapUp(root.retrieve().to(getApiTailUrl("teams"), GHTeam[].class), root.getOrganization(getOwnerName()))))); } public void addCollaborators(GHUser... users) throws IOException { @@ -551,7 +555,7 @@ public class GHRepository extends GHObject { try { new Requester(root).method("DELETE").to(getApiTailUrl("")); } catch (FileNotFoundException x) { - throw (FileNotFoundException) new FileNotFoundException("Failed to delete " + owner.login + "/" + name + "; might not exist, or you might need the delete_repo scope in your token: http://stackoverflow.com/a/19327004/12916").initCause(x); + throw (FileNotFoundException) new FileNotFoundException("Failed to delete " + getOwnerName() + "/" + name + "; might not exist, or you might need the delete_repo scope in your token: http://stackoverflow.com/a/19327004/12916").initCause(x); } } @@ -742,7 +746,7 @@ public class GHRepository extends GHObject { * @throws IOException on failure communicating with GitHub */ public GHRef[] getRefs() throws IOException { - return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs", owner.login, name), GHRef[].class), root); + return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs", getOwnerName(), name), GHRef[].class), root); } /** @@ -752,7 +756,7 @@ public class GHRepository extends GHObject { * @throws IOException on failure communicating with GitHub, potentially due to an invalid ref type being requested */ public GHRef[] getRefs(String refType) throws IOException { - return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refType), GHRef[].class),root); + return GHRef.wrap(root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", getOwnerName(), name, refType), GHRef[].class),root); } /** * Retrive a ref of the given type for the current GitHub repository. @@ -769,7 +773,7 @@ public class GHRepository extends GHObject { // FIXME: how about other URL unsafe characters, like space, @, : etc? do we need to be using URLEncoder.encode()? // OTOH, '/' need no escaping refName = refName.replaceAll("#", "%23"); - return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", owner.login, name, refName), GHRef.class).wrap(root); + return root.retrieve().to(String.format("/repos/%s/%s/git/refs/%s", getOwnerName(), name, refName), GHRef.class).wrap(root); } /** * Retrive a tree of the given type for the current GitHub repository. @@ -781,7 +785,7 @@ public class GHRepository extends GHObject { * invalid tree type being requested */ public GHTree getTree(String sha) throws IOException { - String url = String.format("/repos/%s/%s/git/trees/%s", owner.login, name, sha); + String url = String.format("/repos/%s/%s/git/trees/%s", getOwnerName(), name, sha); return root.retrieve().to(url, GHTree.class).wrap(root); } @@ -796,7 +800,7 @@ public class GHRepository extends GHObject { * invalid tree type being requested */ public GHTree getTreeRecursive(String sha, int recursive) throws IOException { - String url = String.format("/repos/%s/%s/git/trees/%s?recursive=%d", owner.login, name, sha, recursive); + String url = String.format("/repos/%s/%s/git/trees/%s?recursive=%d", getOwnerName(), name, sha, recursive); return root.retrieve().to(url, GHTree.class).wrap(root); } @@ -806,7 +810,7 @@ public class GHRepository extends GHObject { public GHCommit getCommit(String sha1) throws IOException { GHCommit c = commits.get(sha1); if (c==null) { - c = root.retrieve().to(String.format("/repos/%s/%s/commits/%s", owner.login, name, sha1), GHCommit.class).wrapUp(this); + c = root.retrieve().to(String.format("/repos/%s/%s/commits/%s", getOwnerName(), name, sha1), GHCommit.class).wrapUp(this); commits.put(sha1,c); } return c; @@ -818,7 +822,7 @@ public class GHRepository extends GHObject { public PagedIterable listCommits() { return new PagedIterable() { public PagedIterator _iterator(int pageSize) { - return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/commits", owner.login, name), GHCommit[].class, pageSize)) { + return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/commits", getOwnerName(), name), GHCommit[].class, pageSize)) { protected void wrapUp(GHCommit[] page) { for (GHCommit c : page) c.wrapUp(GHRepository.this); @@ -841,7 +845,7 @@ public class GHRepository extends GHObject { public PagedIterable listCommitComments() { return new PagedIterable() { public PagedIterator _iterator(int pageSize) { - return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/comments", owner.login, name), GHCommitComment[].class, pageSize)) { + return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/comments", getOwnerName(), name), GHCommitComment[].class, pageSize)) { @Override protected void wrapUp(GHCommitComment[] page) { for (GHCommitComment c : page) @@ -898,7 +902,7 @@ public class GHRepository extends GHObject { public PagedIterable listCommitStatuses(final String sha1) throws IOException { return new PagedIterable() { public PagedIterator _iterator(int pageSize) { - return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/statuses/%s", owner.login, name, sha1), GHCommitStatus[].class, pageSize)) { + return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/statuses/%s", getOwnerName(), name, sha1), GHCommitStatus[].class, pageSize)) { @Override protected void wrapUp(GHCommitStatus[] page) { for (GHCommitStatus c : page) @@ -933,7 +937,7 @@ public class GHRepository extends GHObject { .with("target_url", targetUrl) .with("description", description) .with("context", context) - .to(String.format("/repos/%s/%s/statuses/%s",owner.login,this.name,sha1),GHCommitStatus.class).wrapUp(root); + .to(String.format("/repos/%s/%s/statuses/%s",getOwnerName(),this.name,sha1),GHCommitStatus.class).wrapUp(root); } /** @@ -949,7 +953,7 @@ public class GHRepository extends GHObject { public PagedIterable listEvents() throws IOException { return new PagedIterable() { public PagedIterator _iterator(int pageSize) { - return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/events", owner.login, name), GHEventInfo[].class, pageSize)) { + return new PagedIterator(root.retrieve().asIterator(String.format("/repos/%s/%s/events", getOwnerName(), name), GHEventInfo[].class, pageSize)) { @Override protected void wrapUp(GHEventInfo[] page) { for (GHEventInfo c : page) @@ -1076,8 +1080,8 @@ public class GHRepository extends GHObject { // } private void verifyMine() throws IOException { - if (!root.login.equals(owner.login)) - throw new IOException("Operation not applicable to a repository owned by someone else: "+owner.login); + if (!root.login.equals(getOwnerName())) + throw new IOException("Operation not applicable to a repository owned by someone else: " + getOwnerName()); } /** @@ -1425,14 +1429,14 @@ public class GHRepository extends GHObject { @Override public int hashCode() { - return ("Repository:"+owner.login+":"+name).hashCode(); + return ("Repository:"+getOwnerName()+":"+name).hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof GHRepository) { GHRepository that = (GHRepository) obj; - return this.owner.login.equals(that.owner.login) + return this.getOwnerName().equals(that.getOwnerName()) && this.name.equals(that.name); } return false; @@ -1440,6 +1444,6 @@ public class GHRepository extends GHObject { String getApiTailUrl(String tail) { if (tail.length()>0 && !tail.startsWith("/")) tail='/'+tail; - return "/repos/" + owner.login + "/" + name +tail; + return "/repos/" + getOwnerName() + "/" + name +tail; } } diff --git a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java index 356a5a77d..07758d1a0 100644 --- a/src/test/java/org/kohsuke/github/GHEventPayloadTest.java +++ b/src/test/java/org/kohsuke/github/GHEventPayloadTest.java @@ -214,7 +214,7 @@ public class GHEventPayloadTest { assertThat(event.getCommits().get(0).getModified().size(), is(1)); assertThat(event.getCommits().get(0).getModified().get(0), is("README.md")); assertThat(event.getRepository().getName(), is("public-repo")); - assertThat(event.getRepository().getOwner().getLogin(), is("baxterthehacker")); + assertThat(event.getRepository().getOwnerName(), is("baxterthehacker")); assertThat(event.getRepository().getUrl().toExternalForm(), is("https://github.com/baxterthehacker/public-repo")); assertThat(event.getPusher().getName(), is("baxterthehacker")); assertThat(event.getPusher().getEmail(), is("baxterthehacker@users.noreply.github.com")); diff --git a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json index 44ba0bbdb..11477e0bb 100644 --- a/src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json +++ b/src/test/resources/org/kohsuke/github/GHEventPayloadTest/push.json @@ -64,23 +64,8 @@ "name": "public-repo", "full_name": "baxterthehacker/public-repo", "owner": { - "login": "baxterthehacker", - "id": 6752317, - "avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3", - "gravatar_id": "", - "url": "https://api.github.com/users/baxterthehacker", - "html_url": "https://github.com/baxterthehacker", - "followers_url": "https://api.github.com/users/baxterthehacker/followers", - "following_url": "https://api.github.com/users/baxterthehacker/following{/other_user}", - "gists_url": "https://api.github.com/users/baxterthehacker/gists{/gist_id}", - "starred_url": "https://api.github.com/users/baxterthehacker/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/baxterthehacker/subscriptions", - "organizations_url": "https://api.github.com/users/baxterthehacker/orgs", - "repos_url": "https://api.github.com/users/baxterthehacker/repos", - "events_url": "https://api.github.com/users/baxterthehacker/events{/privacy}", - "received_events_url": "https://api.github.com/users/baxterthehacker/received_events", - "type": "User", - "site_admin": false + "name": "baxterthehacker", + "email": "baxterthehacker@users.noreply.github.com" }, "private": false, "html_url": "https://github.com/baxterthehacker/public-repo", From def3a28fb5ef091d69a0057ef6eee2a32d9e610a Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 16 Nov 2016 18:18:45 -0800 Subject: [PATCH 103/118] Restoring backward compatibility of names --- src/main/java/org/kohsuke/github/GHRepository.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index f595bf632..f98d9380c 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -358,7 +358,7 @@ public class GHRepository extends GHObject { * Returns the number of all forks of this repository. * This not only counts direct forks, but also forks of forks, and so on. */ - public int getForksCount() { + public int getForks() { return forks_count; } @@ -378,7 +378,7 @@ public class GHRepository extends GHObject { return has_pages; } - public int getWatchersCount() { + public int getWatchers() { return watchers_count; } @@ -386,6 +386,15 @@ public class GHRepository extends GHObject { return open_issues_count; } + /** + * @deprecated + * This no longer exists in the official API documentation. + * Use {@link #getForks()} + */ + public int getNetworkCount() { + return forks_count; + } + public int getSubscribersCount() { return subscribers_count; } From 818f6dc045c3fc30dcc19bd5d0250e889e9c0ba0 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 16 Nov 2016 18:26:43 -0800 Subject: [PATCH 104/118] Issue #309: Added user listing --- src/main/java/org/kohsuke/github/GitHub.java | 17 +++++++++++++++++ .../java/org/kohsuke/github/GitHubTest.java | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index cb446e1fe..2a54626f2 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -392,6 +392,23 @@ public class GitHub { }; } + /** + * Returns a list of all users. + */ + public PagedIterable listUsers() throws IOException { + return new PagedIterable() { + public PagedIterator _iterator(int pageSize) { + return new PagedIterator(retrieve().asIterator("/users", GHUser[].class, pageSize)) { + @Override + protected void wrapUp(GHUser[] page) { + for (GHUser u : page) + u.wrapUp(GitHub.this); + } + }; + } + }; + } + /** * Returns the full details for a license * diff --git a/src/test/java/org/kohsuke/github/GitHubTest.java b/src/test/java/org/kohsuke/github/GitHubTest.java index fe6faefac..010adc8b2 100644 --- a/src/test/java/org/kohsuke/github/GitHubTest.java +++ b/src/test/java/org/kohsuke/github/GitHubTest.java @@ -7,6 +7,8 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; import org.junit.Test; import static org.hamcrest.CoreMatchers.notNullValue; @@ -145,4 +147,13 @@ public class GitHubTest { assertTrue(ioe.getMessage().contains("private mode enabled")); } } + + @Test + public void listUsers() throws IOException { + GitHub hub = GitHub.connect(); + for (GHUser u : Iterables.limit(hub.listUsers(),10)) { + assert u.getName()!=null; + System.out.println(u.getName()); + } + } } From 85aa2ad4e6df8dba05950154b6e4e496891b7e78 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 16 Nov 2016 19:10:37 -0800 Subject: [PATCH 105/118] Added reaction API --- .../org/kohsuke/github/GHCommitComment.java | 27 ++++++++- src/main/java/org/kohsuke/github/GHIssue.java | 27 ++++++++- .../org/kohsuke/github/GHIssueComment.java | 29 +++++++++- .../github/GHPullRequestReviewComment.java | 27 ++++++++- .../java/org/kohsuke/github/GHReaction.java | 55 +++++++++++++++++++ .../java/org/kohsuke/github/Previews.java | 1 + .../java/org/kohsuke/github/Reactable.java | 23 ++++++++ .../org/kohsuke/github/ReactionContent.java | 40 ++++++++++++++ src/test/java/org/kohsuke/github/AppTest.java | 15 +++++ 9 files changed, 239 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/kohsuke/github/GHReaction.java create mode 100644 src/main/java/org/kohsuke/github/Reactable.java create mode 100644 src/main/java/org/kohsuke/github/ReactionContent.java diff --git a/src/main/java/org/kohsuke/github/GHCommitComment.java b/src/main/java/org/kohsuke/github/GHCommitComment.java index 79f19a6e6..3543b5fdb 100644 --- a/src/main/java/org/kohsuke/github/GHCommitComment.java +++ b/src/main/java/org/kohsuke/github/GHCommitComment.java @@ -5,6 +5,8 @@ import java.io.IOException; import java.net.URL; import java.util.Date; +import static org.kohsuke.github.Previews.SQUIRREL_GIRL; + /** * A comment attached to a commit (or a specific line in a specific file of a commit.) * @@ -15,7 +17,7 @@ import java.util.Date; */ @SuppressFBWarnings(value = {"UWF_UNWRITTEN_PUBLIC_OR_PROTECTED_FIELD", "UWF_UNWRITTEN_FIELD", "NP_UNWRITTEN_FIELD"}, justification = "JSON API") -public class GHCommitComment extends GHObject { +public class GHCommitComment extends GHObject implements Reactable { private GHRepository owner; String body, html_url, commit_id; @@ -86,6 +88,29 @@ public class GHCommitComment extends GHObject { this.body = body; } + @Preview @Deprecated + public GHReaction createReaction(ReactionContent content) throws IOException { + return new Requester(owner.root) + .withPreview(SQUIRREL_GIRL) + .with("content", content.getContent()) + .to(getApiTail()+"/reactions", GHReaction.class).wrap(owner.root); + } + + @Preview @Deprecated + public PagedIterable listReactions() { + return new PagedIterable() { + public PagedIterator _iterator(int pageSize) { + return new PagedIterator(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiTail()+"/reactions", GHReaction[].class, pageSize)) { + @Override + protected void wrapUp(GHReaction[] page) { + for (GHReaction c : page) + c.wrap(owner.root); + } + }; + } + }; + } + /** * Deletes this comment. */ diff --git a/src/main/java/org/kohsuke/github/GHIssue.java b/src/main/java/org/kohsuke/github/GHIssue.java index a5afad6d2..f02439daa 100644 --- a/src/main/java/org/kohsuke/github/GHIssue.java +++ b/src/main/java/org/kohsuke/github/GHIssue.java @@ -35,6 +35,8 @@ import java.util.Date; import java.util.List; import java.util.Locale; +import static org.kohsuke.github.Previews.SQUIRREL_GIRL; + /** * Represents an issue on GitHub. * @@ -44,7 +46,7 @@ import java.util.Locale; * @see GitHub#searchIssues() * @see GHIssueSearchBuilder */ -public class GHIssue extends GHObject { +public class GHIssue extends GHObject implements Reactable{ GitHub root; GHRepository owner; @@ -217,6 +219,29 @@ public class GHIssue extends GHObject { }; } + @Preview @Deprecated + public GHReaction createReaction(ReactionContent content) throws IOException { + return new Requester(owner.root) + .withPreview(SQUIRREL_GIRL) + .with("content", content.getContent()) + .to(getApiRoute()+"/reactions", GHReaction.class).wrap(root); + } + + @Preview @Deprecated + public PagedIterable listReactions() { + return new PagedIterable() { + public PagedIterator _iterator(int pageSize) { + return new PagedIterator(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute()+"/reactions", GHReaction[].class, pageSize)) { + @Override + protected void wrapUp(GHReaction[] page) { + for (GHReaction c : page) + c.wrap(owner.root); + } + }; + } + }; + } + protected String getApiRoute() { return getIssuesApiRoute(); } diff --git a/src/main/java/org/kohsuke/github/GHIssueComment.java b/src/main/java/org/kohsuke/github/GHIssueComment.java index 18d08bc7f..a98f6f639 100644 --- a/src/main/java/org/kohsuke/github/GHIssueComment.java +++ b/src/main/java/org/kohsuke/github/GHIssueComment.java @@ -26,12 +26,14 @@ package org.kohsuke.github; import java.io.IOException; import java.net.URL; +import static org.kohsuke.github.Previews.SQUIRREL_GIRL; + /** * Comment to the issue * * @author Kohsuke Kawaguchi */ -public class GHIssueComment extends GHObject { +public class GHIssueComment extends GHObject implements Reactable { GHIssue owner; private String body, gravatar_id; @@ -93,7 +95,30 @@ public class GHIssueComment extends GHObject { public void delete() throws IOException { new Requester(owner.root).method("DELETE").to(getApiRoute()); } - + + @Preview @Deprecated + public GHReaction createReaction(ReactionContent content) throws IOException { + return new Requester(owner.root) + .withPreview(SQUIRREL_GIRL) + .with("content", content.getContent()) + .to(getApiRoute()+"/reactions", GHReaction.class).wrap(owner.root); + } + + @Preview @Deprecated + public PagedIterable listReactions() { + return new PagedIterable() { + public PagedIterator _iterator(int pageSize) { + return new PagedIterator(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute()+"/reactions", GHReaction[].class, pageSize)) { + @Override + protected void wrapUp(GHReaction[] page) { + for (GHReaction c : page) + c.wrap(owner.root); + } + }; + } + }; + } + private String getApiRoute() { return "/repos/"+owner.getRepository().getOwnerName()+"/"+owner.getRepository().getName()+"/issues/comments/" + id; } diff --git a/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java b/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java index 8cb497e16..05784b507 100644 --- a/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java +++ b/src/main/java/org/kohsuke/github/GHPullRequestReviewComment.java @@ -26,6 +26,8 @@ package org.kohsuke.github; import java.io.IOException; import java.net.URL; +import static org.kohsuke.github.Previews.*; + /** * Review comment to the pull request * @@ -33,7 +35,7 @@ import java.net.URL; * @see GHPullRequest#listReviewComments() * @see GHPullRequest#createReviewComment(String, String, String, int) */ -public class GHPullRequestReviewComment extends GHObject { +public class GHPullRequestReviewComment extends GHObject implements Reactable { GHPullRequest owner; private String body; @@ -103,4 +105,27 @@ public class GHPullRequestReviewComment extends GHObject { public void delete() throws IOException { new Requester(owner.root).method("DELETE").to(getApiRoute()); } + + @Preview @Deprecated + public GHReaction createReaction(ReactionContent content) throws IOException { + return new Requester(owner.root) + .withPreview(SQUIRREL_GIRL) + .with("content", content.getContent()) + .to(getApiRoute()+"/reactions", GHReaction.class).wrap(owner.root); + } + + @Preview @Deprecated + public PagedIterable listReactions() { + return new PagedIterable() { + public PagedIterator _iterator(int pageSize) { + return new PagedIterator(owner.root.retrieve().withPreview(SQUIRREL_GIRL).asIterator(getApiRoute()+"/reactions", GHReaction[].class, pageSize)) { + @Override + protected void wrapUp(GHReaction[] page) { + for (GHReaction c : page) + c.wrap(owner.root); + } + }; + } + }; + } } diff --git a/src/main/java/org/kohsuke/github/GHReaction.java b/src/main/java/org/kohsuke/github/GHReaction.java new file mode 100644 index 000000000..55b26365e --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHReaction.java @@ -0,0 +1,55 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; + +import static org.kohsuke.github.Previews.SQUIRREL_GIRL; + +/** + * Reaction to issue, comment, PR, and so on. + * + * @author Kohsuke Kawaguchi + * @see Reactable + */ +@Preview @Deprecated +public class GHReaction extends GHObject { + private GitHub root; + + private GHUser user; + private ReactionContent content; + + /*package*/ GHReaction wrap(GitHub root) { + this.root = root; + user.wrapUp(root); + return this; + } + + /** + * The kind of reaction left. + */ + public ReactionContent getContent() { + return content; + } + + /** + * User who left the reaction. + */ + public GHUser getUser() { + return user; + } + + /** + * Reaction has no HTML URL. Don't call this method. + */ + @Deprecated + public URL getHtmlUrl() { + return null; + } + + /** + * Removes this reaction. + */ + public void delete() throws IOException { + new Requester(root).method("DELETE").withPreview(SQUIRREL_GIRL).to("/reactions/"+id); + } +} diff --git a/src/main/java/org/kohsuke/github/Previews.java b/src/main/java/org/kohsuke/github/Previews.java index a5d061cbd..f95a28b42 100644 --- a/src/main/java/org/kohsuke/github/Previews.java +++ b/src/main/java/org/kohsuke/github/Previews.java @@ -6,4 +6,5 @@ package org.kohsuke.github; /*package*/ class Previews { static final String LOKI = "application/vnd.github.loki-preview+json"; static final String DRAX = "application/vnd.github.drax-preview+json"; + static final String SQUIRREL_GIRL = "application/vnd.github.squirrel-girl-preview"; } diff --git a/src/main/java/org/kohsuke/github/Reactable.java b/src/main/java/org/kohsuke/github/Reactable.java new file mode 100644 index 000000000..d8821362c --- /dev/null +++ b/src/main/java/org/kohsuke/github/Reactable.java @@ -0,0 +1,23 @@ +package org.kohsuke.github; + +import java.io.IOException; + +/** + * Those {@link GHObject}s that can have {@linkplain GHReaction reactions}. + * + * @author Kohsuke Kawaguchi + */ +@Preview @Deprecated +public interface Reactable { + /** + * List all the reactions left to this object. + */ + @Preview @Deprecated + PagedIterable listReactions(); + + /** + * Leaves a reaction to this object. + */ + @Preview @Deprecated + GHReaction createReaction(ReactionContent content) throws IOException; +} diff --git a/src/main/java/org/kohsuke/github/ReactionContent.java b/src/main/java/org/kohsuke/github/ReactionContent.java new file mode 100644 index 000000000..57a204b56 --- /dev/null +++ b/src/main/java/org/kohsuke/github/ReactionContent.java @@ -0,0 +1,40 @@ +package org.kohsuke.github; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +/** + * Content of reactions. + * + * @author Kohsuke Kawaguchi + * @see API documentation + * @see GHReaction + */ +public enum ReactionContent { + PLUS_ONE("+1"), + MINUS_ONE("-1"), + LAUGH("laugh"), + CONFUSED("confused"), + HEART("heart"), + HOORAY("hooray"); + + private final String content; + + ReactionContent(String content) { + this.content = content; + } + + @JsonValue + public String getContent() { + return content; + } + + @JsonCreator + public static ReactionContent forContent(String content) { + for (ReactionContent c : ReactionContent.values()) { + if (c.getContent().equals(content)) + return c; + } + return null; + } +} diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 5a2758257..15f4ba9c7 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -870,6 +870,21 @@ public class AppTest extends AbstractGitHubApiTestBase { System.out.println(r.getIssue(1)); } + @Test + public void reactions() throws Exception { + GHIssue i = gitHub.getRepository("kohsuke/github-api").getIssue(311); + + // retrieval + GHReaction r = i.listReactions().iterator().next(); + assert r.getUser().getName().equals("kohsuke"); + assert r.getContent()==ReactionContent.HEART; + + // CRUD + GHReaction a = i.createReaction(ReactionContent.HOORAY); + assert a.getUser().equals(gitHub.getMyself()); + a.delete(); + } + private void kohsuke() { String login = getUser().getLogin(); Assume.assumeTrue(login.equals("kohsuke") || login.equals("kohsuke2")); From 18e797095fc3eaaabf8d933b8810a9dd1fa27cbc Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 16 Nov 2016 22:36:16 -0800 Subject: [PATCH 106/118] rewrote assert with JUnit ones --- src/test/java/org/kohsuke/github/AppTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 15f4ba9c7..724678112 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -5,6 +5,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.apache.commons.io.IOUtils; +import org.hamcrest.CoreMatchers; import org.junit.Assume; import org.junit.Test; import org.kohsuke.github.GHCommit.File; @@ -17,6 +18,8 @@ import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.regex.Pattern; +import static org.hamcrest.CoreMatchers.*; + /** * Unit test for simple App. */ @@ -876,12 +879,12 @@ public class AppTest extends AbstractGitHubApiTestBase { // retrieval GHReaction r = i.listReactions().iterator().next(); - assert r.getUser().getName().equals("kohsuke"); - assert r.getContent()==ReactionContent.HEART; + assertThat(r.getUser().getLogin(), is("kohsuke")); + assertThat(r.getContent(),is(ReactionContent.HEART)); // CRUD GHReaction a = i.createReaction(ReactionContent.HOORAY); - assert a.getUser().equals(gitHub.getMyself()); + assertThat(a.getUser().getLogin(),is(gitHub.getMyself().getLogin())); a.delete(); } From 129651479412362a4cbbc9e7b93e579e43d39b9e Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 16 Nov 2016 22:49:13 -0800 Subject: [PATCH 107/118] this field is not yet used --- src/main/java/org/kohsuke/github/GHAuthorization.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHAuthorization.java b/src/main/java/org/kohsuke/github/GHAuthorization.java index ead866bb0..2a9fa3909 100644 --- a/src/main/java/org/kohsuke/github/GHAuthorization.java +++ b/src/main/java/org/kohsuke/github/GHAuthorization.java @@ -109,6 +109,6 @@ public class GHAuthorization extends GHObject { private static class App { private String url; private String name; - private String client_id; + // private String client_id; not yet used } } From b0e0f045f858156d24100e5e78751afe54040789 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 16 Nov 2016 22:52:10 -0800 Subject: [PATCH 108/118] [maven-release-plugin] prepare release github-api-1.80 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8d018c1a2..97328ce89 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.80-SNAPSHOT + 1.80 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.80 From c7f2228a44aaee340ac0796842cf80d3d66f7140 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 16 Nov 2016 22:52:14 -0800 Subject: [PATCH 109/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 97328ce89..cd302f7cd 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.80 + 1.81-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.80 + HEAD From 47fc813027055cc5b8b53c12828eb650d684e9f1 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 19 Nov 2016 14:29:27 -0800 Subject: [PATCH 110/118] Assignees of the repository. (Personally this concept makes no sense for me, so I don't know what this API really does. I'm just following their API docs) --- .../java/org/kohsuke/github/GHRepository.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index fdd39b8d4..cc25c8600 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -469,6 +469,21 @@ public class GHRepository extends GHObject { } + /** + * Lists all the available assignees + * to which issues may be assigned. + */ + public PagedIterable listAssignees() throws IOException { + return listUsers("assignees"); + } + + /** + * Checks if the given user is an assignee for this repository. + */ + public boolean hasAssignee(GHUser u) throws IOException { + return root.retrieve().asHttpStatusCode(getApiTailUrl("assignees/" + u.getLogin()))/100==2; + } + /** * Gets the names of the collaborators on this repository. * This method deviates from the principle of this library but it works a lot faster than {@link #getCollaborators()}. From b8bfddbf3a523557c97d3bafddca50102b53e982 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 19 Nov 2016 14:30:35 -0800 Subject: [PATCH 111/118] Code simplification --- .../java/org/kohsuke/github/GHRepository.java | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHRepository.java b/src/main/java/org/kohsuke/github/GHRepository.java index cc25c8600..f34ea8500 100644 --- a/src/main/java/org/kohsuke/github/GHRepository.java +++ b/src/main/java/org/kohsuke/github/GHRepository.java @@ -50,8 +50,8 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; -import static java.util.Arrays.asList; -import static org.kohsuke.github.Previews.DRAX; +import static java.util.Arrays.*; +import static org.kohsuke.github.Previews.*; /** * A repository on GitHub. @@ -451,22 +451,7 @@ public class GHRepository extends GHObject { * @throws IOException */ public PagedIterable listCollaborators() throws IOException { - return new PagedIterable() { - public PagedIterator _iterator(int pageSize) { - - return new PagedIterator(root.retrieve().asIterator(getApiTailUrl("collaborators"), GHUser[].class, pageSize)) { - - @Override - protected void wrapUp(GHUser[] users) { - for (GHUser user : users) { - user.wrapUp(root); - } - } - }; - - } - }; - + return listUsers("collaborators"); } /** From a1528a1a63ced24f6f042a1e0b5bfba368f16950 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 19 Nov 2016 14:48:43 -0800 Subject: [PATCH 112/118] API to add/set/remove assignees from an issue --- src/main/java/org/kohsuke/github/GHIssue.java | 50 +++++++++++++++++-- .../java/org/kohsuke/github/Requester.java | 15 +++++- 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHIssue.java b/src/main/java/org/kohsuke/github/GHIssue.java index f02439daa..849d4831f 100644 --- a/src/main/java/org/kohsuke/github/GHIssue.java +++ b/src/main/java/org/kohsuke/github/GHIssue.java @@ -29,13 +29,15 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.IOException; import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Locale; -import static org.kohsuke.github.Previews.SQUIRREL_GIRL; +import static org.kohsuke.github.Previews.*; /** * Represents an issue on GitHub. @@ -51,7 +53,8 @@ public class GHIssue extends GHObject implements Reactable{ GHRepository owner; // API v3 - protected GHUser assignee; + protected GHUser assignee; // not sure what this field is now that 'assignees' exist + protected GHUser[] assignees; protected String state; protected int number; protected String closed_at; @@ -81,6 +84,7 @@ public class GHIssue extends GHObject implements Reactable{ /*package*/ GHIssue wrap(GitHub root) { this.root = root; if(assignee != null) assignee.wrapUp(root); + if(assignees!=null) GHUser.wrap(assignees,root); if(user != null) user.wrapUp(root); if(closed_by != null) closed_by.wrapUp(root); return this; @@ -187,7 +191,7 @@ public class GHIssue extends GHObject implements Reactable{ } public void assignTo(GHUser user) throws IOException { - editIssue("assignee", user.getLogin()); + setAssignees(user); } public void setLabels(String... labels) throws IOException { @@ -242,6 +246,40 @@ public class GHIssue extends GHObject implements Reactable{ }; } + public void addAssignees(GHUser... assignees) throws IOException { + addAssignees(Arrays.asList(assignees)); + } + + public void addAssignees(Collection assignees) throws IOException { + List names = toLogins(assignees); + root.retrieve().method("POST").with("assignees",names).to(getIssuesApiRoute()+"/assignees",this); + } + + public void setAssignees(GHUser... assignees) throws IOException { + setAssignees(Arrays.asList(assignees)); + } + + public void setAssignees(Collection assignees) throws IOException { + editIssue("assignees",toLogins(assignees)); + } + + public void removeAssignees(GHUser... assignees) throws IOException { + removeAssignees(Arrays.asList(assignees)); + } + + public void removeAssignees(Collection assignees) throws IOException { + List names = toLogins(assignees); + root.retrieve().method("DELETE").with("assignees",names).inBody().to(getIssuesApiRoute()+"/assignees",this); + } + + private List toLogins(Collection assignees) { + List names = new ArrayList(assignees.size()); + for (GHUser a : assignees) { + names.add(a.getLogin()); + } + return names; + } + protected String getApiRoute() { return getIssuesApiRoute(); } @@ -253,7 +291,11 @@ public class GHIssue extends GHObject implements Reactable{ public GHUser getAssignee() { return assignee; } - + + public List getAssignees() { + return Collections.unmodifiableList(Arrays.asList(assignees)); + } + /** * User who submitted the issue. */ diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 6175191ea..3d240abd6 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -81,6 +81,7 @@ class Requester { * Current connection. */ private HttpURLConnection uc; + private boolean forceBody; private static class Entry { String key; @@ -197,6 +198,16 @@ class Requester { return this; } + /** + * Small number of GitHub APIs use HTTP methods somewhat inconsistently, and use a body where it's not expected. + * Normally whether parameters go as query parameters or a body depends on the HTTP verb in use, + * but this method forces the parameters to be sent as a body. + */ + /*package*/ Requester inBody() { + forceBody = true; + return this; + } + public void to(String tailApiUrl) throws IOException { to(tailApiUrl,null); } @@ -230,7 +241,7 @@ class Requester { @SuppressFBWarnings("SBSC_USE_STRINGBUFFER_CONCATENATION") private T _to(String tailApiUrl, Class type, T instance) throws IOException { - if (METHODS_WITHOUT_BODY.contains(method) && !args.isEmpty()) { + if (!isMethodWithBody() && !args.isEmpty()) { boolean questionMarkFound = tailApiUrl.indexOf('?') != -1; tailApiUrl += questionMarkFound ? '&' : '?'; for (Iterator it = args.listIterator(); it.hasNext();) { @@ -340,7 +351,7 @@ class Requester { } private boolean isMethodWithBody() { - return !METHODS_WITHOUT_BODY.contains(method); + return forceBody || !METHODS_WITHOUT_BODY.contains(method); } /** From 3f223b1ba079882d16303595a215457d08a5a3b6 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 19 Nov 2016 14:50:47 -0800 Subject: [PATCH 113/118] Support assignees when creating a new issue --- src/main/java/org/kohsuke/github/GHIssueBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHIssueBuilder.java b/src/main/java/org/kohsuke/github/GHIssueBuilder.java index 385fcd04a..3a5a53230 100644 --- a/src/main/java/org/kohsuke/github/GHIssueBuilder.java +++ b/src/main/java/org/kohsuke/github/GHIssueBuilder.java @@ -11,6 +11,7 @@ public class GHIssueBuilder { private final GHRepository repo; private final Requester builder; private List labels = new ArrayList(); + private List assignees = new ArrayList(); GHIssueBuilder(GHRepository repo, String title) { this.repo = repo; @@ -28,13 +29,13 @@ public class GHIssueBuilder { public GHIssueBuilder assignee(GHUser user) { if (user!=null) - builder.with("assignee",user.getLogin()); + assignees.add(user.getLogin()); return this; } public GHIssueBuilder assignee(String user) { if (user!=null) - builder.with("assignee",user); + assignees.add(user); return this; } @@ -54,6 +55,6 @@ public class GHIssueBuilder { * Creates a new issue. */ public GHIssue create() throws IOException { - return builder.with("labels",labels).to(repo.getApiTailUrl("issues"),GHIssue.class).wrap(repo); + return builder.with("labels",labels).with("assignees",assignees).to(repo.getApiTailUrl("issues"),GHIssue.class).wrap(repo); } } From 511f156603500f659e86343add60496ebd50fb11 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 19 Nov 2016 15:26:04 -0800 Subject: [PATCH 114/118] Added the membership API for the authenticated user. --- .../java/org/kohsuke/github/GHMembership.java | 84 +++++++++++++++++++ .../java/org/kohsuke/github/GHMyself.java | 33 ++++++++ src/main/java/org/kohsuke/github/GHUser.java | 5 ++ src/main/java/org/kohsuke/github/GitHub.java | 2 +- src/test/java/org/kohsuke/github/AppTest.java | 15 ++++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/kohsuke/github/GHMembership.java diff --git a/src/main/java/org/kohsuke/github/GHMembership.java b/src/main/java/org/kohsuke/github/GHMembership.java new file mode 100644 index 000000000..2847e1891 --- /dev/null +++ b/src/main/java/org/kohsuke/github/GHMembership.java @@ -0,0 +1,84 @@ +package org.kohsuke.github; + +import java.io.IOException; +import java.net.URL; +import java.util.Locale; + +/** + * Represents a membership of a user in an organization. + * + * @author Kohsuke Kawaguchi + * @see GHMyself#listOrgMemberships() + */ +public class GHMembership /* extends GHObject --- but it doesn't have id, created_at, etc. */ { + GitHub root; + + String url; + String state; + String role; + GHUser user; + GHOrganization organization; + + public URL getUrl() { + return GitHub.parseURL(url); + } + + public State getState() { + return Enum.valueOf(State.class, state.toUpperCase(Locale.ENGLISH)); + } + + public Role getRole() { + return Enum.valueOf(Role.class, role.toUpperCase(Locale.ENGLISH)); + } + + public GHUser getUser() { + return user; + } + + public GHOrganization getOrganization() { + return organization; + } + + /** + * Accepts a pending invitation to an organization. + * + * @see GHMyself#getMembership(GHOrganization) + */ + public void activate() throws IOException { + root.retrieve().method("PATCH").with("state",State.ACTIVE).to(url,this); + } + + /*package*/ GHMembership wrap(GitHub root) { + this.root = root; + if (user!=null) user = root.getUser(user.wrapUp(root)); + if (organization!=null) organization.wrapUp(root); + return this; + } + + /*package*/ static void wrap(GHMembership[] page, GitHub root) { + for (GHMembership m : page) + m.wrap(root); + } + + /** + * Role of a user in an organization. + */ + public enum Role { + /** + * Organization owner. + */ + ADMIN, + /** + * Non-owner organization member. + */ + MEMBER; + } + + /** + * Whether a role is currently active or waiting for acceptance (pending) + */ + public enum State { + ACTIVE, + PENDING; + } +} diff --git a/src/main/java/org/kohsuke/github/GHMyself.java b/src/main/java/org/kohsuke/github/GHMyself.java index c7ae80dd7..cc05f03bc 100644 --- a/src/main/java/org/kohsuke/github/GHMyself.java +++ b/src/main/java/org/kohsuke/github/GHMyself.java @@ -178,6 +178,39 @@ public class GHMyself extends GHUser { return listRepositories(); } + /** + * List your organization memberships + */ + public PagedIterable listOrgMemberships() { + return listOrgMemberships(null); + } + + /** + * List your organization memberships + * + * @param state + * Filter by a specific state + */ + public PagedIterable listOrgMemberships(final GHMembership.State state) { + return new PagedIterable() { + public PagedIterator _iterator(int pageSize) { + return new PagedIterator(root.retrieve().with("state",state).asIterator("/user/memberships/orgs", GHMembership[].class, pageSize)) { + @Override + protected void wrapUp(GHMembership[] page) { + GHMembership.wrap(page,root); + } + }; + } + }; + } + + /** + * Gets your membership in a specific organization. + */ + public GHMembership getMembership(GHOrganization o) throws IOException { + return root.retrieve().to("/user/memberships/orgs/"+o.getLogin(),GHMembership.class).wrap(root); + } + // public void addEmails(Collection emails) throws IOException { //// new Requester(root,ApiVersion.V3).withCredential().to("/user/emails"); // root.retrieveWithAuth3() diff --git a/src/main/java/org/kohsuke/github/GHUser.java b/src/main/java/org/kohsuke/github/GHUser.java index 790f24ec2..77beb11b8 100644 --- a/src/main/java/org/kohsuke/github/GHUser.java +++ b/src/main/java/org/kohsuke/github/GHUser.java @@ -214,4 +214,9 @@ public class GHUser extends GHPerson { if (tail.length()>0 && !tail.startsWith("/")) tail='/'+tail; return "/users/" + login + tail; } + + /*package*/ GHUser wrapUp(GitHub root) { + super.wrapUp(root); + return this; + } } diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 2a54626f2..b50b2234e 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -340,7 +340,7 @@ public class GitHub { /** * Interns the given {@link GHUser}. */ - protected GHUser getUser(GHUser orig) throws IOException { + protected GHUser getUser(GHUser orig) { GHUser u = users.get(orig.getLogin()); if (u==null) { orig.root = this; diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 724678112..0a958418b 100755 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -888,6 +888,21 @@ public class AppTest extends AbstractGitHubApiTestBase { a.delete(); } + @Test + public void listOrgMemberships() throws Exception { + GHMyself me = gitHub.getMyself(); + for (GHMembership m : me.listOrgMemberships()) { + assertThat(m.getUser(), is((GHUser)me)); + assertNotNull(m.getState()); + assertNotNull(m.getRole()); + + System.out.printf("%s %s %s\n", + m.getOrganization().getLogin(), + m.getState(), + m.getRole()); + } + } + private void kohsuke() { String login = getUser().getLogin(); Assume.assumeTrue(login.equals("kohsuke") || login.equals("kohsuke2")); From 0023ecefa4004180c86757042c96e92009022285 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 21 Nov 2016 08:53:38 -0800 Subject: [PATCH 115/118] [maven-release-plugin] prepare release github-api-1.81 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index cd302f7cd..a2254c512 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.81-SNAPSHOT + 1.81 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - HEAD + github-api-1.81 From a1df526f937efae5e6290e4b4a45d54e1a761131 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Mon, 21 Nov 2016 08:53:42 -0800 Subject: [PATCH 116/118] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a2254c512..df146ab5c 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.81 + 1.82-SNAPSHOT GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java @@ -16,7 +16,7 @@ scm:git:git@github.com/kohsuke/${project.artifactId}.git scm:git:ssh://git@github.com/kohsuke/${project.artifactId}.git http://${project.artifactId}.kohsuke.org/ - github-api-1.81 + HEAD From 68ebc08c9d8bfdc48253f265c2c1484fd28e678b Mon Sep 17 00:00:00 2001 From: David Xia Date: Sat, 26 Nov 2016 00:44:52 -0500 Subject: [PATCH 117/118] Fix typos in javadocs Replace "pagenated" with "paginated". --- src/main/java/org/kohsuke/github/GHPerson.java | 4 ++-- src/main/java/org/kohsuke/github/PagedIterator.java | 2 +- src/main/java/org/kohsuke/github/Requester.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHPerson.java b/src/main/java/org/kohsuke/github/GHPerson.java index 67e157173..f9872699c 100644 --- a/src/main/java/org/kohsuke/github/GHPerson.java +++ b/src/main/java/org/kohsuke/github/GHPerson.java @@ -93,10 +93,10 @@ public abstract class GHPerson extends GHObject { } /** - * Loads repository list in a pagenated fashion. + * Loads repository list in a paginated fashion. * *

- * For a person with a lot of repositories, GitHub returns the list of repositories in a pagenated fashion. + * For a person with a lot of repositories, GitHub returns the list of repositories in a paginated fashion. * Unlike {@link #getRepositories()}, this method allows the caller to start processing data as it arrives. * * Every {@link Iterator#next()} call results in I/O. Exceptions that occur during the processing is wrapped diff --git a/src/main/java/org/kohsuke/github/PagedIterator.java b/src/main/java/org/kohsuke/github/PagedIterator.java index 914929091..aaa818207 100644 --- a/src/main/java/org/kohsuke/github/PagedIterator.java +++ b/src/main/java/org/kohsuke/github/PagedIterator.java @@ -6,7 +6,7 @@ import java.util.List; import java.util.NoSuchElementException; /** - * Iterator over a pagenated data source. + * Iterator over a paginated data source. * * Aside from the normal iterator operation, this method exposes {@link #nextPage()} * that allows the caller to retrieve items per page. diff --git a/src/main/java/org/kohsuke/github/Requester.java b/src/main/java/org/kohsuke/github/Requester.java index 3d240abd6..70c48940c 100644 --- a/src/main/java/org/kohsuke/github/Requester.java +++ b/src/main/java/org/kohsuke/github/Requester.java @@ -355,7 +355,7 @@ class Requester { } /** - * Loads pagenated resources. + * Loads paginated resources. * * Every iterator call reports a new batch. */ From 0731f63237cc7c09c708db3b83089fa561e361a6 Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Sat, 26 Nov 2016 14:45:03 -0800 Subject: [PATCH 118/118] Added order parameter --- src/main/java/org/kohsuke/github/GHIssueSearchBuilder.java | 5 +++++ .../java/org/kohsuke/github/GHRepositorySearchBuilder.java | 5 +++++ src/main/java/org/kohsuke/github/GHUserSearchBuilder.java | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/main/java/org/kohsuke/github/GHIssueSearchBuilder.java b/src/main/java/org/kohsuke/github/GHIssueSearchBuilder.java index ff574025c..f9634a59f 100644 --- a/src/main/java/org/kohsuke/github/GHIssueSearchBuilder.java +++ b/src/main/java/org/kohsuke/github/GHIssueSearchBuilder.java @@ -41,6 +41,11 @@ public class GHIssueSearchBuilder extends GHSearchBuilder { return q("is:merged"); } + public GHIssueSearchBuilder order(GHDirection v) { + req.with("order",v); + return this; + } + public GHIssueSearchBuilder sort(Sort sort) { req.with("sort",sort); return this; diff --git a/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java b/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java index 8d30aaaf6..03b12f513 100644 --- a/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java +++ b/src/main/java/org/kohsuke/github/GHRepositorySearchBuilder.java @@ -57,6 +57,11 @@ public class GHRepositorySearchBuilder extends GHSearchBuilder { return q("stars:"+v); } + public GHRepositorySearchBuilder order(GHDirection v) { + req.with("order",v); + return this; + } + public GHRepositorySearchBuilder sort(Sort sort) { req.with("sort",sort); return this; diff --git a/src/main/java/org/kohsuke/github/GHUserSearchBuilder.java b/src/main/java/org/kohsuke/github/GHUserSearchBuilder.java index fa5161683..ca40f4d05 100644 --- a/src/main/java/org/kohsuke/github/GHUserSearchBuilder.java +++ b/src/main/java/org/kohsuke/github/GHUserSearchBuilder.java @@ -49,6 +49,11 @@ public class GHUserSearchBuilder extends GHSearchBuilder { return q("followers:"+v); } + public GHUserSearchBuilder order(GHDirection v) { + req.with("order",v); + return this; + } + public GHUserSearchBuilder sort(Sort sort) { req.with("sort",sort); return this;