ci: bound legacy QA smoke compatibility (#105213)

This commit is contained in:
Peter Steinberger
2026-07-12 10:15:33 +01:00
committed by GitHub
parent def7b51899
commit d79373fa14
2 changed files with 55 additions and 1 deletions
+46 -1
View File
@@ -1198,13 +1198,58 @@ jobs:
if (typeof smokePlan.createQaSmokeCiPart === "function") {
runs = smokePlan.createQaSmokeCiPart(partId).runs;
} else if (typeof smokePlan.createQaSmokeCiMatrix === "function") {
// Legacy planners select the entire profile and can mix long-lived
// execution kinds. Reuse the current bounded smoke contract and
// isolate each kind so frozen targets cannot pin a profile part.
const compatibilityScenarioIds = new Set([
"control-ui-chat-flow-playwright",
"crestodian-ring-zero-setup",
"dreaming-shadow-trial-report",
"gateway-smoke",
"group-visible-reply-tool",
"long-running-release-audit",
"luna-thinking-visibility-switch",
"matrix-restart-resume",
"personal-task-followthrough-status",
"plugin-lifecycle-hot-reload",
"subagent-completion-direct-fallback",
"telegram-commands-command",
]);
const partIndex = partId === "profile-1" ? 0 : partId === "profile-2" ? 1 : -1;
if (partIndex < 0) {
throw new Error(`unknown QA smoke CI profile part: ${partId}`);
}
runs = smokePlan
const scenarioCatalog = await import("./extensions/qa-lab/src/scenario-catalog.ts");
const scenarioKindById = new Map(
scenarioCatalog
.readQaScenarioPack()
.scenarios.map((scenario) => [scenario.id, scenario.execution.kind]),
);
const legacyRuns = smokePlan
.createQaSmokeCiMatrix()
.include.filter((_, index) => index % 2 === partIndex);
runs = legacyRuns.flatMap((run) => {
const scenarioIdsByKind = new Map();
for (const scenarioId of run.scenario_ids) {
if (!compatibilityScenarioIds.has(scenarioId)) {
continue;
}
const kind = scenarioKindById.get(scenarioId);
if (!kind) {
throw new Error(`legacy QA smoke scenario not found: ${scenarioId}`);
}
const scenarioIds = scenarioIdsByKind.get(kind) ?? [];
scenarioIds.push(scenarioId);
scenarioIdsByKind.set(kind, scenarioIds);
}
return [...scenarioIdsByKind.entries()]
.toSorted(([left], [right]) => left.localeCompare(right))
.map(([kind, scenarioIds]) => ({
...run,
slug: `${run.slug}-${kind}`,
scenario_ids: scenarioIds,
}));
});
} else {
throw new Error("QA smoke plan does not expose a supported CI planner.");
}
+9
View File
@@ -2675,6 +2675,15 @@ describe("ci workflow guards", () => {
expect(smokeProfileJob["runs-on"]).toContain("blacksmith-16vcpu-ubuntu-2404");
expect(smokeRunStep.run).toContain("createQaSmokeCiPart");
expect(smokeRunStep.run).toContain("createQaSmokeCiMatrix");
expect(smokeRunStep.run).toContain("readQaScenarioPack");
expect(smokeRunStep.run).toContain("scenarioIdsByKind");
const compatibilityScenarioBlock = smokeRunStep.run.match(
/const compatibilityScenarioIds = new Set\(\[([\s\S]*?)\]\);/u,
)?.[1];
expect(compatibilityScenarioBlock?.match(/^\s+"[^"]+",$/gmu)).toHaveLength(12);
expect(compatibilityScenarioBlock).toContain('"control-ui-chat-flow-playwright"');
expect(compatibilityScenarioBlock).toContain('"gateway-smoke"');
expect(compatibilityScenarioBlock).toContain('"matrix-restart-resume"');
expect(smokeRunStep.run).toContain("No QA smoke runs assigned");
expect(smokeRunStep.run).toContain("node openclaw.mjs qa run");
expect(smokeRunStep.run).not.toContain("pnpm openclaw qa run");