fix(web-probe): harden sentinel dashboard validation

This commit is contained in:
Codex
2026-06-26 17:50:52 +00:00
parent 1599367eeb
commit f6225f0e12
3 changed files with 196 additions and 50 deletions
+29 -13
View File
@@ -87,21 +87,33 @@ export async function runSshPlaywrightOperation(
for (const artifact of manifest.artifacts) {
const localPath = join(localDir, `${runId}-${safePathSegment(basename(artifact.remotePath) || "artifact")}`);
try {
const download = await downloadSshFileVerified(
invocation,
executor,
builders,
artifact.remotePath,
localPath,
options.inactivityTimeoutMs,
);
artifacts.push({ ...download, manifestBytes: artifact.bytes, manifestSha256: artifact.sha256 });
} catch (error) {
const maxAttempts = 3;
let downloaded = false;
let lastError: unknown = null;
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
try {
const download = await downloadSshFileVerified(
invocation,
executor,
builders,
artifact.remotePath,
localPath,
options.inactivityTimeoutMs,
);
artifacts.push({ ...download, manifestBytes: artifact.bytes, manifestSha256: artifact.sha256 });
downloaded = true;
break;
} catch (error) {
lastError = error;
if (attempt < maxAttempts) await sleep(750 * attempt);
}
}
if (!downloaded) {
downloadFailure = {
remotePath: artifact.remotePath,
message: error instanceof Error ? error.message : String(error),
name: error instanceof Error ? error.name : undefined,
attempts: maxAttempts,
message: lastError instanceof Error ? lastError.message : String(lastError),
name: lastError instanceof Error ? lastError.name : undefined,
};
break;
}
@@ -536,6 +548,10 @@ function decodeBase64(value: string): string {
}
}
function sleep(ms: number): Promise<void> {
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
}
function safePathSegment(value: string): string {
const cleaned = value.replace(/[^A-Za-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
return cleaned.length > 0 ? cleaned.slice(0, 120) : "artifact";