Retries on oidc. 152

This commit is contained in:
Colin McDonnell
2025-12-22 14:33:18 -08:00
parent 2dea842981
commit 5353d80388
4 changed files with 41 additions and 12 deletions
+35 -6
View File
@@ -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]);
+3 -3
View File
@@ -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}`);
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@pullfrog/action",
"version": "0.0.151",
"version": "0.0.152",
"type": "module",
"files": [
"index.js",
+2 -2
View File
@@ -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<string> {
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<string> {
async function acquireNewToken(): Promise<string> {
if (isGitHubActionsEnvironment()) {
return await acquireTokenViaOIDC();
return await retry(() => acquireTokenViaOIDC(), { label: "token exchange" });
} else {
return await acquireTokenViaGitHubApp();
}