From 45db2b688a08322980c71658a67d707dd3904ad4 Mon Sep 17 00:00:00 2001 From: whywaita Date: Thu, 2 Sep 2021 00:22:24 +0900 Subject: [PATCH 1/3] fix bug when scope is repository --- README.md | 1 + action.yml | 2 +- dist/index.js | 38 ++++++++++++++++++++++++++++++++++---- src/main.ts | 45 ++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8f14867..2cf3c37 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ You will need to provide the GitHub App ID and private key. The action will then with: app_id: ${{ secrets.APP_ID }} private_key: ${{ secrets.APP_PRIVATE_KEY }} + scope: "octocat" # Optional, you can set "org" or "org/repo" - name: Checkout private repo uses: actions/checkout@v2 diff --git a/action.yml b/action.yml index dc74e0b..71f3c12 100644 --- a/action.yml +++ b/action.yml @@ -10,7 +10,7 @@ inputs: description: 'Private key for the GitHub App' scope: required: false - description: 'Scope of installation account' + description: 'Scope of installation account. Format: "org" or "org/repo"' default: '' outputs: token: diff --git a/dist/index.js b/dist/index.js index 3824bf0..42aa46f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -104,12 +104,13 @@ const installations = yield appOctokit.apps.listInstallations(); let installationId = installations.data[0].id; if (scope !== '') { + const loginName = scope.split('/')[0]; // if scope set repository, loginName is username const scopedData = installations.data.find((item) => { var _a; return ( ((_a = item.account) === null || _a === void 0 ? void 0 - : _a.login) === scope + : _a.login) === loginName ); }); if (scopedData === undefined) { @@ -129,9 +130,19 @@ throw new Error('Unable to authenticate'); } // @ts-expect-error - core.setSecret(resp.token); - // @ts-expect-error - core.setOutput('token', resp.token); + const installationToken = resp.token; + // Need to check accessibility if scope set repository + if (scope !== '' && scope.split('/').length === 2) { + const error = yield isExistRepositoryInGitHubApps( + installationToken, + scope + ); + if (error.error !== '') { + throw new Error(error.error); + } + } + core.setSecret(installationToken); + core.setOutput('token', installationToken); } catch (error) { if (error instanceof Error) { core.setFailed(error.message); @@ -139,6 +150,25 @@ } }); } + function isExistRepositoryInGitHubApps(installationToken, repository) { + return __awaiter(this, void 0, void 0, function* () { + const installationOctokit = new rest_1.Octokit({ + auth: installationToken, + baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com', + }); + const accessibleRepositories = + yield installationOctokit.apps.listReposAccessibleToInstallation(); + const repo = accessibleRepositories.data.repositories.find( + (item) => item.full_name === repository + ); + if (repo === undefined) { + return { + error: `GitHub Apps can't accessible repository (${repository})`, + }; + } + return {error: ''}; + }); + } run(); /***/ diff --git a/src/main.ts b/src/main.ts index 986abf2..94ffbc2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,6 +5,8 @@ import * as core from '@actions/core'; type listInstallationsResponse = Endpoints['GET /app/installations']['response']; +type listRepositoriesResponse = + Endpoints['GET /installation/repositories']['response']; async function run(): Promise { try { @@ -24,8 +26,9 @@ async function run(): Promise { await appOctokit.apps.listInstallations(); let installationId = installations.data[0].id; if (scope !== '') { + const loginName: string = scope.split('/')[0]; // if scope set repository, loginName is username const scopedData = installations.data.find( - (item) => item.account?.login === scope + (item) => item.account?.login === loginName ); if (scopedData === undefined) { throw new Error(`set scope is ${scope}, but installation is not found`); @@ -43,11 +46,22 @@ async function run(): Promise { if (!resp) { throw new Error('Unable to authenticate'); } - - // @ts-expect-error - core.setSecret(resp.token); // @ts-expect-error - core.setOutput('token', resp.token); + const installationToken = resp.token; + + // Need to check accessibility if scope set repository + if (scope !== '' && scope.split('/').length === 2) { + const error = await isExistRepositoryInGitHubApps( + installationToken, + scope + ); + if (error.error !== '') { + throw new Error(error.error); + } + } + + core.setSecret(installationToken); + core.setOutput('token', installationToken); } catch (error) { if (error instanceof Error) { core.setFailed(error.message); @@ -55,4 +69,25 @@ async function run(): Promise { } } +async function isExistRepositoryInGitHubApps( + installationToken: string, + repository: string +): Promise<{error: string}> { + const installationOctokit = new Octokit({ + auth: installationToken, + baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com', + }); + const accessibleRepositories: listRepositoriesResponse = + await installationOctokit.apps.listReposAccessibleToInstallation(); + + const repo = accessibleRepositories.data.repositories.find( + (item) => item.full_name === repository + ); + if (repo === undefined) { + return {error: `GitHub Apps can't accessible repository (${repository})`}; + } + + return {error: ''}; +} + run(); From f318804345d507c11e017643476cacadad34a60f Mon Sep 17 00:00:00 2001 From: whywaita Date: Mon, 13 Sep 2021 00:33:44 +0900 Subject: [PATCH 2/3] throw Error in function --- dist/index.js | 15 ++++----------- src/main.ts | 14 +++----------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/dist/index.js b/dist/index.js index 42aa46f..f9b91b8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -133,13 +133,7 @@ const installationToken = resp.token; // Need to check accessibility if scope set repository if (scope !== '' && scope.split('/').length === 2) { - const error = yield isExistRepositoryInGitHubApps( - installationToken, - scope - ); - if (error.error !== '') { - throw new Error(error.error); - } + yield isExistRepositoryInGitHubApps(installationToken, scope); } core.setSecret(installationToken); core.setOutput('token', installationToken); @@ -162,11 +156,10 @@ (item) => item.full_name === repository ); if (repo === undefined) { - return { - error: `GitHub Apps can't accessible repository (${repository})`, - }; + throw new Error( + `GitHub Apps can't accessible repository (${repository})` + ); } - return {error: ''}; }); } run(); diff --git a/src/main.ts b/src/main.ts index 94ffbc2..418097a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -51,13 +51,7 @@ async function run(): Promise { // Need to check accessibility if scope set repository if (scope !== '' && scope.split('/').length === 2) { - const error = await isExistRepositoryInGitHubApps( - installationToken, - scope - ); - if (error.error !== '') { - throw new Error(error.error); - } + await isExistRepositoryInGitHubApps(installationToken, scope); } core.setSecret(installationToken); @@ -72,7 +66,7 @@ async function run(): Promise { async function isExistRepositoryInGitHubApps( installationToken: string, repository: string -): Promise<{error: string}> { +): Promise { const installationOctokit = new Octokit({ auth: installationToken, baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com', @@ -84,10 +78,8 @@ async function isExistRepositoryInGitHubApps( (item) => item.full_name === repository ); if (repo === undefined) { - return {error: `GitHub Apps can't accessible repository (${repository})`}; + throw new Error(`GitHub Apps can't accessible repository (${repository})`); } - - return {error: ''}; } run(); From 25bd9794cb055ca5c8552a9b273461d5fdbe1beb Mon Sep 17 00:00:00 2001 From: whywaita Date: Mon, 7 Mar 2022 17:56:21 +0900 Subject: [PATCH 3/3] Check all repository by paginate library --- dist/index.js | 79 ++++++++++++++++++++++++++++++++++++++++++++------- src/main.ts | 23 ++++++++------- 2 files changed, 82 insertions(+), 20 deletions(-) diff --git a/dist/index.js b/dist/index.js index f9b91b8..e819172 100644 --- a/dist/index.js +++ b/dist/index.js @@ -83,10 +83,50 @@ ); }); }; + var __asyncValues = + (this && this.__asyncValues) || + function (o) { + if (!Symbol.asyncIterator) + throw new TypeError('Symbol.asyncIterator is not defined.'); + var m = o[Symbol.asyncIterator], + i; + return m + ? m.call(o) + : ((o = + typeof __values === 'function' + ? __values(o) + : o[Symbol.iterator]()), + (i = {}), + verb('next'), + verb('throw'), + verb('return'), + (i[Symbol.asyncIterator] = function () { + return this; + }), + i); + function verb(n) { + i[n] = + o[n] && + function (v) { + return new Promise(function (resolve, reject) { + (v = o[n](v)), settle(resolve, reject, v.done, v.value); + }); + }; + } + function settle(resolve, reject, d, v) { + Promise.resolve(v).then(function (v) { + resolve({value: v, done: d}); + }, reject); + } + }; Object.defineProperty(exports, '__esModule', {value: true}); const auth_app_1 = __nccwpck_require__(7541); const rest_1 = __nccwpck_require__(5375); const core = __importStar(__nccwpck_require__(2186)); + const plugin_paginate_rest_1 = __nccwpck_require__(4193); + const paginateOctokit = rest_1.Octokit.plugin( + plugin_paginate_rest_1.paginateRest + ); function run() { return __awaiter(this, void 0, void 0, function* () { try { @@ -145,21 +185,40 @@ }); } function isExistRepositoryInGitHubApps(installationToken, repository) { + var e_1, _a; return __awaiter(this, void 0, void 0, function* () { - const installationOctokit = new rest_1.Octokit({ + const installationOctokit = new paginateOctokit({ auth: installationToken, baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com', }); - const accessibleRepositories = - yield installationOctokit.apps.listReposAccessibleToInstallation(); - const repo = accessibleRepositories.data.repositories.find( - (item) => item.full_name === repository - ); - if (repo === undefined) { - throw new Error( - `GitHub Apps can't accessible repository (${repository})` - ); + try { + for ( + var _b = __asyncValues( + installationOctokit.paginate.iterator( + 'GET /installation/repositories' + ) + ), + _c; + (_c = yield _b.next()), !_c.done; + + ) { + const response = _c.value; + if (response.data.find((r) => r.full_name === repository)) { + return undefined; + } + } + } catch (e_1_1) { + e_1 = {error: e_1_1}; + } finally { + try { + if (_c && !_c.done && (_a = _b.return)) yield _a.call(_b); + } finally { + if (e_1) throw e_1.error; + } } + throw new Error( + `GitHub Apps can't accessible repository (${repository})` + ); }); } run(); diff --git a/src/main.ts b/src/main.ts index 418097a..d7b6f93 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,10 +3,12 @@ import {Octokit} from '@octokit/rest'; import {Endpoints} from '@octokit/types'; import * as core from '@actions/core'; +import {paginateRest} from '@octokit/plugin-paginate-rest'; + +const paginateOctokit = Octokit.plugin(paginateRest); + type listInstallationsResponse = Endpoints['GET /app/installations']['response']; -type listRepositoriesResponse = - Endpoints['GET /installation/repositories']['response']; async function run(): Promise { try { @@ -67,19 +69,20 @@ async function isExistRepositoryInGitHubApps( installationToken: string, repository: string ): Promise { - const installationOctokit = new Octokit({ + const installationOctokit = new paginateOctokit({ auth: installationToken, baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com', }); - const accessibleRepositories: listRepositoriesResponse = - await installationOctokit.apps.listReposAccessibleToInstallation(); - const repo = accessibleRepositories.data.repositories.find( - (item) => item.full_name === repository - ); - if (repo === undefined) { - throw new Error(`GitHub Apps can't accessible repository (${repository})`); + for await (const response of installationOctokit.paginate.iterator( + 'GET /installation/repositories' + )) { + if (response.data.find((r) => r.full_name === repository)) { + return undefined; + } } + + throw new Error(`GitHub Apps can't accessible repository (${repository})`); } run();