Audit core.warning/core.error usage (#269)

* Stop using command-based logs for warnings and errors

Co-authored-by: Cursor <cursoragent@cursor.com>

* revert

* tweak

* de-noise

* Remove redundant ts() timestamp prefix from log calls

* Restore timestamped logging and refine debug output routing.

Bring back timestamp prefixes for standard logs and make log.debug emit via core.debug when runner debug is enabled, while still surfacing debug lines for --debug runs.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
This commit is contained in:
pullfrog[bot]
2026-02-19 23:11:47 +00:00
committed by pullfrog[bot]
parent 4ee1ae89a5
commit 70f1c47a28
20 changed files with 296 additions and 286 deletions
+1 -1
View File
@@ -161,7 +161,7 @@ export function $git(
if (result.status !== 0) {
const stderr = result.stderr?.trim() ?? "";
log.error(`git ${subcommand} failed: ${stderr}`);
log.info(`git ${subcommand} failed: ${stderr}`);
throw new Error(`git ${subcommand} failed: ${stderr}`);
}
+20 -12
View File
@@ -6,8 +6,17 @@ import * as core from "@actions/core";
import { table } from "table";
import { isGitHubActions, isInsideDocker } from "./globals.ts";
const isDebugEnabled = () =>
process.env.LOG_LEVEL === "debug" || process.env.ACTIONS_STEP_DEBUG === "true" || core.isDebug();
const isRunnerDebugEnabled = () => core.isDebug();
const isLocalDebugEnabled = () =>
process.env.LOG_LEVEL === "debug" || process.env.ACTIONS_STEP_DEBUG === "true";
const isDebugEnabled = () => isLocalDebugEnabled() || isRunnerDebugEnabled();
/** timestamp prefix for debug mode — empty string when debug is off */
function ts(): string {
return isDebugEnabled() ? `[${new Date().toISOString()}] ` : "";
}
/**
* Format arguments into a single string for logging
@@ -206,23 +215,18 @@ 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(`${ts()}${formatArgs(args)}`);
},
/** Print warning message */
/** Print a warning message. Use only for warnings that should be displayed in the job summary. */
warning: (...args: unknown[]): void => {
core.warning(`${ts()}${formatArgs(args)}`);
},
/** Print error message */
/** Print an error message. Use only for errors that should be displayed in the job summary. */
error: (...args: unknown[]): void => {
core.error(`${ts()}${formatArgs(args)}`);
},
@@ -232,10 +236,14 @@ export const log = {
core.info(`${ts()}» ${formatArgs(args)}`);
},
/** Print debug message (only if LOG_LEVEL=debug) */
/** Print debug message (only when debug mode is enabled) */
debug: (...args: unknown[]): void => {
if (isDebugEnabled()) {
core.info(`[${new Date().toISOString()}] [DEBUG] ${formatArgs(args)}`);
if (isRunnerDebugEnabled()) {
core.debug(formatArgs(args));
return;
}
if (isLocalDebugEnabled()) {
core.info(`${ts()}[DEBUG] ${formatArgs(args)}`);
}
},
+4 -4
View File
@@ -50,7 +50,7 @@ async function validateStuckProgressComment(
return null;
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
log.error(`[post] failed to get comment ${commentId}: ${errorMessage}`);
log.info(`[post] failed to get comment ${commentId}: ${errorMessage}`);
return null;
}
}
@@ -97,7 +97,7 @@ async function getIsCancelled(params: {
}
log.info("[post] no cancellation found, assuming failure");
} catch (error) {
log.warning(
log.info(
`[post] failed to get job status: ${error instanceof Error ? error.message : String(error)}`
);
}
@@ -116,7 +116,7 @@ export async function runPostCleanup(): Promise<void> {
const resolved = resolvePromptInput();
if (typeof resolved !== "string") promptInput = resolved;
} catch (error) {
log.warning(
log.info(
`[post] failed to resolve prompt input: ${error instanceof Error ? error.message : String(error)}`
);
}
@@ -158,6 +158,6 @@ export async function runPostCleanup(): Promise<void> {
log.info("» [post] successfully updated progress comment");
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
log.error(`[post] failed to update comment: ${errorMessage}`);
log.info(`[post] failed to update comment: ${errorMessage}`);
}
}
+1 -3
View File
@@ -37,9 +37,7 @@ export async function retry<T>(fn: () => Promise<T>, options: RetryOptions = {})
}
const delay = delayMs * attempt;
log.warning(
`» ${label} failed (attempt ${attempt}/${maxAttempts}), retrying in ${delay}ms...`
);
log.info(`» ${label} failed (attempt ${attempt}/${maxAttempts}), retrying in ${delay}ms...`);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
+1 -3
View File
@@ -121,9 +121,7 @@ export async function setupGit(params: SetupGitParams): Promise<void> {
} catch (error) {
// If git config fails, log warning but don't fail the action
// This can happen if we're not in a git repo or git isn't available
log.warning(
`Failed to set git config: ${error instanceof Error ? error.message : String(error)}`
);
log.info(`Failed to set git config: ${error instanceof Error ? error.message : String(error)}`);
}
// 2. setup authentication
+1 -1
View File
@@ -157,7 +157,7 @@ export async function spawn(options: SpawnOptions): Promise<SpawnResult> {
if (idleMs > activityTimeoutMs) {
isActivityTimedOut = true;
const idleSec = Math.round(idleMs / 1000);
log.error(`no output for ${idleSec}s from pid=${child.pid} (${cmd}), killing process`);
log.info(`no output for ${idleSec}s from pid=${child.pid} (${cmd}), killing process`);
child.kill("SIGKILL");
clearInterval(activityCheckIntervalId);
}
+1 -1
View File
@@ -169,7 +169,7 @@ export async function revokeGitHubInstallationToken(token: string): Promise<void
});
log.debug("» installation token revoked");
} catch (error) {
log.warning(
log.info(
`Failed to revoke installation token: ${error instanceof Error ? error.message : String(error)}`
);
}