Clean up url resolution
This commit is contained in:
committed by
pullfrog[bot]
parent
267a4586ae
commit
78cf05f111
@@ -1,8 +1,21 @@
|
||||
import { performance } from "node:perf_hooks";
|
||||
import * as core from "@actions/core";
|
||||
|
||||
export const DEFAULT_ACTIVITY_TIMEOUT_MS = 60_000;
|
||||
export const DEFAULT_ACTIVITY_CHECK_INTERVAL_MS = 5_000;
|
||||
|
||||
// inline debug check — can't import log.ts since activity.ts is a dependency of it
|
||||
function debugLog(msg: string): void {
|
||||
const isDebug =
|
||||
process.env.LOG_LEVEL === "debug" ||
|
||||
process.env.ACTIONS_STEP_DEBUG === "true" ||
|
||||
process.env.RUNNER_DEBUG === "1" ||
|
||||
core.isDebug();
|
||||
if (isDebug) {
|
||||
core.info(`[${new Date().toISOString()}] [DEBUG] ${msg}`);
|
||||
}
|
||||
}
|
||||
|
||||
type ActivityTimeoutContext = {
|
||||
timeoutMs: number;
|
||||
checkIntervalMs: number;
|
||||
@@ -72,8 +85,11 @@ function startProcessOutputMonitor(ctx: OutputMonitorContext): OutputMonitor {
|
||||
process.stdout.write = wrapWrite(originalStdoutWrite, markActivity);
|
||||
process.stderr.write = wrapWrite(originalStderrWrite, markActivity);
|
||||
|
||||
debugLog(`process activity monitor started: timeout=${ctx.timeoutMs}ms`);
|
||||
|
||||
const intervalId = setInterval(() => {
|
||||
const idleMs = getIdleMs();
|
||||
debugLog(`process activity check: idle=${idleMs}ms / ${ctx.timeoutMs}ms`);
|
||||
if (timedOut || idleMs <= ctx.timeoutMs) return;
|
||||
timedOut = true;
|
||||
ctx.onTimeout(idleMs);
|
||||
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
import type { Agent } from "../agents/index.ts";
|
||||
import { getApiUrl } from "./apiUrl.ts";
|
||||
|
||||
/**
|
||||
* Build a helpful error message for missing API key with links to repo settings
|
||||
*/
|
||||
function buildMissingApiKeyError(params: { agent: Agent; owner: string; name: string }): string {
|
||||
const apiUrl = process.env.API_URL || "https://pullfrog.com";
|
||||
const apiUrl = getApiUrl();
|
||||
const settingsUrl = `${apiUrl}/console/${params.owner}/${params.name}`;
|
||||
|
||||
const githubRepoUrl = `https://github.com/${params.owner}/${params.name}`;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* resolve the Pullfrog API base URL.
|
||||
*
|
||||
* in the action: API_URL is not explicitly set, so this falls back to https://pullfrog.com.
|
||||
* in local dev: API_URL=http://localhost:3000 (from .env).
|
||||
*/
|
||||
export function getApiUrl(): string {
|
||||
return process.env.API_URL || "https://pullfrog.com";
|
||||
}
|
||||
+2
-1
@@ -2,6 +2,7 @@ import { createSign } from "node:crypto";
|
||||
import * as core from "@actions/core";
|
||||
import { throttling } from "@octokit/plugin-throttling";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { getApiUrl } from "./apiUrl.ts";
|
||||
import { retry } from "./retry.ts";
|
||||
|
||||
export interface InstallationToken {
|
||||
@@ -84,7 +85,7 @@ type AcquireTokenOptions = {
|
||||
async function acquireTokenViaOIDC(opts?: AcquireTokenOptions): Promise<string> {
|
||||
const oidcToken = await core.getIDToken("pullfrog-api");
|
||||
|
||||
const apiUrl = process.env.API_URL || "https://pullfrog.com";
|
||||
const apiUrl = getApiUrl();
|
||||
const params = new URLSearchParams();
|
||||
|
||||
// ensure the token covers GITHUB_REPOSITORY (may differ from OIDC claims repo)
|
||||
|
||||
+11
-10
@@ -206,31 +206,36 @@ function separator(length: number = 50): void {
|
||||
/**
|
||||
* Main logging utility object - import this once and access all utilities
|
||||
*/
|
||||
/** timestamp prefix for debug mode — empty string when debug is off */
|
||||
function ts(): string {
|
||||
return isDebugEnabled() ? `[${new Date().toISOString()}] ` : "";
|
||||
}
|
||||
|
||||
export const log = {
|
||||
/** Print info message */
|
||||
info: (...args: unknown[]): void => {
|
||||
core.info(formatArgs(args));
|
||||
core.info(`${ts()}${formatArgs(args)}`);
|
||||
},
|
||||
|
||||
/** Print warning message */
|
||||
warning: (...args: unknown[]): void => {
|
||||
core.warning(formatArgs(args));
|
||||
core.warning(`${ts()}${formatArgs(args)}`);
|
||||
},
|
||||
|
||||
/** Print error message */
|
||||
error: (...args: unknown[]): void => {
|
||||
core.error(formatArgs(args));
|
||||
core.error(`${ts()}${formatArgs(args)}`);
|
||||
},
|
||||
|
||||
/** Print success message */
|
||||
success: (...args: unknown[]): void => {
|
||||
core.info(`» ${formatArgs(args)}`);
|
||||
core.info(`${ts()}» ${formatArgs(args)}`);
|
||||
},
|
||||
|
||||
/** Print debug message (only if LOG_LEVEL=debug) */
|
||||
debug: (...args: unknown[]): void => {
|
||||
if (isDebugEnabled()) {
|
||||
core.info(`[DEBUG] ${formatArgs(args)}`);
|
||||
core.info(`[${new Date().toISOString()}] [DEBUG] ${formatArgs(args)}`);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -255,11 +260,7 @@ export const log = {
|
||||
/** Log tool call information to console with formatted output */
|
||||
toolCall: ({ toolName, input }: { toolName: string; input: unknown }): void => {
|
||||
const inputFormatted = formatJsonValue(input);
|
||||
const timestamp = isDebugEnabled() ? ` [${new Date().toISOString()}]` : "";
|
||||
const output =
|
||||
inputFormatted !== "{}"
|
||||
? `» ${toolName}(${inputFormatted})${timestamp}`
|
||||
: `» ${toolName}()${timestamp}`;
|
||||
const output = inputFormatted !== "{}" ? `» ${toolName}(${inputFormatted})` : `» ${toolName}()`;
|
||||
|
||||
log.info(output.trimEnd());
|
||||
},
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
import type { AgentName, BashPermission, PushPermission, ToolPermission } from "../external.ts";
|
||||
import { getApiUrl } from "./apiUrl.ts";
|
||||
import type { RepoContext } from "./github.ts";
|
||||
|
||||
export interface Mode {
|
||||
@@ -51,7 +52,7 @@ export async function fetchRunContext(params: {
|
||||
token: string;
|
||||
repoContext: RepoContext;
|
||||
}): Promise<RunContext> {
|
||||
const apiUrl = process.env.API_URL || "https://pullfrog.com";
|
||||
const apiUrl = getApiUrl();
|
||||
const timeoutMs = 30000;
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
||||
|
||||
+5
-1
@@ -148,12 +148,16 @@ export async function spawn(options: SpawnOptions): Promise<SpawnResult> {
|
||||
|
||||
// activity timeout: kill if no output for too long
|
||||
if (activityTimeoutMs > 0) {
|
||||
log.debug(`spawn activity timer: pid=${child.pid} cmd=${cmd} timeout=${activityTimeoutMs}ms`);
|
||||
activityCheckIntervalId = setInterval(() => {
|
||||
const idleMs = performance.now() - lastActivityTime;
|
||||
log.debug(
|
||||
`spawn activity check: pid=${child.pid} idle=${Math.round(idleMs)}ms / ${activityTimeoutMs}ms`
|
||||
);
|
||||
if (idleMs > activityTimeoutMs) {
|
||||
isActivityTimedOut = true;
|
||||
const idleSec = Math.round(idleMs / 1000);
|
||||
log.error(`no output for ${idleSec}s, killing process`);
|
||||
log.error(`no output for ${idleSec}s from pid=${child.pid} (${cmd}), killing process`);
|
||||
child.kill("SIGKILL");
|
||||
clearInterval(activityCheckIntervalId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user