diff --git a/src/create-installation-access-token.ts b/src/create-installation-access-token.ts index 2054fad..9c72a9a 100644 --- a/src/create-installation-access-token.ts +++ b/src/create-installation-access-token.ts @@ -23,7 +23,9 @@ export const createInstallationAccessToken = async ({ permissions, privateKey, repositories, -}: InstallationAccessTokenCreationOptions): Promise => { +}: InstallationAccessTokenCreationOptions): Promise<{ + [s: string]: string; +}> => { try { const app = createAppAuth({ appId, @@ -45,12 +47,12 @@ export const createInstallationAccessToken = async ({ ); const { - data: { token }, + data: { token, expires_at }, } = await octokit.request( "POST /app/installations/{installation_id}/access_tokens", { installation_id: installationId, permissions, repositories }, ); - return token; + return { token: token, expiration: expires_at }; } catch (error: unknown) { throw new Error("Could not create installation access token.", { cause: error, diff --git a/src/main.ts b/src/main.ts index 9a0f7f2..890d411 100644 --- a/src/main.ts +++ b/src/main.ts @@ -3,13 +3,14 @@ import { info, saveState, setOutput, setSecret } from "@actions/core"; import { createInstallationAccessToken } from "./create-installation-access-token.js"; import { parseOptions } from "./parse-options.js"; import { run } from "./run.js"; -import { tokenKey } from "./state.js"; +import { expirationKey, tokenKey } from "./state.js"; await run(async () => { const options = parseOptions(); - const token = await createInstallationAccessToken(options); + const { token, expiration } = await createInstallationAccessToken(options); setSecret(token); saveState(tokenKey, token); + saveState(expirationKey, expiration); setOutput("token", token); info("Token created successfully"); }); diff --git a/src/post.ts b/src/post.ts index 0d2680e..a30dca3 100644 --- a/src/post.ts +++ b/src/post.ts @@ -2,7 +2,7 @@ import { getInput, getState, info } from "@actions/core"; import { revokeInstallationAccessToken } from "./revoke-installation-access-token.js"; import { run } from "./run.js"; -import { tokenKey } from "./state.js"; +import { expirationKey, tokenKey } from "./state.js"; await run(async () => { if (!JSON.parse(getInput("revoke"))) { @@ -15,6 +15,15 @@ await run(async () => { info("No token to revoke"); return; } + + // if expiration is before now, then the token already expired and there's no need to revoke it + const expiration = getState(expirationKey); + const now = Date.now(); + const expirationTime = Date.parse(expiration); + if (expirationTime < now) { + info("Token is already expired, no need to revoke it"); + return; + } await revokeInstallationAccessToken(token); info("Token revoked successfully"); }); diff --git a/src/state.ts b/src/state.ts index ddd1ef3..64075f7 100644 --- a/src/state.ts +++ b/src/state.ts @@ -1 +1,2 @@ export const tokenKey = "token"; +export const expirationKey = "expires_at";