Skip to content

Commit 45db2b6

Browse files
committed
fix bug when scope is repository
1 parent 38a3ce5 commit 45db2b6

File tree

4 files changed

+76
-10
lines changed

4 files changed

+76
-10
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ You will need to provide the GitHub App ID and private key. The action will then
2626
with:
2727
app_id: ${{ secrets.APP_ID }}
2828
private_key: ${{ secrets.APP_PRIVATE_KEY }}
29+
scope: "octocat" # Optional, you can set "org" or "org/repo"
2930
3031
- name: Checkout private repo
3132
uses: actions/checkout@v2

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ inputs:
1010
description: 'Private key for the GitHub App'
1111
scope:
1212
required: false
13-
description: 'Scope of installation account'
13+
description: 'Scope of installation account. Format: "org" or "org/repo"'
1414
default: ''
1515
outputs:
1616
token:

dist/index.js

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,13 @@
104104
const installations = yield appOctokit.apps.listInstallations();
105105
let installationId = installations.data[0].id;
106106
if (scope !== '') {
107+
const loginName = scope.split('/')[0]; // if scope set repository, loginName is username
107108
const scopedData = installations.data.find((item) => {
108109
var _a;
109110
return (
110111
((_a = item.account) === null || _a === void 0
111112
? void 0
112-
: _a.login) === scope
113+
: _a.login) === loginName
113114
);
114115
});
115116
if (scopedData === undefined) {
@@ -129,16 +130,45 @@
129130
throw new Error('Unable to authenticate');
130131
}
131132
// @ts-expect-error
132-
core.setSecret(resp.token);
133-
// @ts-expect-error
134-
core.setOutput('token', resp.token);
133+
const installationToken = resp.token;
134+
// Need to check accessibility if scope set repository
135+
if (scope !== '' && scope.split('/').length === 2) {
136+
const error = yield isExistRepositoryInGitHubApps(
137+
installationToken,
138+
scope
139+
);
140+
if (error.error !== '') {
141+
throw new Error(error.error);
142+
}
143+
}
144+
core.setSecret(installationToken);
145+
core.setOutput('token', installationToken);
135146
} catch (error) {
136147
if (error instanceof Error) {
137148
core.setFailed(error.message);
138149
}
139150
}
140151
});
141152
}
153+
function isExistRepositoryInGitHubApps(installationToken, repository) {
154+
return __awaiter(this, void 0, void 0, function* () {
155+
const installationOctokit = new rest_1.Octokit({
156+
auth: installationToken,
157+
baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com',
158+
});
159+
const accessibleRepositories =
160+
yield installationOctokit.apps.listReposAccessibleToInstallation();
161+
const repo = accessibleRepositories.data.repositories.find(
162+
(item) => item.full_name === repository
163+
);
164+
if (repo === undefined) {
165+
return {
166+
error: `GitHub Apps can't accessible repository (${repository})`,
167+
};
168+
}
169+
return {error: ''};
170+
});
171+
}
142172
run();
143173

144174
/***/

src/main.ts

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import * as core from '@actions/core';
55

66
type listInstallationsResponse =
77
Endpoints['GET /app/installations']['response'];
8+
type listRepositoriesResponse =
9+
Endpoints['GET /installation/repositories']['response'];
810

911
async function run(): Promise<void> {
1012
try {
@@ -24,8 +26,9 @@ async function run(): Promise<void> {
2426
await appOctokit.apps.listInstallations();
2527
let installationId = installations.data[0].id;
2628
if (scope !== '') {
29+
const loginName: string = scope.split('/')[0]; // if scope set repository, loginName is username
2730
const scopedData = installations.data.find(
28-
(item) => item.account?.login === scope
31+
(item) => item.account?.login === loginName
2932
);
3033
if (scopedData === undefined) {
3134
throw new Error(`set scope is ${scope}, but installation is not found`);
@@ -43,16 +46,48 @@ async function run(): Promise<void> {
4346
if (!resp) {
4447
throw new Error('Unable to authenticate');
4548
}
46-
47-
// @ts-expect-error
48-
core.setSecret(resp.token);
4949
// @ts-expect-error
50-
core.setOutput('token', resp.token);
50+
const installationToken = resp.token;
51+
52+
// Need to check accessibility if scope set repository
53+
if (scope !== '' && scope.split('/').length === 2) {
54+
const error = await isExistRepositoryInGitHubApps(
55+
installationToken,
56+
scope
57+
);
58+
if (error.error !== '') {
59+
throw new Error(error.error);
60+
}
61+
}
62+
63+
core.setSecret(installationToken);
64+
core.setOutput('token', installationToken);
5165
} catch (error) {
5266
if (error instanceof Error) {
5367
core.setFailed(error.message);
5468
}
5569
}
5670
}
5771

72+
async function isExistRepositoryInGitHubApps(
73+
installationToken: string,
74+
repository: string
75+
): Promise<{error: string}> {
76+
const installationOctokit = new Octokit({
77+
auth: installationToken,
78+
baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com',
79+
});
80+
const accessibleRepositories: listRepositoriesResponse =
81+
await installationOctokit.apps.listReposAccessibleToInstallation();
82+
83+
const repo = accessibleRepositories.data.repositories.find(
84+
(item) => item.full_name === repository
85+
);
86+
if (repo === undefined) {
87+
return {error: `GitHub Apps can't accessible repository (${repository})`};
88+
}
89+
90+
return {error: ''};
91+
}
92+
5893
run();

0 commit comments

Comments
 (0)