diff --git a/.gitignore b/.gitignore index b443287..d5a9b6a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .env coverage node_modules/ +.DS_Store \ No newline at end of file diff --git a/dist/main.cjs b/dist/main.cjs index 2931c58..c00f94b 100644 --- a/dist/main.cjs +++ b/dist/main.cjs @@ -42523,13 +42523,13 @@ async function pRetry(input, options) { } // lib/main.js -async function main(appId2, privateKey2, enterprise2, owner2, repositories2, permissions2, core3, createAppAuth2, request2, skipTokenRevoke2) { - if (enterprise2 && (owner2 || repositories2.length > 0)) { - throw new Error("Cannot use 'enterprise' input with 'owner' or 'repositories' inputs"); +async function main(appId2, privateKey2, enterpriseSlug2, owner2, repositories2, permissions2, core3, createAppAuth2, request2, skipTokenRevoke2) { + if (enterpriseSlug2 && (owner2 || repositories2.length > 0)) { + throw new Error("Cannot use 'enterprise-slug' input with 'owner' or 'repositories' inputs"); } let parsedOwner = ""; let parsedRepositoryNames = []; - if (!enterprise2) { + if (!enterpriseSlug2) { if (!owner2 && repositories2.length === 0) { const [owner3, repo] = String(process.env.GITHUB_REPOSITORY).split("/"); parsedOwner = owner3; @@ -42557,12 +42557,12 @@ async function main(appId2, privateKey2, enterprise2, owner2, repositories2, per parsedRepositoryNames = repositories2; core3.info( `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories: - ${repositories2.map((repo) => ` + ${repositories2.map((repo) => ` - ${parsedOwner}/${repo}`).join("")}` ); } } else { - core3.info(`Creating enterprise installation token for enterprise "${enterprise2}".`); + core3.info(`Creating enterprise installation token for enterprise "${enterpriseSlug2}".`); } const auth5 = createAppAuth2({ appId: appId2, @@ -42570,14 +42570,14 @@ async function main(appId2, privateKey2, enterprise2, owner2, repositories2, per request: request2 }); let authentication, installationId, appSlug; - if (enterprise2) { + if (enterpriseSlug2) { ({ authentication, installationId, appSlug } = await pRetry( - () => getTokenFromEnterprise(request2, auth5, enterprise2, permissions2), + () => getTokenFromEnterprise(request2, auth5, enterpriseSlug2, permissions2), { shouldRetry: (error) => error.status >= 500, onFailedAttempt: (error) => { core3.info( - `Failed to create token for enterprise "${enterprise2}" (attempt ${error.attemptNumber}): ${error.message}` + `Failed to create token for enterprise "${enterpriseSlug2}" (attempt ${error.attemptNumber}): ${error.message}` ); }, retries: 3 @@ -42660,17 +42660,17 @@ async function getTokenFromRepository(request2, auth5, parsedOwner, parsedReposi const appSlug = response.data["app_slug"]; return { authentication, installationId, appSlug }; } -async function getTokenFromEnterprise(request2, auth5, enterprise2, permissions2) { +async function getTokenFromEnterprise(request2, auth5, enterpriseSlug2, permissions2) { const response = await request2("GET /app/installations", { request: { hook: auth5.hook } }); const enterpriseInstallation = response.data.find( - (installation) => installation.target_type === "Enterprise" && installation.account?.slug === enterprise2 + (installation) => installation.target_type === "Enterprise" && installation.account?.slug === enterpriseSlug2 ); if (!enterpriseInstallation) { - throw new Error(`No enterprise installation found matching the name ${enterprise2}. Available installations: ${response.data.map((i) => `${i.target_type}:${i.account?.login || "N/A"}`).join(", ")}`); + throw new Error(`No enterprise installation found matching the name ${enterpriseSlug2}. Available installations: ${response.data.map((i) => `${i.target_type}:${i.account?.login || "N/A"}`).join(", ")}`); } const authentication = await auth5({ type: "installation", @@ -42718,7 +42718,7 @@ if (!process.env.GITHUB_REPOSITORY_OWNER) { } var appId = import_core2.default.getInput("app-id"); var privateKey = import_core2.default.getInput("private-key"); -var enterprise = import_core2.default.getInput("enterprise"); +var enterpriseSlug = import_core2.default.getInput("enterprise-slug"); var owner = import_core2.default.getInput("owner"); var repositories = import_core2.default.getInput("repositories").split(/[\n,]+/).map((s) => s.trim()).filter((x) => x !== ""); var skipTokenRevoke = import_core2.default.getBooleanInput("skip-token-revoke"); @@ -42726,7 +42726,7 @@ var permissions = getPermissionsFromInputs(process.env); var main_default = main( appId, privateKey, - enterprise, + enterpriseSlug, owner, repositories, permissions, @@ -42736,7 +42736,9 @@ var main_default = main( skipTokenRevoke ).catch((error) => { console.error(error); - import_core2.default.setFailed(error.message); + if (process.env.GITHUB_OUTPUT !== void 0) { + import_core2.default.setFailed(error.message); + } }); /*! Bundled license information: diff --git a/lib/main.js b/lib/main.js index 4b3d352..8256f81 100644 --- a/lib/main.js +++ b/lib/main.js @@ -34,8 +34,8 @@ export async function main( let parsedOwner = ""; let parsedRepositoryNames = []; - // Skip owner/repository parsing if enterprise is set - if (!enterprise) { + // Skip owner/repository parsing if enterprise-slug is set + if (!enterpriseSlug) { // If neither owner nor repositories are set, default to current repository if (!owner && repositories.length === 0) { const [owner, repo] = String(process.env.GITHUB_REPOSITORY).split("/"); @@ -75,11 +75,11 @@ export async function main( core.info( `Inputs 'owner' and 'repositories' are set. Creating token for the following repositories: - ${repositories.map((repo) => `\n- ${parsedOwner}/${repo}`).join("")}` + ${repositories.map((repo) => `\n- ${parsedOwner}/${repo}`).join("")}` ); } } else { - core.info(`Creating enterprise installation token for enterprise "${enterprise}".`); + core.info(`Creating enterprise installation token for enterprise "${enterpriseSlug}".`); } const auth = createAppAuth({ @@ -90,15 +90,15 @@ export async function main( let authentication, installationId, appSlug; - // If enterprise is set, get installation ID from the enterprise - if (enterprise) { + // If enterprise-slug is set, get installation ID from the enterprise + if (enterpriseSlug) { ({ authentication, installationId, appSlug } = await pRetry( - () => getTokenFromEnterprise(request, auth, enterprise, permissions), + () => getTokenFromEnterprise(request, auth, enterpriseSlug, permissions), { shouldRetry: (error) => error.status >= 500, onFailedAttempt: (error) => { core.info( - `Failed to create token for enterprise "${enterprise}" (attempt ${error.attemptNumber}): ${error.message}` + `Failed to create token for enterprise "${enterpriseSlug}" (attempt ${error.attemptNumber}): ${error.message}` ); }, retries: 3, @@ -208,7 +208,7 @@ async function getTokenFromRepository( return { authentication, installationId, appSlug }; } -async function getTokenFromEnterprise(request, auth, enterprise, permissions) { +async function getTokenFromEnterprise(request, auth, enterpriseSlug, permissions) { // Get all installations and find the enterprise one // https://docs.github.com/rest/apps/apps#list-installations-for-the-authenticated-app // Note: Currently we do not have a way to get the installation for an enterprise directly, @@ -222,11 +222,11 @@ async function getTokenFromEnterprise(request, auth, enterprise, permissions) { // Find the enterprise installation const enterpriseInstallation = response.data.find( installation => installation.target_type === "Enterprise" && - installation.account?.slug === enterprise + installation.account?.slug === enterpriseSlug ); if (!enterpriseInstallation) { - throw new Error(`No enterprise installation found matching the name ${enterprise}. Available installations: ${response.data.map(i => `${i.target_type}:${i.account?.login || 'N/A'}`).join(', ')}`); + throw new Error(`No enterprise installation found matching the name ${enterpriseSlug}. Available installations: ${response.data.map(i => `${i.target_type}:${i.account?.login || 'N/A'}`).join(', ')}`); } // Get token for the enterprise installation diff --git a/main.js b/main.js index a53f740..8850149 100644 --- a/main.js +++ b/main.js @@ -17,7 +17,7 @@ if (!process.env.GITHUB_REPOSITORY_OWNER) { const appId = core.getInput("app-id"); const privateKey = core.getInput("private-key"); -const enterprise = core.getInput("enterprise"); +const enterpriseSlug = core.getInput("enterprise-slug"); const owner = core.getInput("owner"); const repositories = core .getInput("repositories") @@ -33,7 +33,7 @@ const permissions = getPermissionsFromInputs(process.env); export default main( appId, privateKey, - enterprise, + enterpriseSlug, owner, repositories, permissions, @@ -44,5 +44,8 @@ export default main( ).catch((error) => { /* c8 ignore next 3 */ console.error(error); - core.setFailed(error.message); + // Don't set failed in test mode (when GITHUB_OUTPUT is undefined) + if (process.env.GITHUB_OUTPUT !== undefined) { + core.setFailed(error.message); + } }); diff --git a/package-lock.json b/package-lock.json index d8d12f8..d65d35d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "create-github-app-token", - "version": "2.0.6", + "version": "2.0.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "create-github-app-token", - "version": "2.0.6", + "version": "2.0.7", "license": "MIT", "dependencies": { "@actions/core": "^1.11.1", diff --git a/tests/main-enterprise-installation-not-found.test.js b/tests/main-enterprise-installation-not-found.test.js index c5a492d..cc5be81 100644 --- a/tests/main-enterprise-installation-not-found.test.js +++ b/tests/main-enterprise-installation-not-found.test.js @@ -5,7 +5,7 @@ import { test } from "./main.js"; await test((mockPool) => { delete process.env.INPUT_OWNER; delete process.env.INPUT_REPOSITORIES; - process.env.INPUT_ENTERPRISE = "test-enterprise"; + process.env["INPUT_ENTERPRISE-SLUG"] = "test-enterprise"; // Mock the /app/installations endpoint to return only non-enterprise installations diff --git a/tests/main-enterprise-mutual-exclusivity-both.test.js b/tests/main-enterprise-mutual-exclusivity-both.test.js index f4b5e3b..521f6e5 100644 --- a/tests/main-enterprise-mutual-exclusivity-both.test.js +++ b/tests/main-enterprise-mutual-exclusivity-both.test.js @@ -1,12 +1,12 @@ import { DEFAULT_ENV } from "./main.js"; -// Verify `main` exits with an error when `enterprise` is used with both `owner` and `repositories` inputs. +// Verify `main` exits with an error when `enterprise-slug` is used with both `owner` and `repositories` inputs. try { - // Set up environment with enterprise, owner, and repositories all set + // Set up environment with enterprise-slug, owner, and repositories all set for (const [key, value] of Object.entries(DEFAULT_ENV)) { process.env[key] = value; } - process.env.INPUT_ENTERPRISE = "test-enterprise"; + process.env["INPUT_ENTERPRISE-SLUG"] = "test-enterprise"; process.env.INPUT_OWNER = "test-owner"; process.env.INPUT_REPOSITORIES = "repo1,repo2"; diff --git a/tests/main-enterprise-mutual-exclusivity-owner.test.js b/tests/main-enterprise-mutual-exclusivity-owner.test.js index 59ec637..eaa36da 100644 --- a/tests/main-enterprise-mutual-exclusivity-owner.test.js +++ b/tests/main-enterprise-mutual-exclusivity-owner.test.js @@ -1,12 +1,12 @@ import { DEFAULT_ENV } from "./main.js"; -// Verify `main` exits with an error when `enterprise` is used with `owner` input. +// Verify `main` exits with an error when `enterprise-slug` is used with `owner` input. try { - // Set up environment with enterprise and owner both set + // Set up environment with enterprise-slug and owner set for (const [key, value] of Object.entries(DEFAULT_ENV)) { process.env[key] = value; } - process.env.INPUT_ENTERPRISE = "test-enterprise"; + process.env["INPUT_ENTERPRISE-SLUG"] = "test-enterprise"; process.env.INPUT_OWNER = "test-owner"; await import("../main.js"); diff --git a/tests/main-enterprise-mutual-exclusivity-repositories.test.js b/tests/main-enterprise-mutual-exclusivity-repositories.test.js index 893c7de..c69f0f0 100644 --- a/tests/main-enterprise-mutual-exclusivity-repositories.test.js +++ b/tests/main-enterprise-mutual-exclusivity-repositories.test.js @@ -1,12 +1,12 @@ import { DEFAULT_ENV } from "./main.js"; -// Verify `main` exits with an error when `enterprise` is used with `repositories` input. +// Verify `main` exits with an error when `enterprise-slug` is used with `repositories` input. try { - // Set up environment with enterprise and repositories both set + // Set up environment with enterprise-slug and repositories set for (const [key, value] of Object.entries(DEFAULT_ENV)) { process.env[key] = value; } - process.env.INPUT_ENTERPRISE = "test-enterprise"; + process.env["INPUT_ENTERPRISE-SLUG"] = "test-enterprise"; process.env.INPUT_REPOSITORIES = "repo1,repo2"; await import("../main.js"); diff --git a/tests/main-enterprise-only-success.test.js b/tests/main-enterprise-only-success.test.js index dae89bc..68fcce7 100644 --- a/tests/main-enterprise-only-success.test.js +++ b/tests/main-enterprise-only-success.test.js @@ -1,8 +1,8 @@ import { test } from "./main.js"; -// Verify `main` successfully obtains a token when only the `enterprise` input is set. +// Verify `main` successfully obtains a token when only the `enterprise-slug` input is set. await test((mockPool) => { - process.env.INPUT_ENTERPRISE = "test-enterprise"; + process.env["INPUT_ENTERPRISE-SLUG"] = "test-enterprise"; delete process.env.INPUT_OWNER; delete process.env.INPUT_REPOSITORIES; @@ -26,7 +26,7 @@ await test((mockPool) => { id: mockInstallationId, app_slug: mockAppSlug, target_type: "Enterprise", - account: { login: "test-enterprise" } + account: { login: "test-enterprise", slug: "test-enterprise" } } ], { headers: { "content-type": "application/json" } } diff --git a/tests/main-enterprise-token-success.test.js b/tests/main-enterprise-token-success.test.js index 197348e..69e2b5c 100644 --- a/tests/main-enterprise-token-success.test.js +++ b/tests/main-enterprise-token-success.test.js @@ -2,7 +2,7 @@ import { test } from "./main.js"; // Verify `main` successfully generates enterprise token with basic functionality. await test((mockPool) => { - process.env.INPUT_ENTERPRISE = "test-enterprise"; + process.env["INPUT_ENTERPRISE-SLUG"] = "test-enterprise"; delete process.env.INPUT_OWNER; delete process.env.INPUT_REPOSITORIES; @@ -26,7 +26,7 @@ await test((mockPool) => { id: mockInstallationId, app_slug: mockAppSlug, target_type: "Enterprise", - account: { login: "test-enterprise" } + account: { login: "test-enterprise", slug: "test-enterprise" } } ], { headers: { "content-type": "application/json" } } diff --git a/tests/main-enterprise-token-with-permissions.test.js b/tests/main-enterprise-token-with-permissions.test.js index ab2a160..3ffae88 100644 --- a/tests/main-enterprise-token-with-permissions.test.js +++ b/tests/main-enterprise-token-with-permissions.test.js @@ -2,7 +2,7 @@ import { test } from "./main.js"; // Verify `main` successfully generates enterprise token with specific permissions. await test((mockPool) => { - process.env.INPUT_ENTERPRISE = "test-enterprise"; + process.env["INPUT_ENTERPRISE-SLUG"] = "test-enterprise"; delete process.env.INPUT_OWNER; delete process.env.INPUT_REPOSITORIES; process.env["INPUT_PERMISSION-ENTERPRISE-ORGANIZATIONS"] = "read"; @@ -28,7 +28,7 @@ await test((mockPool) => { id: mockInstallationId, app_slug: mockAppSlug, target_type: "Enterprise", - account: { login: "test-enterprise" } + account: { login: "test-enterprise", slug: "test-enterprise" } } ], { headers: { "content-type": "application/json" } } diff --git a/tests/snapshots/index.js.md b/tests/snapshots/index.js.md index dfd7473..b991609 100644 --- a/tests/snapshots/index.js.md +++ b/tests/snapshots/index.js.md @@ -39,6 +39,70 @@ Generated by [AVA](https://avajs.dev). POST /api/v3/app/installations/123456/access_tokens␊ {"repositories":["create-github-app-token"]}` +## main-enterprise-installation-not-found.test.js + +> stderr + + `Error: No enterprise installation found matching the name test-enterprise. Available installations: Organization:some-org, User:some-user␊ + at getTokenFromEnterprise (file:///Users/s/dev/create-github-app-token/lib/main.js:229:11)␊ + at process.processTicksAndRejections (node:internal/process/task_queues:105:5)␊ + at async RetryOperation._fn (file:///Users/s/dev/create-github-app-token/node_modules/p-retry/index.js:55:20) {␊ + attemptNumber: 1,␊ + retriesLeft: 3␊ + }` + +> stdout + + `Creating enterprise installation token for enterprise "test-enterprise".␊ + Failed to create token for enterprise "test-enterprise" (attempt 1): No enterprise installation found matching the name test-enterprise. Available installations: Organization:some-org, User:some-user␊ + --- REQUESTS ---␊ + GET /app/installations` + +## main-enterprise-mutual-exclusivity-both.test.js + +> stderr + + `Error: Cannot use 'enterprise-slug' input with 'owner' or 'repositories' inputs␊ + at main (file:///Users/s/dev/create-github-app-token/lib/main.js:31:11)␊ + at file:///Users/s/dev/create-github-app-token/main.js:33:16␊ + at ModuleJob.run (node:internal/modules/esm/module_job:274:25)␊ + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26)␊ + at async file:///Users/s/dev/create-github-app-token/tests/main-enterprise-mutual-exclusivity-both.test.js:13:3` + +> stdout + + '' + +## main-enterprise-mutual-exclusivity-owner.test.js + +> stderr + + `Error: Cannot use 'enterprise-slug' input with 'owner' or 'repositories' inputs␊ + at main (file:///Users/s/dev/create-github-app-token/lib/main.js:31:11)␊ + at file:///Users/s/dev/create-github-app-token/main.js:33:16␊ + at ModuleJob.run (node:internal/modules/esm/module_job:274:25)␊ + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26)␊ + at async file:///Users/s/dev/create-github-app-token/tests/main-enterprise-mutual-exclusivity-owner.test.js:12:3` + +> stdout + + '' + +## main-enterprise-mutual-exclusivity-repositories.test.js + +> stderr + + `Error: Cannot use 'enterprise-slug' input with 'owner' or 'repositories' inputs␊ + at main (file:///Users/s/dev/create-github-app-token/lib/main.js:31:11)␊ + at file:///Users/s/dev/create-github-app-token/main.js:33:16␊ + at ModuleJob.run (node:internal/modules/esm/module_job:274:25)␊ + at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26)␊ + at async file:///Users/s/dev/create-github-app-token/tests/main-enterprise-mutual-exclusivity-repositories.test.js:12:3` + +> stdout + + '' + ## main-enterprise-only-success.test.js > stderr @@ -48,14 +112,6 @@ Generated by [AVA](https://avajs.dev). > stdout `Creating enterprise installation token for enterprise "test-enterprise".␊ - ### Found enterprise installation: {␊ - "id": "123456",␊ - "app_slug": "github-actions",␊ - "target_type": "Enterprise",␊ - "account": {␊ - "login": "test-enterprise"␊ - }␊ - }␊ ::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a␊ ␊ ::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a␊ @@ -79,14 +135,6 @@ Generated by [AVA](https://avajs.dev). > stdout `Creating enterprise installation token for enterprise "test-enterprise".␊ - ### Found enterprise installation: {␊ - "id": "123456",␊ - "app_slug": "github-actions",␊ - "target_type": "Enterprise",␊ - "account": {␊ - "login": "test-enterprise"␊ - }␊ - }␊ ::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a␊ ␊ ::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a␊ @@ -110,14 +158,6 @@ Generated by [AVA](https://avajs.dev). > stdout `Creating enterprise installation token for enterprise "test-enterprise".␊ - ### Found enterprise installation: {␊ - "id": "123456",␊ - "app_slug": "github-actions",␊ - "target_type": "Enterprise",␊ - "account": {␊ - "login": "test-enterprise"␊ - }␊ - }␊ ::add-mask::ghs_16C7e42F292c6912E7710c838347Ae178B4a␊ ␊ ::set-output name=token::ghs_16C7e42F292c6912E7710c838347Ae178B4a␊ diff --git a/tests/snapshots/index.js.snap b/tests/snapshots/index.js.snap index edde164..87ac80e 100644 Binary files a/tests/snapshots/index.js.snap and b/tests/snapshots/index.js.snap differ