ci: speed up release live smoke retries

This commit is contained in:
Peter Steinberger
2026-04-29 12:33:46 +01:00
parent d8b9ace39c
commit 1446069707
7 changed files with 103 additions and 44 deletions

View File

@@ -13,7 +13,7 @@ fi
attempts="${OPENCLAW_LIVE_COMMAND_ATTEMPTS:-2}"
delay_seconds="${OPENCLAW_LIVE_COMMAND_RETRY_DELAY_SECONDS:-10}"
retry_pattern="${OPENCLAW_LIVE_COMMAND_RETRY_PATTERN:-ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|fetch failed|TLS connection|socket hang up|UND_ERR|\\b429\\b|\\b529\\b}"
retry_pattern="${OPENCLAW_LIVE_COMMAND_RETRY_PATTERN:-ECONNRESET|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|fetch failed|TLS connection|socket hang up|UND_ERR|gateway request timeout|model idle timeout|did not produce a response before the model idle timeout|\\b429\\b|\\b529\\b}"
if ! [[ "$attempts" =~ ^[1-9][0-9]*$ ]]; then
echo "OPENCLAW_LIVE_COMMAND_ATTEMPTS must be a positive integer, got: $attempts" >&2

View File

@@ -55,6 +55,16 @@ const providerConfig = {
},
};
export function resolveProviderConfig(provider, env = process.env) {
const config = providerConfig[provider];
if (!config) {
return null;
}
const providerEnvKey = `OPENCLAW_CROSS_OS_${provider.toUpperCase().replace(/[^A-Z0-9]+/gu, "_")}_MODEL`;
const model = env[providerEnvKey]?.trim() || env.OPENCLAW_CROSS_OS_MODEL?.trim() || config.model;
return { ...config, model };
}
const RELEASE_SMOKE_PLUGIN_ALLOWLIST_BASE = [
"acpx",
"bonjour",
@@ -304,7 +314,7 @@ async function main(argv) {
throw new Error(`Unsupported provider "${provider}".`);
}
const selectedProvider = providerConfig[provider];
const selectedProvider = resolveProviderConfig(provider);
const providerSecretValue = process.env[selectedProvider.secretEnv]?.trim();
if (!providerSecretValue) {
throw new Error(`Missing ${selectedProvider.secretEnv}.`);
@@ -1882,30 +1892,36 @@ async function runInstalledModelsSet(params) {
}
async function runInstalledAgentTurn(params) {
const sessionId = `cross-os-release-check-${params.label}-${Date.now()}`;
const result = await runInstalledCli({
cliPath: params.cliPath,
args: [
"agent",
"--agent",
"main",
"--session-id",
sessionId,
"--message",
"Reply with exact ASCII text OK only.",
"--thinking",
"minimal",
"--json",
],
cwd: params.cwd,
env: params.env,
logPath: params.logPath,
timeoutMs: 10 * 60 * 1000,
});
if (!agentOutputHasExpectedOkMarker(result.stdout, { logPath: params.logPath })) {
throw new Error("Agent output did not contain the expected OK marker.");
let lastError;
for (let attempt = 1; attempt <= 2; attempt += 1) {
const sessionId = `cross-os-release-check-${params.label}-${Date.now()}-${attempt}`;
try {
const result = await runInstalledCli({
cliPath: params.cliPath,
args: buildReleaseAgentTurnArgs(sessionId),
cwd: params.cwd,
env: params.env,
logPath: params.logPath,
timeoutMs: 10 * 60 * 1000,
});
if (!agentOutputHasExpectedOkMarker(result.stdout, { logPath: params.logPath })) {
throw new Error("Agent output did not contain the expected OK marker.");
}
return result;
} catch (error) {
lastError = error;
if (attempt >= 2 || !shouldRetryCrossOsAgentTurnError(error)) {
throw error;
}
appendFileSync(
params.logPath,
`\n[release-checks] retrying installed agent turn after retryable live failure: ${
error instanceof Error ? error.message : String(error)
}\n`,
);
}
}
return result;
throw lastError;
}
export function verifyDevUpdateStatus(stdout, options = {}) {
@@ -2657,18 +2673,7 @@ async function runAgentTurn(params) {
const result = await runOpenClaw({
lane: params.lane,
env: params.env,
args: [
"agent",
"--agent",
"main",
"--session-id",
sessionId,
"--message",
"Reply with exact ASCII text OK only.",
"--thinking",
"minimal",
"--json",
],
args: buildReleaseAgentTurnArgs(sessionId),
logPath: params.logPath,
timeoutMs: 10 * 60 * 1000,
});
@@ -2683,7 +2688,7 @@ async function runAgentTurn(params) {
}
appendFileSync(
params.logPath,
`\n[release-checks] retrying agent turn after bundled runtime deps staging failure: ${
`\n[release-checks] retrying agent turn after retryable live failure: ${
error instanceof Error ? error.message : String(error)
}\n`,
);
@@ -2692,9 +2697,24 @@ async function runAgentTurn(params) {
throw lastError;
}
function buildReleaseAgentTurnArgs(sessionId) {
return [
"agent",
"--agent",
"main",
"--session-id",
sessionId,
"--message",
"Reply with exact ASCII text OK only.",
"--thinking",
"minimal",
"--json",
];
}
export function shouldRetryCrossOsAgentTurnError(error) {
const message = error instanceof Error ? error.message : String(error);
return /failed to (?:install|stage) bundled runtime deps|failed to stage bundled runtime deps after/u.test(
return /failed to (?:install|stage) bundled runtime deps|failed to stage bundled runtime deps after|Agent output did not contain the expected OK marker|model idle timeout|did not produce a response before the model idle timeout/u.test(
message,
);
}