From 0e3707d1c3d76b372e0efcff0bb1ecbf472b494a Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 2 Jul 2014 21:28:38 -0700 Subject: [PATCH 1/5] [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 79c521c4a4..ed0d45b76a 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.56 + 1.57-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.56 + HEAD From 40780525f85c34c9cfdd83e8f6c8e22dd346affe Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Wed, 2 Jul 2014 21:39:13 -0700 Subject: [PATCH 2/5] Bumping up the version in the hope of fixing site plugin problem --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ed0d45b76a..da8d5573cf 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ org.kohsuke pom - 8 + 9 github-api From 449909b0e8a71347cc029638ab172c36d84348bf Mon Sep 17 00:00:00 2001 From: Luca Milanesio Date: Thu, 3 Jul 2014 10:05:17 +0100 Subject: [PATCH 3/5] Implement pagination on list of private+public repos of a user. The paginated version of listRepositories() was missing at GHMyself: as side-effect of this bug when requesting a paginated list of repositories the ones privately owned by a user were not shown. This was caused by the missing override of the listRepositories(final int pageSize) at GHMyself that caused the GHPerson implementation to invoked. The GHPerson version uses the /users/:org/repos?per_page=x URL which *works fine* for organisations but unfortunately *does not return* private repositories for users. IMHO GitHub API are quite inconsistent form this point of view, but they are documented in this way so that work (inconsistently) as designed. --- src/main/java/org/kohsuke/github/GHMyself.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/kohsuke/github/GHMyself.java b/src/main/java/org/kohsuke/github/GHMyself.java index 06e61f83d3..7b588e88fa 100644 --- a/src/main/java/org/kohsuke/github/GHMyself.java +++ b/src/main/java/org/kohsuke/github/GHMyself.java @@ -101,12 +101,24 @@ public synchronized Map getAllRepositories() throws IOExcep * Lists up all repositories this user owns (public and private). * * Unlike {@link #getAllRepositories()}, this does not wait until all the repositories are returned. + * Repositories are returned by GitHub API with a 30 items per page. */ @Override public PagedIterable listRepositories() { + return listRepositories(30); + } + + /** + * Lists up all the repositories this user owns (public and private) using the specified page size. + * + * @param pageSize size for each page of items returned by GitHub. Maximum page size is 100. + * + * Unlike {@link #getRepositories()}, this does not wait until all the repositories are returned. + */ + public PagedIterable listRepositories(final int pageSize) { return new PagedIterable() { public PagedIterator iterator() { - return new PagedIterator(root.retrieve().asIterator("/user/repos", GHRepository[].class)) { + return new PagedIterator(root.retrieve().asIterator("/user/repos?per_page=" + pageSize, GHRepository[].class)) { @Override protected void wrapUp(GHRepository[] page) { for (GHRepository c : page) From 0b92fa561504ed0232c284c86aee26505646f828 Mon Sep 17 00:00:00 2001 From: Luca Milanesio Date: Thu, 24 Jul 2014 09:15:50 +0100 Subject: [PATCH 4/5] Get all orgs/teams/permissions in a single GitHub API call Exposes a new API call at GitHub root level to build the complete set of organisations and teams that current user belongs to. This change allows to massively reduce the number of calls to GitHub especially for people that belongs to multiple organisations with lots of teams and members. Signed-off-by: Luca Milanesio --- src/main/java/org/kohsuke/github/GHTeam.java | 10 +++++ src/main/java/org/kohsuke/github/GitHub.java | 27 +++++++++++- src/test/java/org/kohsuke/github/AppTest.java | 41 ++++++++++++++----- 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/kohsuke/github/GHTeam.java b/src/main/java/org/kohsuke/github/GHTeam.java index c578130fa6..54b416edd8 100644 --- a/src/main/java/org/kohsuke/github/GHTeam.java +++ b/src/main/java/org/kohsuke/github/GHTeam.java @@ -15,6 +15,7 @@ public class GHTeam { private String name,permission; private int id; + private GHOrganization organization; // populated by GET /user/teams where Teams+Orgs are returned together protected /*final*/ GHOrganization org; @@ -23,6 +24,11 @@ public class GHTeam { return this; } + /*package*/ GHTeam wrapUp(GitHub root) { // auto-wrapUp when organization is known from GET /user/teams + this.organization.wrapUp(root); + return wrapUp(organization); + } + /*package*/ static GHTeam[] wrapUp(GHTeam[] teams, GHOrganization owner) { for (GHTeam t : teams) { t.wrapUp(owner); @@ -95,4 +101,8 @@ public void remove(GHRepository r) throws IOException { private String api(String tail) { return "/teams/"+id+tail; } + + public GHOrganization getOrganization() { + return org; + } } diff --git a/src/main/java/org/kohsuke/github/GitHub.java b/src/main/java/org/kohsuke/github/GitHub.java index 2488c982a2..136daf0df7 100644 --- a/src/main/java/org/kohsuke/github/GitHub.java +++ b/src/main/java/org/kohsuke/github/GitHub.java @@ -23,7 +23,8 @@ */ package org.kohsuke.github; -import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.*; +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.ANY; +import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE; import java.io.File; import java.io.FileInputStream; @@ -38,9 +39,11 @@ import java.util.Collection; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; import java.util.TimeZone; import org.apache.commons.codec.binary.Base64; @@ -328,6 +331,28 @@ public Map getMyOrganizations() throws IOException { return r; } + /** + * Gets complete map of organizations/teams that current user belongs to. + * + * Leverages the new GitHub API /user/teams made available recently to + * get in a single call the complete set of organizations, teams and permissions + * in a single call. + */ + public Map> getMyTeams() throws IOException { + Map> allMyTeams = new HashMap>(); + for (GHTeam team : retrieve().to("/user/teams", GHTeam[].class)) { + team.wrapUp(this); + String orgLogin = team.getOrganization().getLogin(); + Set teamsPerOrg = allMyTeams.get(orgLogin); + if (teamsPerOrg == null) { + teamsPerOrg = new HashSet(); + } + teamsPerOrg.add(team); + allMyTeams.put(orgLogin, teamsPerOrg); + } + return allMyTeams; + } + /** * Public events visible to you. Equivalent of what's displayed on https://github.com/ */ diff --git a/src/test/java/org/kohsuke/github/AppTest.java b/src/test/java/org/kohsuke/github/AppTest.java index 0866a8e93a..07b386314b 100644 --- a/src/test/java/org/kohsuke/github/AppTest.java +++ b/src/test/java/org/kohsuke/github/AppTest.java @@ -3,19 +3,13 @@ import java.io.IOException; import java.net.URL; import java.util.ArrayList; -import java.util.Collection; +import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.UUID; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import org.junit.Assume; import org.junit.Test; import org.kohsuke.github.GHCommit.File; @@ -24,8 +18,6 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; -import java.util.Date; - /** * Unit test for simple App. */ @@ -170,6 +162,35 @@ public void testMyOrganizations() throws IOException { System.out.println(org); } + @Test + public void testMyTeamsContainsAllMyOrganizations() throws IOException { + Map> teams = gitHub.getMyTeams(); + Map myOrganizations = gitHub.getMyOrganizations(); + assertEquals(teams.keySet(), myOrganizations.keySet()); + } + + @Test + public void testMyTeamsShouldIncludeMyself() throws IOException { + Map> teams = gitHub.getMyTeams(); + for (Entry> teamsPerOrg : teams.entrySet()) { + String organizationName = teamsPerOrg.getKey(); + for (GHTeam team : teamsPerOrg.getValue()) { + String teamName = team.getName(); + assertTrue("Team " + teamName + " in organization " + organizationName + + " does not contain myself", + shouldBelongToTeam(organizationName, teamName)); + } + } + } + + private boolean shouldBelongToTeam(String organizationName, String teamName) throws IOException { + GHOrganization org = gitHub.getOrganization(organizationName); + assertNotNull(org); + GHTeam team = org.getTeamByName(teamName); + assertNotNull(team); + return team.hasMember(gitHub.getMyself()); + } + @Test public void testFetchPullRequest() throws Exception { GHRepository r = gitHub.getOrganization("jenkinsci").getRepository("jenkins"); From 7e49946bedf39919f5cc9cb79cfa0b68926b37b6 Mon Sep 17 00:00:00 2001 From: Surya Gaddipati Date: Tue, 19 Aug 2014 13:29:37 -0500 Subject: [PATCH 5/5] [maven-release-plugin] prepare release github-api-1.57 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index da8d5573cf..d976ca838b 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ github-api - 1.57-SNAPSHOT + 1.57 GitHub API for Java http://github-api.kohsuke.org/ GitHub API for Java