Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c18db965c3 | |||
| 1b4628e26b |
@@ -40481,7 +40481,7 @@ function query({
|
|||||||
// package.json
|
// package.json
|
||||||
var package_default = {
|
var package_default = {
|
||||||
name: "@pullfrog/action",
|
name: "@pullfrog/action",
|
||||||
version: "0.0.90",
|
version: "0.0.92",
|
||||||
type: "module",
|
type: "module",
|
||||||
files: [
|
files: [
|
||||||
"index.js",
|
"index.js",
|
||||||
@@ -40920,22 +40920,39 @@ async function acquireTokenViaOIDC() {
|
|||||||
log.info("OIDC token generated successfully");
|
log.info("OIDC token generated successfully");
|
||||||
const apiUrl = process.env.API_URL || "https://pullfrog.ai";
|
const apiUrl = process.env.API_URL || "https://pullfrog.ai";
|
||||||
log.info("Exchanging OIDC token for installation token...");
|
log.info("Exchanging OIDC token for installation token...");
|
||||||
const tokenResponse = await fetch(`${apiUrl}/api/github/installation-token`, {
|
const timeoutMs = 5e3;
|
||||||
method: "POST",
|
const controller = new AbortController();
|
||||||
headers: {
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
||||||
Authorization: `Bearer ${oidcToken}`,
|
try {
|
||||||
"Content-Type": "application/json"
|
const tokenResponse = await fetch(`${apiUrl}/api/github/installation-token`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${oidcToken}`,
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
signal: controller.signal
|
||||||
|
});
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
if (!tokenResponse.ok) {
|
||||||
|
log.warning(
|
||||||
|
`Token exchange failed: ${tokenResponse.status} ${tokenResponse.statusText}. Falling back to GITHUB_TOKEN.`
|
||||||
|
);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
});
|
const tokenData = await tokenResponse.json();
|
||||||
if (!tokenResponse.ok) {
|
log.info(`Installation token obtained for ${tokenData.repository || "all repositories"}`);
|
||||||
const errorText = await tokenResponse.text();
|
return tokenData.token;
|
||||||
throw new Error(
|
} catch (error2) {
|
||||||
`Token exchange failed: ${tokenResponse.status} ${tokenResponse.statusText} - ${errorText}`
|
clearTimeout(timeoutId);
|
||||||
);
|
if (error2 instanceof Error && error2.name === "AbortError") {
|
||||||
|
log.warning(`Token exchange timed out after ${timeoutMs}ms. Falling back to GITHUB_TOKEN.`);
|
||||||
|
} else {
|
||||||
|
log.warning(
|
||||||
|
`Token exchange failed: ${error2 instanceof Error ? error2.message : String(error2)}. Falling back to GITHUB_TOKEN.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
const tokenData = await tokenResponse.json();
|
|
||||||
log.info(`Installation token obtained for ${tokenData.repository || "all repositories"}`);
|
|
||||||
return tokenData.token;
|
|
||||||
}
|
}
|
||||||
var base64UrlEncode = (str) => {
|
var base64UrlEncode = (str) => {
|
||||||
return Buffer.from(str).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
return Buffer.from(str).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
||||||
@@ -41039,6 +41056,19 @@ async function acquireNewToken() {
|
|||||||
return await acquireTokenViaGitHubApp();
|
return await acquireTokenViaGitHubApp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function getDefaultGitHubToken() {
|
||||||
|
if (isGitHubActionsEnvironment()) {
|
||||||
|
const githubEnvVars = Object.keys(process.env).filter((key) => key.startsWith("GITHUB_")).reduce(
|
||||||
|
(acc, key) => {
|
||||||
|
acc[key] = key === "GITHUB_TOKEN" ? "***" : process.env[key];
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
log.debug(`GitHub env vars: ${JSON.stringify(githubEnvVars)}`);
|
||||||
|
}
|
||||||
|
return process.env.GITHUB_TOKEN || null;
|
||||||
|
}
|
||||||
async function setupGitHubInstallationToken() {
|
async function setupGitHubInstallationToken() {
|
||||||
const existingToken = checkExistingToken();
|
const existingToken = checkExistingToken();
|
||||||
if (existingToken) {
|
if (existingToken) {
|
||||||
@@ -41046,10 +41076,22 @@ async function setupGitHubInstallationToken() {
|
|||||||
log.info("Using provided GitHub installation token");
|
log.info("Using provided GitHub installation token");
|
||||||
return { githubInstallationToken: existingToken, wasAcquired: false };
|
return { githubInstallationToken: existingToken, wasAcquired: false };
|
||||||
}
|
}
|
||||||
const githubInstallationToken = await acquireNewToken();
|
const acquiredToken = await acquireNewToken();
|
||||||
core2.setSecret(githubInstallationToken);
|
if (!acquiredToken) {
|
||||||
process.env.GITHUB_INSTALLATION_TOKEN = githubInstallationToken;
|
const defaultToken = getDefaultGitHubToken();
|
||||||
return { githubInstallationToken, wasAcquired: true };
|
if (!defaultToken) {
|
||||||
|
throw new Error(
|
||||||
|
"Failed to acquire installation token and GITHUB_TOKEN is not available. Either install the Pullfrog GitHub App or ensure GITHUB_TOKEN is set."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
log.info("Using GITHUB_TOKEN (app not installed or token exchange failed)");
|
||||||
|
core2.setSecret(defaultToken);
|
||||||
|
process.env.GITHUB_INSTALLATION_TOKEN = defaultToken;
|
||||||
|
return { githubInstallationToken: defaultToken, wasAcquired: false };
|
||||||
|
}
|
||||||
|
core2.setSecret(acquiredToken);
|
||||||
|
process.env.GITHUB_INSTALLATION_TOKEN = acquiredToken;
|
||||||
|
return { githubInstallationToken: acquiredToken, wasAcquired: true };
|
||||||
}
|
}
|
||||||
async function revokeInstallationToken(token) {
|
async function revokeInstallationToken(token) {
|
||||||
const apiUrl = process.env.GITHUB_API_URL || "https://api.github.com";
|
const apiUrl = process.env.GITHUB_API_URL || "https://api.github.com";
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@pullfrog/action",
|
"name": "@pullfrog/action",
|
||||||
"version": "0.0.90",
|
"version": "0.0.92",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"files": [
|
"files": [
|
||||||
"index.js",
|
"index.js",
|
||||||
|
|||||||
+79
-23
@@ -53,7 +53,7 @@ function isGitHubActionsEnvironment(): boolean {
|
|||||||
return Boolean(process.env.GITHUB_ACTIONS);
|
return Boolean(process.env.GITHUB_ACTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function acquireTokenViaOIDC(): Promise<string> {
|
async function acquireTokenViaOIDC(): Promise<string | null> {
|
||||||
log.info("Generating OIDC token...");
|
log.info("Generating OIDC token...");
|
||||||
|
|
||||||
const oidcToken = await core.getIDToken("pullfrog-api");
|
const oidcToken = await core.getIDToken("pullfrog-api");
|
||||||
@@ -62,25 +62,47 @@ async function acquireTokenViaOIDC(): Promise<string> {
|
|||||||
const apiUrl = process.env.API_URL || "https://pullfrog.ai";
|
const apiUrl = process.env.API_URL || "https://pullfrog.ai";
|
||||||
|
|
||||||
log.info("Exchanging OIDC token for installation token...");
|
log.info("Exchanging OIDC token for installation token...");
|
||||||
const tokenResponse = await fetch(`${apiUrl}/api/github/installation-token`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${oidcToken}`,
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!tokenResponse.ok) {
|
// Add timeout to prevent long waits (5 seconds)
|
||||||
const errorText = await tokenResponse.text();
|
const timeoutMs = 5000;
|
||||||
throw new Error(
|
const controller = new AbortController();
|
||||||
`Token exchange failed: ${tokenResponse.status} ${tokenResponse.statusText} - ${errorText}`
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
||||||
);
|
|
||||||
|
try {
|
||||||
|
const tokenResponse = await fetch(`${apiUrl}/api/github/installation-token`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${oidcToken}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
signal: controller.signal,
|
||||||
|
});
|
||||||
|
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
if (!tokenResponse.ok) {
|
||||||
|
log.warning(
|
||||||
|
`Token exchange failed: ${tokenResponse.status} ${tokenResponse.statusText}. Falling back to GITHUB_TOKEN.`
|
||||||
|
);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tokenData = (await tokenResponse.json()) as InstallationToken;
|
||||||
|
log.info(`Installation token obtained for ${tokenData.repository || "all repositories"}`);
|
||||||
|
|
||||||
|
return tokenData.token;
|
||||||
|
} catch (error) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
|
||||||
|
if (error instanceof Error && error.name === "AbortError") {
|
||||||
|
log.warning(`Token exchange timed out after ${timeoutMs}ms. Falling back to GITHUB_TOKEN.`);
|
||||||
|
} else {
|
||||||
|
log.warning(
|
||||||
|
`Token exchange failed: ${error instanceof Error ? error.message : String(error)}. Falling back to GITHUB_TOKEN.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenData = (await tokenResponse.json()) as InstallationToken;
|
|
||||||
log.info(`Installation token obtained for ${tokenData.repository || "all repositories"}`);
|
|
||||||
|
|
||||||
return tokenData.token;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const base64UrlEncode = (str: string): string => {
|
const base64UrlEncode = (str: string): string => {
|
||||||
@@ -224,7 +246,7 @@ async function acquireTokenViaGitHubApp(): Promise<string> {
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function acquireNewToken(): Promise<string> {
|
async function acquireNewToken(): Promise<string | null> {
|
||||||
if (isGitHubActionsEnvironment()) {
|
if (isGitHubActionsEnvironment()) {
|
||||||
return await acquireTokenViaOIDC();
|
return await acquireTokenViaOIDC();
|
||||||
} else {
|
} else {
|
||||||
@@ -232,9 +254,28 @@ async function acquireNewToken(): Promise<string> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDefaultGitHubToken(): string | null {
|
||||||
|
// Debug: log all GITHUB_* env vars
|
||||||
|
if (isGitHubActionsEnvironment()) {
|
||||||
|
const githubEnvVars = Object.keys(process.env)
|
||||||
|
.filter((key) => key.startsWith("GITHUB_"))
|
||||||
|
.reduce(
|
||||||
|
(acc, key) => {
|
||||||
|
acc[key] = key === "GITHUB_TOKEN" ? "***" : process.env[key];
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<string, string | undefined>
|
||||||
|
);
|
||||||
|
log.debug(`GitHub env vars: ${JSON.stringify(githubEnvVars)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return process.env.GITHUB_TOKEN || null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup GitHub installation token for the action
|
* Setup GitHub installation token for the action
|
||||||
* Returns the token and whether it was acquired (needs revocation)
|
* Returns the token and whether it was acquired (needs revocation)
|
||||||
|
* Falls back to GITHUB_TOKEN if app is not installed
|
||||||
*/
|
*/
|
||||||
export async function setupGitHubInstallationToken(): Promise<{
|
export async function setupGitHubInstallationToken(): Promise<{
|
||||||
githubInstallationToken: string;
|
githubInstallationToken: string;
|
||||||
@@ -247,12 +288,27 @@ export async function setupGitHubInstallationToken(): Promise<{
|
|||||||
return { githubInstallationToken: existingToken, wasAcquired: false };
|
return { githubInstallationToken: existingToken, wasAcquired: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
const githubInstallationToken = await acquireNewToken();
|
const acquiredToken = await acquireNewToken();
|
||||||
|
|
||||||
core.setSecret(githubInstallationToken);
|
// If token acquisition failed (e.g., app not installed), fall back to GITHUB_TOKEN
|
||||||
process.env.GITHUB_INSTALLATION_TOKEN = githubInstallationToken;
|
if (!acquiredToken) {
|
||||||
|
const defaultToken = getDefaultGitHubToken();
|
||||||
|
if (!defaultToken) {
|
||||||
|
throw new Error(
|
||||||
|
"Failed to acquire installation token and GITHUB_TOKEN is not available. " +
|
||||||
|
"Either install the Pullfrog GitHub App or ensure GITHUB_TOKEN is set."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
log.info("Using GITHUB_TOKEN (app not installed or token exchange failed)");
|
||||||
|
core.setSecret(defaultToken);
|
||||||
|
process.env.GITHUB_INSTALLATION_TOKEN = defaultToken;
|
||||||
|
return { githubInstallationToken: defaultToken, wasAcquired: false };
|
||||||
|
}
|
||||||
|
|
||||||
return { githubInstallationToken, wasAcquired: true };
|
core.setSecret(acquiredToken);
|
||||||
|
process.env.GITHUB_INSTALLATION_TOKEN = acquiredToken;
|
||||||
|
|
||||||
|
return { githubInstallationToken: acquiredToken, wasAcquired: true };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user