This commit is contained in:
Colin McDonnell
2026-01-28 07:47:52 +00:00
committed by pullfrog[bot]
parent 071e885d63
commit f77fecc2a0
8 changed files with 174 additions and 253 deletions
+39 -11
View File
@@ -135594,9 +135594,14 @@ import { join } from "node:path";
// utils/log.ts
var core = __toESM(require_core(), 1);
var import_table = __toESM(require_src(), 1);
// utils/globals.ts
import { existsSync } from "node:fs";
var isCloudflareSandbox = !!process.env.CLOUDFLARE_APPLICATION_ID && !!process.env.SANDBOX_VERSION;
var isGitHubActions = !!process.env.GITHUB_ACTIONS;
var isInsideDocker = existsSync("/.dockerenv");
// utils/log.ts
var isDebugEnabled = () => process.env.LOG_LEVEL === "debug" || process.env.ACTIONS_STEP_DEBUG === "true" || process.env.RUNNER_DEBUG === "1" || core.isDebug();
function formatArgs(args3) {
return args3.map((arg) => {
@@ -141996,14 +142001,31 @@ import assert2 from "node:assert/strict";
var githubInstallationToken;
async function resolveInstallationToken() {
assert2(!githubInstallationToken, "GitHub installation token is already set.");
const acquiredToken = await acquireNewToken();
core3.setSecret(acquiredToken);
githubInstallationToken = acquiredToken;
const originalToken = process.env.GITHUB_TOKEN;
if (originalToken) {
process.env.ORIGINAL_GITHUB_TOKEN = originalToken;
}
const externalToken = process.env.GH_TOKEN;
const token = externalToken || await acquireNewToken();
process.env.GITHUB_TOKEN = token;
githubInstallationToken = token;
if (isGitHubActions) {
core3.setSecret(token);
}
return {
token: acquiredToken,
[Symbol.asyncDispose]() {
token,
originalToken,
async [Symbol.asyncDispose]() {
githubInstallationToken = void 0;
return revokeGitHubInstallationToken(acquiredToken);
if (originalToken) {
process.env.GITHUB_TOKEN = originalToken;
} else {
delete process.env.GITHUB_TOKEN;
}
if (externalToken) {
return;
}
return revokeGitHubInstallationToken(token);
}
};
}
@@ -159965,7 +159987,7 @@ function query({
// package.json
var package_default = {
name: "@pullfrog/pullfrog",
version: "0.0.159",
version: "0.0.161",
type: "module",
files: [
"index.js",
@@ -159992,7 +160014,6 @@ var package_default = {
},
dependencies: {
"@actions/core": "^1.11.1",
"@actions/github": "^6.0.1",
"@anthropic-ai/claude-agent-sdk": "0.2.7",
"@ark/fs": "0.53.0",
"@ark/util": "0.53.0",
@@ -162604,10 +162625,11 @@ async function resolveRun(params) {
// main.ts
async function main() {
var _stack2 = [];
try {
normalizeEnv();
process.env.ORIGINAL_GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const timer = new Timer();
const tokenRef = await resolveInstallationToken();
const tokenRef = __using(_stack2, await resolveInstallationToken(), true);
process.env.GITHUB_TOKEN = tokenRef.token;
const octokit = createOctokit(tokenRef.token);
const runInfo = await resolveRun({ octokit });
@@ -162643,7 +162665,7 @@ async function main() {
});
await setupGit({
token: tokenRef.token,
originalToken: process.env.ORIGINAL_GITHUB_TOKEN,
originalToken: tokenRef.originalToken,
bashPermission: payload.bash,
owner: runContext.repo.owner,
name: runContext.repo.name,
@@ -162700,6 +162722,12 @@ async function main() {
error: errorMessage
};
}
} catch (_2) {
var _error2 = _2, _hasError2 = true;
} finally {
var _promise3 = __callDispose(_stack2, _error2, _hasError2);
_promise3 && await _promise3;
}
}
// entry.ts
+5
View File
@@ -25507,9 +25507,14 @@ var core3 = __toESM(require_core(), 1);
// utils/log.ts
var core = __toESM(require_core(), 1);
var import_table = __toESM(require_src(), 1);
// utils/globals.ts
import { existsSync } from "node:fs";
var isCloudflareSandbox = !!process.env.CLOUDFLARE_APPLICATION_ID && !!process.env.SANDBOX_VERSION;
var isGitHubActions = !!process.env.GITHUB_ACTIONS;
var isInsideDocker = existsSync("/.dockerenv");
// utils/log.ts
var isDebugEnabled = () => process.env.LOG_LEVEL === "debug" || process.env.ACTIONS_STEP_DEBUG === "true" || process.env.RUNNER_DEBUG === "1" || core.isDebug();
function formatArgs(args) {
return args.map((arg) => {
+4 -5
View File
@@ -30,13 +30,12 @@ export async function main(): Promise<MainResult> {
// normalize env var names to uppercase (handles case-insensitive workflow files)
normalizeEnv();
// store original GITHUB_TOKEN
process.env.ORIGINAL_GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const timer = new Timer();
const tokenRef = await resolveInstallationToken();
await using tokenRef = await resolveInstallationToken();
process.env.GITHUB_TOKEN = tokenRef.token;
const octokit = createOctokit(tokenRef.token);
const runInfo = await resolveRun({ octokit });
const toolState = initToolState({ runInfo });
@@ -82,7 +81,7 @@ export async function main(): Promise<MainResult> {
await setupGit({
token: tokenRef.token,
originalToken: process.env.ORIGINAL_GITHUB_TOKEN,
originalToken: tokenRef.originalToken,
bashPermission: payload.bash,
owner: runContext.repo.owner,
name: runContext.repo.name,
+1 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@pullfrog/pullfrog",
"version": "0.0.159",
"version": "0.0.161",
"type": "module",
"files": [
"index.js",
@@ -27,7 +27,6 @@
},
"dependencies": {
"@actions/core": "^1.11.1",
"@actions/github": "^6.0.1",
"@anthropic-ai/claude-agent-sdk": "0.2.7",
"@ark/fs": "0.53.0",
"@ark/util": "0.53.0",
-137
View File
@@ -11,9 +11,6 @@ importers:
'@actions/core':
specifier: ^1.11.1
version: 1.11.1
'@actions/github':
specifier: ^6.0.1
version: 6.0.1
'@anthropic-ai/claude-agent-sdk':
specifier: 0.2.7
version: 0.2.7(zod@4.3.5)
@@ -105,9 +102,6 @@ packages:
'@actions/exec@1.1.1':
resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==}
'@actions/github@6.0.1':
resolution: {integrity: sha512-xbZVcaqD4XnQAe35qSQqskb3SqIAfRyLBrHMd/8TuL7hJSz2QtbDwnNM8zWx4zO5l2fnGtseNE3MbEvD7BxVMw==}
'@actions/http-client@2.2.3':
resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==}
@@ -556,18 +550,10 @@ packages:
'@cfworker/json-schema':
optional: true
'@octokit/auth-token@4.0.0':
resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==}
engines: {node: '>= 18'}
'@octokit/auth-token@6.0.0':
resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==}
engines: {node: '>= 20'}
'@octokit/core@5.2.2':
resolution: {integrity: sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg==}
engines: {node: '>= 18'}
'@octokit/core@7.0.5':
resolution: {integrity: sha512-t54CUOsFMappY1Jbzb7fetWeO0n6K0k/4+/ZpkS+3Joz8I4VcvY9OiEBFRYISqaI2fq5sCiPtAjRDOzVYG8m+Q==}
engines: {node: '>= 20'}
@@ -576,24 +562,10 @@ packages:
resolution: {integrity: sha512-7P1dRAZxuWAOPI7kXfio88trNi/MegQ0IJD3vfgC3b+LZo1Qe6gRJc2v0mz2USWWJOKrB2h5spXCzGbw+fAdqA==}
engines: {node: '>= 20'}
'@octokit/endpoint@9.0.6':
resolution: {integrity: sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==}
engines: {node: '>= 18'}
'@octokit/graphql@7.1.1':
resolution: {integrity: sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g==}
engines: {node: '>= 18'}
'@octokit/graphql@9.0.2':
resolution: {integrity: sha512-iz6KzZ7u95Fzy9Nt2L8cG88lGRMr/qy1Q36ih/XVzMIlPDMYwaNLE/ENhqmIzgPrlNWiYJkwmveEetvxAgFBJw==}
engines: {node: '>= 20'}
'@octokit/openapi-types@20.0.0':
resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==}
'@octokit/openapi-types@24.2.0':
resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==}
'@octokit/openapi-types@26.0.0':
resolution: {integrity: sha512-7AtcfKtpo77j7Ts73b4OWhOZHTKo/gGY8bB3bNBQz4H+GRSWqx2yvj8TXRsbdTE0eRmYmXOEY66jM7mJ7LzfsA==}
@@ -606,24 +578,12 @@ packages:
peerDependencies:
'@octokit/core': '>=6'
'@octokit/plugin-paginate-rest@9.2.2':
resolution: {integrity: sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '5'
'@octokit/plugin-request-log@6.0.0':
resolution: {integrity: sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==}
engines: {node: '>= 20'}
peerDependencies:
'@octokit/core': '>=6'
'@octokit/plugin-rest-endpoint-methods@10.4.1':
resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==}
engines: {node: '>= 18'}
peerDependencies:
'@octokit/core': '5'
'@octokit/plugin-rest-endpoint-methods@16.1.0':
resolution: {integrity: sha512-nCsyiKoGRnhH5LkH8hJEZb9swpqOcsW+VXv1QoyUNQXJeVODG4+xM6UICEqyqe9XFr6LkL8BIiFCPev8zMDXPw==}
engines: {node: '>= 20'}
@@ -636,10 +596,6 @@ packages:
peerDependencies:
'@octokit/core': ^7.0.0
'@octokit/request-error@5.1.1':
resolution: {integrity: sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==}
engines: {node: '>= 18'}
'@octokit/request-error@7.0.1':
resolution: {integrity: sha512-CZpFwV4+1uBrxu7Cw8E5NCXDWFNf18MSY23TdxCBgjw1tXXHvTrZVsXlW8hgFTOLw8RQR1BBrMvYRtuyaijHMA==}
engines: {node: '>= 20'}
@@ -648,20 +604,10 @@ packages:
resolution: {integrity: sha512-TXnouHIYLtgDhKo+N6mXATnDBkV05VwbR0TtMWpgTHIoQdRQfCSzmy/LGqR1AbRMbijq/EckC/E3/ZNcU92NaQ==}
engines: {node: '>= 20'}
'@octokit/request@8.4.1':
resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==}
engines: {node: '>= 18'}
'@octokit/rest@22.0.0':
resolution: {integrity: sha512-z6tmTu9BTnw51jYGulxrlernpsQYXpui1RK21vmXn8yF5bp6iX16yfTtJYGK5Mh1qDkvDOmp2n8sRMcQmR8jiA==}
engines: {node: '>= 20'}
'@octokit/types@12.6.0':
resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==}
'@octokit/types@13.10.0':
resolution: {integrity: sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA==}
'@octokit/types@15.0.0':
resolution: {integrity: sha512-8o6yDfmoGJUIeR9OfYU0/TUJTnMPG2r68+1yEdUeG2Fdqpj8Qetg0ziKIgcBm0RW/j29H41WP37CYCEhp6GoHQ==}
@@ -918,9 +864,6 @@ packages:
resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
engines: {node: '>=8'}
before-after-hook@2.2.3:
resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==}
before-after-hook@4.0.0:
resolution: {integrity: sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==}
@@ -995,9 +938,6 @@ packages:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
deprecation@2.3.1:
resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
dotenv@17.2.3:
resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==}
engines: {node: '>=12'}
@@ -1546,9 +1486,6 @@ packages:
resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
engines: {node: '>=18'}
universal-user-agent@6.0.1:
resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==}
universal-user-agent@7.0.3:
resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==}
@@ -1712,16 +1649,6 @@ snapshots:
dependencies:
'@actions/io': 1.1.3
'@actions/github@6.0.1':
dependencies:
'@actions/http-client': 2.2.3
'@octokit/core': 5.2.2
'@octokit/plugin-paginate-rest': 9.2.2(@octokit/core@5.2.2)
'@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.2)
'@octokit/request': 8.4.1
'@octokit/request-error': 5.1.1
undici: 5.29.0
'@actions/http-client@2.2.3':
dependencies:
tunnel: 0.0.6
@@ -2001,20 +1928,8 @@ snapshots:
- hono
- supports-color
'@octokit/auth-token@4.0.0': {}
'@octokit/auth-token@6.0.0': {}
'@octokit/core@5.2.2':
dependencies:
'@octokit/auth-token': 4.0.0
'@octokit/graphql': 7.1.1
'@octokit/request': 8.4.1
'@octokit/request-error': 5.1.1
'@octokit/types': 13.10.0
before-after-hook: 2.2.3
universal-user-agent: 6.0.1
'@octokit/core@7.0.5':
dependencies:
'@octokit/auth-token': 6.0.0
@@ -2030,27 +1945,12 @@ snapshots:
'@octokit/types': 15.0.0
universal-user-agent: 7.0.3
'@octokit/endpoint@9.0.6':
dependencies:
'@octokit/types': 13.10.0
universal-user-agent: 6.0.1
'@octokit/graphql@7.1.1':
dependencies:
'@octokit/request': 8.4.1
'@octokit/types': 13.10.0
universal-user-agent: 6.0.1
'@octokit/graphql@9.0.2':
dependencies:
'@octokit/request': 10.0.5
'@octokit/types': 15.0.0
universal-user-agent: 7.0.3
'@octokit/openapi-types@20.0.0': {}
'@octokit/openapi-types@24.2.0': {}
'@octokit/openapi-types@26.0.0': {}
'@octokit/openapi-types@27.0.0': {}
@@ -2060,20 +1960,10 @@ snapshots:
'@octokit/core': 7.0.5
'@octokit/types': 15.0.0
'@octokit/plugin-paginate-rest@9.2.2(@octokit/core@5.2.2)':
dependencies:
'@octokit/core': 5.2.2
'@octokit/types': 12.6.0
'@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.5)':
dependencies:
'@octokit/core': 7.0.5
'@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.2.2)':
dependencies:
'@octokit/core': 5.2.2
'@octokit/types': 12.6.0
'@octokit/plugin-rest-endpoint-methods@16.1.0(@octokit/core@7.0.5)':
dependencies:
'@octokit/core': 7.0.5
@@ -2085,12 +1975,6 @@ snapshots:
'@octokit/types': 16.0.0
bottleneck: 2.19.5
'@octokit/request-error@5.1.1':
dependencies:
'@octokit/types': 13.10.0
deprecation: 2.3.1
once: 1.4.0
'@octokit/request-error@7.0.1':
dependencies:
'@octokit/types': 15.0.0
@@ -2103,13 +1987,6 @@ snapshots:
fast-content-type-parse: 3.0.0
universal-user-agent: 7.0.3
'@octokit/request@8.4.1':
dependencies:
'@octokit/endpoint': 9.0.6
'@octokit/request-error': 5.1.1
'@octokit/types': 13.10.0
universal-user-agent: 6.0.1
'@octokit/rest@22.0.0':
dependencies:
'@octokit/core': 7.0.5
@@ -2117,14 +1994,6 @@ snapshots:
'@octokit/plugin-request-log': 6.0.0(@octokit/core@7.0.5)
'@octokit/plugin-rest-endpoint-methods': 16.1.0(@octokit/core@7.0.5)
'@octokit/types@12.6.0':
dependencies:
'@octokit/openapi-types': 20.0.0
'@octokit/types@13.10.0':
dependencies:
'@octokit/openapi-types': 24.2.0
'@octokit/types@15.0.0':
dependencies:
'@octokit/openapi-types': 26.0.0
@@ -2329,8 +2198,6 @@ snapshots:
astral-regex@2.0.0: {}
before-after-hook@2.2.3: {}
before-after-hook@4.0.0: {}
body-parser@2.2.0:
@@ -2402,8 +2269,6 @@ snapshots:
depd@2.0.0: {}
deprecation@2.3.1: {}
dotenv@17.2.3: {}
dunder-proto@1.0.1:
@@ -3026,8 +2891,6 @@ snapshots:
unicorn-magic@0.3.0: {}
universal-user-agent@6.0.1: {}
universal-user-agent@7.0.3: {}
unpipe@1.0.0: {}
+9
View File
@@ -0,0 +1,9 @@
import { existsSync } from "node:fs";
export const isCloudflareSandbox =
!!process.env.CLOUDFLARE_APPLICATION_ID && !!process.env.SANDBOX_VERSION;
export const isGitHubActions = !!process.env.GITHUB_ACTIONS;
// detect if running inside Docker container (CI tests run in Docker with host env vars)
export const isInsideDocker = existsSync("/.dockerenv");
+1 -6
View File
@@ -2,14 +2,9 @@
* Logging utilities that work well in both local and GitHub Actions environments
*/
import { existsSync } from "node:fs";
import * as core from "@actions/core";
import { table } from "table";
const isGitHubActions = !!process.env.GITHUB_ACTIONS;
// detect if running inside Docker container (CI tests run in Docker with host env vars)
const isInsideDocker = existsSync("/.dockerenv");
import { isGitHubActions, isInsideDocker } from "./globals.ts";
const isDebugEnabled = () =>
process.env.LOG_LEVEL === "debug" ||
+29 -6
View File
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
import * as core from "@actions/core";
import { log } from "./cli.ts";
import { acquireNewToken } from "./github.ts";
import { isGitHubActions } from "./globals.ts";
// re-export for get-installation-token action
export { acquireNewToken as acquireInstallationToken };
@@ -15,14 +16,36 @@ let githubInstallationToken: string | undefined;
*/
export async function resolveInstallationToken() {
assert(!githubInstallationToken, "GitHub installation token is already set.");
const acquiredToken = await acquireNewToken();
core.setSecret(acquiredToken);
githubInstallationToken = acquiredToken;
const originalToken = process.env.GITHUB_TOKEN;
if (originalToken) {
process.env.ORIGINAL_GITHUB_TOKEN = originalToken;
}
const externalToken = process.env.GH_TOKEN;
const token = externalToken || (await acquireNewToken());
process.env.GITHUB_TOKEN = token;
githubInstallationToken = token;
if (isGitHubActions) {
// out of caution, we don't call this here outside of the GitHub Actions environment
// given this uses `process.stdout.write(cmd.toString() + os.EOL)` under the hood,
core.setSecret(token);
}
return {
token: acquiredToken,
[Symbol.asyncDispose]() {
token,
originalToken,
async [Symbol.asyncDispose]() {
githubInstallationToken = undefined;
return revokeGitHubInstallationToken(acquiredToken);
if (originalToken) {
process.env.GITHUB_TOKEN = originalToken;
} else {
delete process.env.GITHUB_TOKEN;
}
// GH_TOKEN isn't acquired here, so it's not revoked here either
if (externalToken) {
return;
}
return revokeGitHubInstallationToken(token);
},
};
}