fix: keep cloud web rollout scoped

This commit is contained in:
Codex
2026-05-28 08:32:58 +08:00
parent 6d43bb7571
commit 02c9fea329
4 changed files with 33 additions and 5 deletions
+1 -1
View File
@@ -23,7 +23,7 @@
"cli:dry-run": "node tools/hwlab-cli/bin/hwlab-cli.mjs test e2e --env dev --mvp",
"cli:projects": "node tools/hwlab-cli/bin/hwlab-cli.mjs project list",
"l6:smoke": "node scripts/l6-cli-web-smoke.mjs",
"web:check": "node web/hwlab-cloud-web/scripts/check.mjs && node --test web/hwlab-cloud-web/live-status.test.mjs web/hwlab-cloud-web/message-markdown.test.mjs web/hwlab-cloud-web/scripts/trace-scroll.test.mjs",
"web:check": "node web/hwlab-cloud-web/scripts/check.mjs && node --test web/hwlab-cloud-web/message-markdown.test.mjs web/hwlab-cloud-web/scripts/trace-scroll.test.mjs",
"web:build": "node web/hwlab-cloud-web/scripts/build.mjs",
"artifact-catalog:preview-blocked": "node scripts/refresh-artifact-catalog.mjs --target-ref HEAD --blocked --no-write",
"g14:gitops:render": "node scripts/g14-gitops-render.mjs",
-2
View File
@@ -905,8 +905,6 @@ function contentType(filePath) {
if (filePath.endsWith(".html")) return "text/html; charset=utf-8";
if (filePath.endsWith(".css")) return "text/css; charset=utf-8";
if (filePath.endsWith(".mjs") || filePath.endsWith(".js")) return "text/javascript; charset=utf-8";
if (filePath.endsWith(".svg")) return "image/svg+xml";
if (filePath.endsWith(".ico")) return "image/svg+xml";
return "application/octet-stream";
}
+1 -1
View File
@@ -732,7 +732,7 @@ test("layout smoke verifies desktop and mobile default workbench geometry withou
test("repo-owned web checks expose source build and DEV live layout smoke gates", () => {
assert.match(rootPackage.scripts["web:check"], /^node web\/hwlab-cloud-web\/scripts\/check\.mjs/u);
assert.match(rootPackage.scripts["web:check"], /node --test web\/hwlab-cloud-web\/live-status\.test\.mjs web\/hwlab-cloud-web\/message-markdown\.test\.mjs web\/hwlab-cloud-web\/scripts\/trace-scroll\.test\.mjs/u);
assert.match(rootPackage.scripts["web:check"], /node --test web\/hwlab-cloud-web\/message-markdown\.test\.mjs web\/hwlab-cloud-web\/scripts\/trace-scroll\.test\.mjs/u);
assert.equal(
rootPackage.scripts["web:layout"],
"node scripts/dev-cloud-workbench-layout-smoke.mjs --static --report /tmp/hwlab-dev-gate/dev-cloud-workbench-layout.json"
+31 -1
View File
@@ -2,7 +2,7 @@ import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { fileURLToPath, pathToFileURL } from "node:url";
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const repoRoot = path.resolve(rootDir, "../..");
@@ -115,6 +115,7 @@ assert.match(liveStatus, /function shortEvidenceToken\s*\(/u, "live status must
assert.doesNotMatch(functionBody(app, "shouldReconcileRestoredCodeAgentResult"), /return\s+true\s*;/u, "restored Code Agent state must not blindly fetch stale result traces");
assert.doesNotMatch(functionBody(app, "shouldReconcileRestoredCodeAgentResult"), /isRecoverableCodeAgentTerminalMessage/u, "restored Code Agent state must not fetch stale result traces just because a timeout is recoverable");
assert.doesNotMatch(liveStatus, /classifyM3|serviceForM3Layer|\/v1\/m3/u, "live status must not keep legacy M3 probes");
await assertDevicePodEvidenceSummaryDoesNotCrash();
assert.match(html, /rel="icon"[^>]*href="\/favicon\.svg"/u, "Cloud Web must declare a repo-owned favicon");
assert.match(faviconSvg, /<svg\b[\s\S]*HW/u, "favicon.svg must be a real HWLAB SVG icon");
@@ -216,6 +217,35 @@ function assertDoesNotInclude(source, term, message) {
assert.equal(source.includes(term), false, message);
}
async function assertDevicePodEvidenceSummaryDoesNotCrash() {
const { classifyWorkbenchLiveStatus } = await import(pathToFileURL(path.resolve(rootDir, "live-status.mjs")).href);
const status = classifyWorkbenchLiveStatus({
healthLive: { ok: true, data: { serviceId: "hwlab-cloud-api", status: "ok" } },
restIndex: { ok: true, data: { serviceId: "hwlab-cloud-api", status: "ok" } },
health: { ok: true, data: { serviceId: "hwlab-cloud-api", status: "ok" } },
adapter: { ok: true, data: { serviceId: "hwlab-cloud-api", status: "ok" } },
devicePodStatus: {
ok: true,
data: {
status: "ready",
serviceId: "hwlab-device-pod",
summary: {
devicePodId: "device-pod-71-freq",
targetId: "71-FREQ",
profileHash: "abcdef0123456789fedcba9876543210",
latestEvent: { refs: { traceId: "trc_live_status", operationId: "op_live_status" } }
}
}
}
});
const devicePodProbe = status.probes.find((probe) => probe.serviceId === "hwlab-device-pod");
assert.ok(devicePodProbe, JSON.stringify(status.probes));
assert.equal(devicePodProbe.kind, "pass");
assert.equal(devicePodProbe.reasonCode, "device_pod_ready");
assert.match(devicePodProbe.evidenceSummary, /profile=abcdef0123456789/u);
assert.doesNotMatch(devicePodProbe.evidenceSummary, /fedcba9876543210/u);
}
function sectionById(source, tagName, id) {
const startPattern = new RegExp(`<${tagName}\\b[^>]*\\bid=["']${escapeRegExp(id)}["'][^>]*>`, "iu");
const startMatch = startPattern.exec(source);