Skip to content

Commit cc85d4a

Browse files
committed
Add GitHub#getInstallation to access endpoints related to the authenticated installation
1 parent 319e943 commit cc85d4a

File tree

11 files changed

+559
-0
lines changed

11 files changed

+559
-0
lines changed

src/main/java/org/kohsuke/github/GHAppInstallation.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,15 @@ public String getRepositoriesUrl() {
117117
* List repositories that this app installation can access.
118118
*
119119
* @return the paged iterable
120+
* @deprecated This method cannot work on a {@link GHAppInstallation} retrieved from
121+
* {@link GHApp#listInstallations()} (for example), except when resorting to unsupported hacks involving
122+
* {@link GHAppInstallation#setRoot(GitHub)} to switch from an application client to an installation
123+
* client. This method will be removed. You should instead use an installation client (with an
124+
* installation token, not a JWT), retrieve a {@link GHAuthenticatedAppInstallation} from
125+
* {@link GitHub#getInstallation()}, then call
126+
* {@link GHAuthenticatedAppInstallation#listRepositories()}.
120127
*/
128+
@Deprecated
121129
@Preview(MACHINE_MAN)
122130
public PagedSearchIterable<GHRepository> listRepositories() {
123131
GitHubRequest request;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package org.kohsuke.github;
2+
3+
import javax.annotation.Nonnull;
4+
5+
import static org.kohsuke.github.internal.Previews.MACHINE_MAN;
6+
7+
/**
8+
* The Github App Installation corresponding to the installation token used in a client.
9+
*
10+
* @see GitHub#getInstallation() GitHub#getAuthenticatedAppInstallation()
11+
*/
12+
public class GHAuthenticatedAppInstallation extends GitHubInteractiveObject {
13+
protected GHAuthenticatedAppInstallation(@Nonnull GitHub root) {
14+
super(root);
15+
}
16+
17+
/**
18+
* List repositories that this app installation can access.
19+
*
20+
* @return the paged iterable
21+
*/
22+
@Preview(MACHINE_MAN)
23+
public PagedSearchIterable<GHRepository> listRepositories() {
24+
GitHubRequest request;
25+
26+
request = root().createRequest().withPreview(MACHINE_MAN).withUrlPath("/installation/repositories").build();
27+
28+
return new PagedSearchIterable<>(root(), request, GHAuthenticatedAppInstallationRepositoryResult.class);
29+
}
30+
31+
private static class GHAuthenticatedAppInstallationRepositoryResult extends SearchResult<GHRepository> {
32+
private GHRepository[] repositories;
33+
34+
@Override
35+
GHRepository[] getItems(GitHub root) {
36+
return repositories;
37+
}
38+
}
39+
40+
}

src/main/java/org/kohsuke/github/GitHub.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,6 +1160,22 @@ public GHApp getApp() throws IOException {
11601160
return createRequest().withPreview(MACHINE_MAN).withUrlPath("/app").fetch(GHApp.class);
11611161
}
11621162

1163+
/**
1164+
* Returns the GitHub App Installation associated with the authentication credentials used.
1165+
* <p>
1166+
* You must use an installation token to access this endpoint; otherwise consider {@link #getApp()} and its various
1167+
* ways of retrieving installations.
1168+
*
1169+
* @return the app
1170+
* @throws IOException
1171+
* the io exception
1172+
* @see <a href="https://docs.github.com/en/rest/apps/installations">GitHub App installations</a>
1173+
*/
1174+
@Preview(MACHINE_MAN)
1175+
public GHAuthenticatedAppInstallation getInstallation() throws IOException {
1176+
return new GHAuthenticatedAppInstallation(this);
1177+
}
1178+
11631179
/**
11641180
* Ensures that the credential is valid.
11651181
*
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.kohsuke.github;
2+
3+
import org.junit.Test;
4+
import org.kohsuke.github.authorization.OrgAppInstallationAuthorizationProvider;
5+
6+
import java.io.IOException;
7+
import java.util.List;
8+
9+
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
10+
import static org.hamcrest.Matchers.equalTo;
11+
12+
public class GHAuthenticatedAppInstallationTest extends AbstractGHAppInstallationTest {
13+
14+
@Override
15+
protected GitHubBuilder getGitHubBuilder() {
16+
OrgAppInstallationAuthorizationProvider provider = new OrgAppInstallationAuthorizationProvider("hub4j-test-org",
17+
jwtProvider1);
18+
return super.getGitHubBuilder().withAuthorizationProvider(provider);
19+
}
20+
21+
@Test
22+
public void testListRepositoriesTwoRepos() throws IOException {
23+
GHAuthenticatedAppInstallation appInstallation = gitHub.getInstallation();
24+
25+
List<GHRepository> repositories = appInstallation.listRepositories().toList();
26+
27+
assertThat(repositories.size(), equalTo(2));
28+
assertThat(repositories.stream().map(GHRepository::getName).toArray(),
29+
arrayContainingInAnyOrder("empty", "test-readme"));
30+
}
31+
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"id": 82994,
3+
"slug": "ghapi-test-app-1",
4+
"node_id": "MDM6QXBwODI5OTQ=",
5+
"owner": {
6+
"login": "hub4j-test-org",
7+
"id": 7544739,
8+
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
9+
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
10+
"gravatar_id": "",
11+
"url": "https://api.github.com/users/hub4j-test-org",
12+
"html_url": "https://github.com/hub4j-test-org",
13+
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
14+
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
15+
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
16+
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
17+
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
18+
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
19+
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
20+
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
21+
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
22+
"type": "Organization",
23+
"site_admin": false
24+
},
25+
"name": "GHApi Test app 1",
26+
"description": "",
27+
"external_url": "http://localhost",
28+
"html_url": "https://github.com/apps/ghapi-test-app-1",
29+
"created_at": "2020-09-30T13:40:56Z",
30+
"updated_at": "2020-09-30T13:40:56Z",
31+
"permissions": {
32+
"contents": "read",
33+
"metadata": "read"
34+
},
35+
"events": [],
36+
"installations_count": 1
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
{
2+
"total_count": 2,
3+
"repository_selection": "selected",
4+
"repositories": [
5+
{
6+
"id": 60391080,
7+
"node_id": "MDEwOlJlcG9zaXRvcnk2MDM5MTA4MA==",
8+
"name": "empty",
9+
"full_name": "hub4j-test-org/empty",
10+
"private": false,
11+
"owner": {
12+
"login": "hub4j-test-org",
13+
"id": 7544739,
14+
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
15+
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
16+
"gravatar_id": "",
17+
"url": "https://api.github.com/users/hub4j-test-org",
18+
"html_url": "https://github.com/hub4j-test-org",
19+
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
20+
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
21+
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
22+
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
23+
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
24+
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
25+
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
26+
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
27+
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
28+
"type": "Organization",
29+
"site_admin": false
30+
},
31+
"html_url": "https://github.com/hub4j-test-org/empty",
32+
"description": "Repository that has no contributor",
33+
"fork": false,
34+
"url": "https://api.github.com/repos/hub4j-test-org/empty",
35+
"forks_url": "https://api.github.com/repos/hub4j-test-org/empty/forks",
36+
"keys_url": "https://api.github.com/repos/hub4j-test-org/empty/keys{/key_id}",
37+
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/empty/collaborators{/collaborator}",
38+
"teams_url": "https://api.github.com/repos/hub4j-test-org/empty/teams",
39+
"hooks_url": "https://api.github.com/repos/hub4j-test-org/empty/hooks",
40+
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/empty/issues/events{/number}",
41+
"events_url": "https://api.github.com/repos/hub4j-test-org/empty/events",
42+
"assignees_url": "https://api.github.com/repos/hub4j-test-org/empty/assignees{/user}",
43+
"branches_url": "https://api.github.com/repos/hub4j-test-org/empty/branches{/branch}",
44+
"tags_url": "https://api.github.com/repos/hub4j-test-org/empty/tags",
45+
"blobs_url": "https://api.github.com/repos/hub4j-test-org/empty/git/blobs{/sha}",
46+
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/empty/git/tags{/sha}",
47+
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/empty/git/refs{/sha}",
48+
"trees_url": "https://api.github.com/repos/hub4j-test-org/empty/git/trees{/sha}",
49+
"statuses_url": "https://api.github.com/repos/hub4j-test-org/empty/statuses/{sha}",
50+
"languages_url": "https://api.github.com/repos/hub4j-test-org/empty/languages",
51+
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/empty/stargazers",
52+
"contributors_url": "https://api.github.com/repos/hub4j-test-org/empty/contributors",
53+
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/empty/subscribers",
54+
"subscription_url": "https://api.github.com/repos/hub4j-test-org/empty/subscription",
55+
"commits_url": "https://api.github.com/repos/hub4j-test-org/empty/commits{/sha}",
56+
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/empty/git/commits{/sha}",
57+
"comments_url": "https://api.github.com/repos/hub4j-test-org/empty/comments{/number}",
58+
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/empty/issues/comments{/number}",
59+
"contents_url": "https://api.github.com/repos/hub4j-test-org/empty/contents/{+path}",
60+
"compare_url": "https://api.github.com/repos/hub4j-test-org/empty/compare/{base}...{head}",
61+
"merges_url": "https://api.github.com/repos/hub4j-test-org/empty/merges",
62+
"archive_url": "https://api.github.com/repos/hub4j-test-org/empty/{archive_format}{/ref}",
63+
"downloads_url": "https://api.github.com/repos/hub4j-test-org/empty/downloads",
64+
"issues_url": "https://api.github.com/repos/hub4j-test-org/empty/issues{/number}",
65+
"pulls_url": "https://api.github.com/repos/hub4j-test-org/empty/pulls{/number}",
66+
"milestones_url": "https://api.github.com/repos/hub4j-test-org/empty/milestones{/number}",
67+
"notifications_url": "https://api.github.com/repos/hub4j-test-org/empty/notifications{?since,all,participating}",
68+
"labels_url": "https://api.github.com/repos/hub4j-test-org/empty/labels{/name}",
69+
"releases_url": "https://api.github.com/repos/hub4j-test-org/empty/releases{/id}",
70+
"deployments_url": "https://api.github.com/repos/hub4j-test-org/empty/deployments",
71+
"created_at": "2016-06-04T03:22:22Z",
72+
"updated_at": "2016-06-04T03:22:22Z",
73+
"pushed_at": "2016-06-04T03:22:23Z",
74+
"git_url": "git://github.com/hub4j-test-org/empty.git",
75+
"ssh_url": "[email protected]:hub4j-test-org/empty.git",
76+
"clone_url": "https://github.com/hub4j-test-org/empty.git",
77+
"svn_url": "https://github.com/hub4j-test-org/empty",
78+
"homepage": null,
79+
"size": 0,
80+
"stargazers_count": 0,
81+
"watchers_count": 0,
82+
"language": null,
83+
"has_issues": true,
84+
"has_projects": true,
85+
"has_downloads": true,
86+
"has_wiki": true,
87+
"has_pages": false,
88+
"forks_count": 0,
89+
"mirror_url": null,
90+
"archived": false,
91+
"disabled": false,
92+
"open_issues_count": 0,
93+
"license": null,
94+
"allow_forking": true,
95+
"is_template": false,
96+
"web_commit_signoff_required": false,
97+
"topics": [],
98+
"visibility": "public",
99+
"forks": 0,
100+
"open_issues": 0,
101+
"watchers": 0,
102+
"default_branch": "master",
103+
"permissions": {
104+
"admin": false,
105+
"maintain": false,
106+
"push": false,
107+
"triage": false,
108+
"pull": false
109+
}
110+
},
111+
{
112+
"id": 30829547,
113+
"node_id": "MDEwOlJlcG9zaXRvcnkzMDgyOTU0Nw==",
114+
"name": "test-readme",
115+
"full_name": "hub4j-test-org/test-readme",
116+
"private": false,
117+
"owner": {
118+
"login": "hub4j-test-org",
119+
"id": 7544739,
120+
"node_id": "MDEyOk9yZ2FuaXphdGlvbjc1NDQ3Mzk=",
121+
"avatar_url": "https://avatars.githubusercontent.com/u/7544739?v=4",
122+
"gravatar_id": "",
123+
"url": "https://api.github.com/users/hub4j-test-org",
124+
"html_url": "https://github.com/hub4j-test-org",
125+
"followers_url": "https://api.github.com/users/hub4j-test-org/followers",
126+
"following_url": "https://api.github.com/users/hub4j-test-org/following{/other_user}",
127+
"gists_url": "https://api.github.com/users/hub4j-test-org/gists{/gist_id}",
128+
"starred_url": "https://api.github.com/users/hub4j-test-org/starred{/owner}{/repo}",
129+
"subscriptions_url": "https://api.github.com/users/hub4j-test-org/subscriptions",
130+
"organizations_url": "https://api.github.com/users/hub4j-test-org/orgs",
131+
"repos_url": "https://api.github.com/users/hub4j-test-org/repos",
132+
"events_url": "https://api.github.com/users/hub4j-test-org/events{/privacy}",
133+
"received_events_url": "https://api.github.com/users/hub4j-test-org/received_events",
134+
"type": "Organization",
135+
"site_admin": false
136+
},
137+
"html_url": "https://github.com/hub4j-test-org/test-readme",
138+
"description": "Checks the readme of content",
139+
"fork": false,
140+
"url": "https://api.github.com/repos/hub4j-test-org/test-readme",
141+
"forks_url": "https://api.github.com/repos/hub4j-test-org/test-readme/forks",
142+
"keys_url": "https://api.github.com/repos/hub4j-test-org/test-readme/keys{/key_id}",
143+
"collaborators_url": "https://api.github.com/repos/hub4j-test-org/test-readme/collaborators{/collaborator}",
144+
"teams_url": "https://api.github.com/repos/hub4j-test-org/test-readme/teams",
145+
"hooks_url": "https://api.github.com/repos/hub4j-test-org/test-readme/hooks",
146+
"issue_events_url": "https://api.github.com/repos/hub4j-test-org/test-readme/issues/events{/number}",
147+
"events_url": "https://api.github.com/repos/hub4j-test-org/test-readme/events",
148+
"assignees_url": "https://api.github.com/repos/hub4j-test-org/test-readme/assignees{/user}",
149+
"branches_url": "https://api.github.com/repos/hub4j-test-org/test-readme/branches{/branch}",
150+
"tags_url": "https://api.github.com/repos/hub4j-test-org/test-readme/tags",
151+
"blobs_url": "https://api.github.com/repos/hub4j-test-org/test-readme/git/blobs{/sha}",
152+
"git_tags_url": "https://api.github.com/repos/hub4j-test-org/test-readme/git/tags{/sha}",
153+
"git_refs_url": "https://api.github.com/repos/hub4j-test-org/test-readme/git/refs{/sha}",
154+
"trees_url": "https://api.github.com/repos/hub4j-test-org/test-readme/git/trees{/sha}",
155+
"statuses_url": "https://api.github.com/repos/hub4j-test-org/test-readme/statuses/{sha}",
156+
"languages_url": "https://api.github.com/repos/hub4j-test-org/test-readme/languages",
157+
"stargazers_url": "https://api.github.com/repos/hub4j-test-org/test-readme/stargazers",
158+
"contributors_url": "https://api.github.com/repos/hub4j-test-org/test-readme/contributors",
159+
"subscribers_url": "https://api.github.com/repos/hub4j-test-org/test-readme/subscribers",
160+
"subscription_url": "https://api.github.com/repos/hub4j-test-org/test-readme/subscription",
161+
"commits_url": "https://api.github.com/repos/hub4j-test-org/test-readme/commits{/sha}",
162+
"git_commits_url": "https://api.github.com/repos/hub4j-test-org/test-readme/git/commits{/sha}",
163+
"comments_url": "https://api.github.com/repos/hub4j-test-org/test-readme/comments{/number}",
164+
"issue_comment_url": "https://api.github.com/repos/hub4j-test-org/test-readme/issues/comments{/number}",
165+
"contents_url": "https://api.github.com/repos/hub4j-test-org/test-readme/contents/{+path}",
166+
"compare_url": "https://api.github.com/repos/hub4j-test-org/test-readme/compare/{base}...{head}",
167+
"merges_url": "https://api.github.com/repos/hub4j-test-org/test-readme/merges",
168+
"archive_url": "https://api.github.com/repos/hub4j-test-org/test-readme/{archive_format}{/ref}",
169+
"downloads_url": "https://api.github.com/repos/hub4j-test-org/test-readme/downloads",
170+
"issues_url": "https://api.github.com/repos/hub4j-test-org/test-readme/issues{/number}",
171+
"pulls_url": "https://api.github.com/repos/hub4j-test-org/test-readme/pulls{/number}",
172+
"milestones_url": "https://api.github.com/repos/hub4j-test-org/test-readme/milestones{/number}",
173+
"notifications_url": "https://api.github.com/repos/hub4j-test-org/test-readme/notifications{?since,all,participating}",
174+
"labels_url": "https://api.github.com/repos/hub4j-test-org/test-readme/labels{/name}",
175+
"releases_url": "https://api.github.com/repos/hub4j-test-org/test-readme/releases{/id}",
176+
"deployments_url": "https://api.github.com/repos/hub4j-test-org/test-readme/deployments",
177+
"created_at": "2015-02-15T14:24:54Z",
178+
"updated_at": "2021-04-19T20:17:38Z",
179+
"pushed_at": "2021-04-19T20:17:36Z",
180+
"git_url": "git://github.com/hub4j-test-org/test-readme.git",
181+
"ssh_url": "[email protected]:hub4j-test-org/test-readme.git",
182+
"clone_url": "https://github.com/hub4j-test-org/test-readme.git",
183+
"svn_url": "https://github.com/hub4j-test-org/test-readme",
184+
"homepage": null,
185+
"size": 0,
186+
"stargazers_count": 0,
187+
"watchers_count": 0,
188+
"language": null,
189+
"has_issues": true,
190+
"has_projects": true,
191+
"has_downloads": true,
192+
"has_wiki": true,
193+
"has_pages": false,
194+
"forks_count": 0,
195+
"mirror_url": null,
196+
"archived": false,
197+
"disabled": false,
198+
"open_issues_count": 0,
199+
"license": null,
200+
"allow_forking": true,
201+
"is_template": false,
202+
"web_commit_signoff_required": false,
203+
"topics": [],
204+
"visibility": "public",
205+
"forks": 0,
206+
"open_issues": 0,
207+
"watchers": 0,
208+
"default_branch": "main",
209+
"permissions": {
210+
"admin": false,
211+
"maintain": false,
212+
"push": false,
213+
"triage": false,
214+
"pull": false
215+
}
216+
}
217+
]
218+
}

0 commit comments

Comments
 (0)