refactor: remove redundant API call (#175)

Combines the two installation requests (org and user) into one because
`/org/{org}` can also be accessed at `/users/{org}`.

---------

Co-authored-by: Gregor Martynus <39992+gr2m@users.noreply.github.com>
This commit is contained in:
Parker Brown
2024-10-07 13:26:35 -07:00
committed by GitHub
parent a2c2dfabb4
commit 25cc3bdc27
8 changed files with 278 additions and 197 deletions

View File

@@ -26,9 +26,7 @@ export async function main(
// 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("/");
const [owner, repo] = String(process.env.GITHUB_REPOSITORY).split("/");
parsedOwner = owner;
parsedRepositoryNames = [repo];
@@ -52,7 +50,9 @@ export async function main(
parsedRepositoryNames = repositories;
core.info(
`owner not set, creating owner for given repositories "${repositories.join(',')}" in current owner ("${parsedOwner}")`
`owner not set, creating owner for given repositories "${repositories.join(
","
)}" in current owner ("${parsedOwner}")`
);
}
@@ -62,7 +62,9 @@ export async function main(
parsedRepositoryNames = repositories;
core.info(
`owner and repositories set, creating token for repositories "${repositories.join(',')}" owned by "${owner}"`
`owner and repositories set, creating token for repositories "${repositories.join(
","
)}" owned by "${owner}"`
);
}
@@ -76,24 +78,38 @@ export async function main(
// If at least one repository is set, get installation ID from that repository
if (parsedRepositoryNames.length > 0) {
({ authentication, installationId, appSlug } = await pRetry(() => getTokenFromRepository(request, auth, parsedOwner, parsedRepositoryNames), {
onFailedAttempt: (error) => {
core.info(
`Failed to create token for "${parsedRepositoryNames.join(',')}" (attempt ${error.attemptNumber}): ${error.message}`
);
},
retries: 3,
}));
({ authentication, installationId, appSlug } = await pRetry(
() =>
getTokenFromRepository(
request,
auth,
parsedOwner,
parsedRepositoryNames
),
{
onFailedAttempt: (error) => {
core.info(
`Failed to create token for "${parsedRepositoryNames.join(
","
)}" (attempt ${error.attemptNumber}): ${error.message}`
);
},
retries: 3,
}
));
} else {
// Otherwise get the installation for the owner, which can either be an organization or a user account
({ authentication, installationId, appSlug } = await pRetry(() => getTokenFromOwner(request, auth, parsedOwner), {
onFailedAttempt: (error) => {
core.info(
`Failed to create token for "${parsedOwner}" (attempt ${error.attemptNumber}): ${error.message}`
);
},
retries: 3,
}));
({ authentication, installationId, appSlug } = await pRetry(
() => getTokenFromOwner(request, auth, parsedOwner),
{
onFailedAttempt: (error) => {
core.info(
`Failed to create token for "${parsedOwner}" (attempt ${error.attemptNumber}): ${error.message}`
);
},
retries: 3,
}
));
}
// Register the token with the runner as a secret to ensure it is masked in logs
@@ -111,23 +127,13 @@ export async function main(
}
async function getTokenFromOwner(request, auth, parsedOwner) {
// https://docs.github.com/en/rest/apps/apps?apiVersion=2022-11-28#get-an-organization-installation-for-the-authenticated-app
const response = await request("GET /orgs/{org}/installation", {
org: parsedOwner,
// https://docs.github.com/rest/apps/apps?apiVersion=2022-11-28#get-a-user-installation-for-the-authenticated-app
// This endpoint works for both users and organizations
const response = await request("GET /users/{username}/installation", {
username: parsedOwner,
request: {
hook: auth.hook,
},
}).catch((error) => {
/* c8 ignore next */
if (error.status !== 404) throw error;
// https://docs.github.com/rest/apps/apps?apiVersion=2022-11-28#get-a-user-installation-for-the-authenticated-app
return request("GET /users/{username}/installation", {
username: parsedOwner,
request: {
hook: auth.hook,
},
});
});
// Get token for for all repositories of the given installation
@@ -137,12 +143,17 @@ async function getTokenFromOwner(request, auth, parsedOwner) {
});
const installationId = response.data.id;
const appSlug = response.data['app_slug'];
const appSlug = response.data["app_slug"];
return { authentication, installationId, appSlug };
}
async function getTokenFromRepository(request, auth, parsedOwner, parsedRepositoryNames) {
async function getTokenFromRepository(
request,
auth,
parsedOwner,
parsedRepositoryNames
) {
// https://docs.github.com/rest/apps/apps?apiVersion=2022-11-28#get-a-repository-installation-for-the-authenticated-app
const response = await request("GET /repos/{owner}/{repo}/installation", {
owner: parsedOwner,
@@ -160,7 +171,7 @@ async function getTokenFromRepository(request, auth, parsedOwner, parsedReposito
});
const installationId = response.data.id;
const appSlug = response.data['app_slug'];
const appSlug = response.data["app_slug"];
return { authentication, installationId, appSlug };
}