diff --git a/entry b/entry index cadfe95..e052997 100755 --- a/entry +++ b/entry @@ -45360,14 +45360,14 @@ var require_retry_agent = __commonJS({ this.#options = options; } dispatch(opts, handler2) { - const retry = new RetryHandler({ + const retry2 = new RetryHandler({ ...opts, retryOptions: this.#options }, { dispatch: this.#agent.dispatch.bind(this.#agent), handler: handler2 }); - return this.#agent.dispatch(opts, retry); + return this.#agent.dispatch(opts, retry2); } close() { return this.#agent.close(); @@ -83328,7 +83328,7 @@ function query({ // package.json var package_default = { name: "@pullfrog/action", - version: "0.0.151", + version: "0.0.152", type: "module", files: [ "index.js", @@ -92866,6 +92866,35 @@ import { pipeline } from "node:stream/promises"; // utils/github.ts var core2 = __toESM(require_core(), 1); import { createSign } from "node:crypto"; + +// utils/retry.ts +var defaultShouldRetry = (error41) => { + if (!(error41 instanceof Error)) return false; + return error41.name === "AbortError" || error41.message.includes("fetch failed") || error41.message.includes("ECONNRESET") || error41.message.includes("ETIMEDOUT"); +}; +async function retry(fn2, options = {}) { + const maxAttempts = options.maxAttempts ?? 3; + const delayMs = options.delayMs ?? 1e3; + const shouldRetry = options.shouldRetry ?? defaultShouldRetry; + const label = options.label ?? "operation"; + let lastError; + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + try { + return await fn2(); + } catch (error41) { + lastError = error41; + if (attempt === maxAttempts || !shouldRetry(error41)) { + throw error41; + } + const delay2 = delayMs * attempt; + log.warning(`\xBB ${label} failed (attempt ${attempt}/${maxAttempts}), retrying in ${delay2}ms...`); + await new Promise((resolve2) => setTimeout(resolve2, delay2)); + } + } + throw lastError; +} + +// utils/github.ts function isGitHubActionsEnvironment() { return Boolean(process.env.GITHUB_ACTIONS); } @@ -92998,7 +93027,7 @@ async function acquireTokenViaGitHubApp() { } async function acquireNewToken() { if (isGitHubActionsEnvironment()) { - return await acquireTokenViaOIDC(); + return await retry(() => acquireTokenViaOIDC(), { label: "token exchange" }); } else { return await acquireTokenViaGitHubApp(); } @@ -123027,10 +123056,10 @@ async function checkoutPrBranch(params) { const remoteName = `pr-${pullNumber}`; const forkUrl = `https://x-access-token:${token}@github.com/${headRepo.full_name}.git`; try { - $("git", ["remote", "add", remoteName, forkUrl]); + $("git", ["remote", "add", remoteName, forkUrl], { log: false }); log.debug(`\u{1F4CC} added remote '${remoteName}' for fork ${headRepo.full_name}`); } catch { - $("git", ["remote", "set-url", remoteName, forkUrl]); + $("git", ["remote", "set-url", remoteName, forkUrl], { log: false }); log.debug(`\u{1F4CC} updated remote '${remoteName}' for fork ${headRepo.full_name}`); } $("git", ["config", `branch.${localBranch}.pushRemote`, remoteName]); diff --git a/mcp/checkout.ts b/mcp/checkout.ts index 9d39715..f4bcacb 100644 --- a/mcp/checkout.ts +++ b/mcp/checkout.ts @@ -107,13 +107,13 @@ export async function checkoutPrBranch( const remoteName = `pr-${pullNumber}`; const forkUrl = `https://x-access-token:${token}@github.com/${headRepo.full_name}.git`; - // add fork as a named remote (ignore error if already exists) + // add fork as a named remote (suppress logging to avoid "error: remote already exists" spam) try { - $("git", ["remote", "add", remoteName, forkUrl]); + $("git", ["remote", "add", remoteName, forkUrl], { log: false }); log.debug(`๐Ÿ“Œ added remote '${remoteName}' for fork ${headRepo.full_name}`); } catch { // remote already exists, update its URL - $("git", ["remote", "set-url", remoteName, forkUrl]); + $("git", ["remote", "set-url", remoteName, forkUrl], { log: false }); log.debug(`๐Ÿ“Œ updated remote '${remoteName}' for fork ${headRepo.full_name}`); } diff --git a/package.json b/package.json index 9119405..432cc7f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@pullfrog/action", - "version": "0.0.151", + "version": "0.0.152", "type": "module", "files": [ "index.js", diff --git a/utils/github.ts b/utils/github.ts index 38091ae..614d1ec 100644 --- a/utils/github.ts +++ b/utils/github.ts @@ -1,6 +1,7 @@ import { createSign } from "node:crypto"; import * as core from "@actions/core"; import { log } from "./cli.ts"; +import { retry } from "./retry.ts"; export interface InstallationToken { token: string; @@ -56,7 +57,6 @@ async function acquireTokenViaOIDC(): Promise { log.info("ยป exchanging OIDC token for installation token..."); - // Add timeout to prevent long waits (30 seconds) const timeoutMs = 30000; const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), timeoutMs); @@ -234,7 +234,7 @@ async function acquireTokenViaGitHubApp(): Promise { async function acquireNewToken(): Promise { if (isGitHubActionsEnvironment()) { - return await acquireTokenViaOIDC(); + return await retry(() => acquireTokenViaOIDC(), { label: "token exchange" }); } else { return await acquireTokenViaGitHubApp(); }