v1.0.1
This commit is contained in:
+11
-102
@@ -2,96 +2,6 @@
|
||||
|
||||
import * as core from "@actions/core";
|
||||
|
||||
type RetryOptions = {
|
||||
maxAttempts?: number;
|
||||
initialDelayMs?: number;
|
||||
maxDelayMs?: number;
|
||||
backoffFactor?: number;
|
||||
};
|
||||
|
||||
async function retryWithBackoff<T>(
|
||||
operation: () => Promise<T>,
|
||||
options: RetryOptions = {},
|
||||
): Promise<T> {
|
||||
const {
|
||||
maxAttempts = 3,
|
||||
initialDelayMs = 5000,
|
||||
maxDelayMs = 20000,
|
||||
backoffFactor = 2,
|
||||
} = options;
|
||||
|
||||
let delayMs = initialDelayMs;
|
||||
let lastError: Error | undefined;
|
||||
|
||||
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
||||
try {
|
||||
console.log(`Attempt ${attempt} of ${maxAttempts}...`);
|
||||
return await operation();
|
||||
} catch (error) {
|
||||
lastError = error instanceof Error ? error : new Error(String(error));
|
||||
console.error(`Attempt ${attempt} failed:`, lastError.message);
|
||||
|
||||
if (attempt < maxAttempts) {
|
||||
console.log(`Retrying in ${delayMs / 1000} seconds...`);
|
||||
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
||||
delayMs = Math.min(delayMs * backoffFactor, maxDelayMs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.error(`Operation failed after ${maxAttempts} attempts`);
|
||||
throw lastError;
|
||||
}
|
||||
|
||||
async function getOidcToken(): Promise<string> {
|
||||
try {
|
||||
const oidcToken = await core.getIDToken("claude-code-github-action");
|
||||
|
||||
return oidcToken;
|
||||
} catch (error) {
|
||||
console.error("Failed to get OIDC token:", error);
|
||||
throw new Error(
|
||||
"Could not fetch an OIDC token. Did you remember to add `id-token: write` to your workflow permissions?",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function exchangeForAppToken(oidcToken: string): Promise<string> {
|
||||
const response = await fetch(
|
||||
"https://api.anthropic.com/api/github/github-app-token-exchange",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
Authorization: `Bearer ${oidcToken}`,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const responseJson = (await response.json()) as {
|
||||
error?: {
|
||||
message?: string;
|
||||
};
|
||||
};
|
||||
console.error(
|
||||
`App token exchange failed: ${response.status} ${response.statusText} - ${responseJson?.error?.message ?? "Unknown error"}`,
|
||||
);
|
||||
throw new Error(`${responseJson?.error?.message ?? "Unknown error"}`);
|
||||
}
|
||||
|
||||
const appTokenData = (await response.json()) as {
|
||||
token?: string;
|
||||
app_token?: string;
|
||||
};
|
||||
const appToken = appTokenData.token || appTokenData.app_token;
|
||||
|
||||
if (!appToken) {
|
||||
throw new Error("App token not found in response");
|
||||
}
|
||||
|
||||
return appToken;
|
||||
}
|
||||
|
||||
export async function setupGitHubToken(): Promise<string> {
|
||||
try {
|
||||
// Check if GitHub token was provided as override
|
||||
@@ -103,22 +13,21 @@ export async function setupGitHubToken(): Promise<string> {
|
||||
return providedToken;
|
||||
}
|
||||
|
||||
console.log("Requesting OIDC token...");
|
||||
const oidcToken = await retryWithBackoff(() => getOidcToken());
|
||||
console.log("OIDC token successfully obtained");
|
||||
// Use the standard GITHUB_TOKEN from the workflow environment
|
||||
const workflowToken = process.env.GITHUB_TOKEN;
|
||||
|
||||
console.log("Exchanging OIDC token for app token...");
|
||||
const appToken = await retryWithBackoff(() =>
|
||||
exchangeForAppToken(oidcToken),
|
||||
if (workflowToken) {
|
||||
console.log("Using workflow GITHUB_TOKEN for authentication");
|
||||
core.setOutput("GITHUB_TOKEN", workflowToken);
|
||||
return workflowToken;
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
"No GitHub token available. Please provide a github_token input or ensure GITHUB_TOKEN is available in the workflow environment.",
|
||||
);
|
||||
console.log("App token successfully obtained");
|
||||
|
||||
console.log("Using GITHUB_TOKEN from OIDC");
|
||||
core.setOutput("GITHUB_TOKEN", appToken);
|
||||
return appToken;
|
||||
} catch (error) {
|
||||
core.setFailed(
|
||||
`Failed to setup GitHub token: ${error}.\n\nIf you instead wish to use this action with a custom GitHub token or custom GitHub app, provide a \`github_token\` in the \`uses\` section of the app in your workflow yml file.`,
|
||||
`Failed to setup GitHub token: ${error}.\n\nPlease provide a \`github_token\` in the \`with\` section of the action in your workflow yml file, or ensure the workflow has access to the default GITHUB_TOKEN.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user