From e5d3caf0acae42205387aa06e92d4bac4ebf70a2 Mon Sep 17 00:00:00 2001 From: wechuli Date: Sat, 3 Feb 2024 21:27:44 +0300 Subject: [PATCH 1/4] update how installation id is obtained --- action.yml | 4 ++++ src/main.ts | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/action.yml b/action.yml index 8da93fb..f3aad12 100644 --- a/action.yml +++ b/action.yml @@ -12,6 +12,10 @@ inputs: required: false description: 'Scope of installation account' default: '' + owner: + required: false + description: 'The organization/user to generate the installation access for' + default: ${{ github.repository_owner }} outputs: token: description: 'Github Token for App installation' diff --git a/src/main.ts b/src/main.ts index c555579..01865e5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,6 +11,7 @@ async function run(): Promise { const privateKey: string = core.getInput('private_key'); const appId: string = core.getInput('app_id'); const scope: string = core.getInput('scope'); + const owner: string = core.getInput('owner').trim(); const appOctokit = new Octokit({ authStrategy: createAppAuth, auth: { @@ -22,7 +23,17 @@ async function run(): Promise { const installations: listInstallationsResponse = await appOctokit.apps.listInstallations(); - let installationId = installations.data[0].id; + + const response = await appOctokit.apps + .getOrgInstallation({org: owner}) + .catch(async (error) => { + if (error.status === 404) { + return await appOctokit.apps.getUserInstallation({username: owner}); + } + throw error; + }); + let installationId = response.data.id; + if (scope !== '') { const scopedData = installations.data.find( (item) => From a2897adb26fd3612275acb06397cf4e9f7c1f33d Mon Sep 17 00:00:00 2001 From: wechuli Date: Sat, 3 Feb 2024 21:53:52 +0300 Subject: [PATCH 2/4] update how the installation id is fetched --- action.yml | 6 +----- src/main.ts | 37 ++++++++++++------------------------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/action.yml b/action.yml index f3aad12..850c7dd 100644 --- a/action.yml +++ b/action.yml @@ -10,11 +10,7 @@ inputs: description: 'Private key for the GitHub App' scope: required: false - description: 'Scope of installation account' - default: '' - owner: - required: false - description: 'The organization/user to generate the installation access for' + description: 'Scope of installation account, defaults to the owner of the repository where the workflow is executing' default: ${{ github.repository_owner }} outputs: token: diff --git a/src/main.ts b/src/main.ts index 01865e5..859696e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,17 +1,12 @@ import {createAppAuth} from '@octokit/auth-app'; import {Octokit} from '@octokit/rest'; -import {Endpoints} from '@octokit/types'; import * as core from '@actions/core'; -type listInstallationsResponse = - Endpoints['GET /app/installations']['response']; - async function run(): Promise { try { const privateKey: string = core.getInput('private_key'); const appId: string = core.getInput('app_id'); - const scope: string = core.getInput('scope'); - const owner: string = core.getInput('owner').trim(); + const scope: string = core.getInput('scope').trim(); const appOctokit = new Octokit({ authStrategy: createAppAuth, auth: { @@ -21,31 +16,23 @@ async function run(): Promise { baseUrl: process.env.GITHUB_API_URL || 'https://api.github.com', }); - const installations: listInstallationsResponse = - await appOctokit.apps.listInstallations(); - const response = await appOctokit.apps - .getOrgInstallation({org: owner}) + .getOrgInstallation({org: scope}) .catch(async (error) => { if (error.status === 404) { - return await appOctokit.apps.getUserInstallation({username: owner}); + return await appOctokit.apps + .getUserInstallation({username: scope}) + .catch((nestederror) => { + if (nestederror.status === 404) { + throw new Error( + `set scope is ${scope}, but installation is not found` + ); + } + }); } throw error; }); - let installationId = response.data.id; - - if (scope !== '') { - const scopedData = installations.data.find( - (item) => - item.account && - 'login' in item.account && - item.account?.login === scope - ); - if (scopedData === undefined) { - throw new Error(`set scope is ${scope}, but installation is not found`); - } - installationId = scopedData.id; - } + const installationId = response.data.id; // This is untyped // See: https://github.com/octokit/core.js/blob/master/src/index.ts#L182-L183 From c8a72c024493d4ec150b13621e28c7070f7a89a1 Mon Sep 17 00:00:00 2001 From: wechuli Date: Sun, 4 Feb 2024 08:42:56 +0300 Subject: [PATCH 3/4] correctly throw nested error --- src/main.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 859696e..35aeafa 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,7 +6,7 @@ async function run(): Promise { try { const privateKey: string = core.getInput('private_key'); const appId: string = core.getInput('app_id'); - const scope: string = core.getInput('scope').trim(); + const scope: string = core.getInput('scope'); const appOctokit = new Octokit({ authStrategy: createAppAuth, auth: { @@ -28,6 +28,7 @@ async function run(): Promise { `set scope is ${scope}, but installation is not found` ); } + throw nestederror; }); } throw error; From d661be58e20661293127ca89d250d10e60e88d05 Mon Sep 17 00:00:00 2001 From: wechuli Date: Wed, 18 Jun 2025 17:58:35 +0300 Subject: [PATCH 4/4] updates --- .idea/.gitignore | 5 ++ .idea/action-github-app-token.iml | 12 ++++ .idea/codeStyles/Project.xml | 67 ++++++++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 ++ .idea/inspectionProfiles/Project_Default.xml | 6 ++ .idea/modules.xml | 8 +++ .idea/vcs.xml | 6 ++ 7 files changed, 109 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/action-github-app-token.iml create mode 100644 .idea/codeStyles/Project.xml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/action-github-app-token.iml b/.idea/action-github-app-token.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/action-github-app-token.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..89930e4 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..03d9549 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..0a282d3 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file