ci: isolate legacy QA smoke invocations (#105340)

* ci: isolate legacy QA smoke invocations

* docs(agents): record PR review recommendation
This commit is contained in:
Peter Steinberger
2026-07-12 12:52:31 +01:00
committed by GitHub
parent 81941f2d68
commit 22f183f8cb
3 changed files with 17 additions and 18 deletions
+13 -17
View File
@@ -1208,7 +1208,7 @@ jobs:
} 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.
// isolate each scenario so one invocation cannot pin a profile part.
const compatibilityScenarioIds = new Set([
"control-ui-chat-flow-playwright",
"crestodian-ring-zero-setup",
@@ -1236,28 +1236,24 @@ jobs:
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) {
runs = legacyRuns.flatMap((run) =>
run.scenario_ids.flatMap((scenarioId) => {
if (!compatibilityScenarioIds.has(scenarioId)) {
continue;
return [];
}
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,
}));
});
return [
{
...run,
slug: `${run.slug}-${kind}-${scenarioId}`,
scenario_ids: [scenarioId],
},
];
}),
);
} else {
throw new Error("QA smoke plan does not expose a supported CI planner.");
}
+1
View File
@@ -195,6 +195,7 @@ Skills own workflows; root owns hard policy and routing.
- CI polling: exact SHA, relevant checks only, minimal fields. Skip routine noise (`Auto response`, `Labeler`, docs agents, performance/stale). Logs only after failure/completion or concrete need.
- Trusted-workflow release-branch CI: pass `target_ref` + `release_candidate_ref`; never `release_gate` (requires workflow head == target).
- Agent PR landing to `main`: use only the repo-native `scripts/pr` wrapper: run `scripts/pr review-init <PR>`, follow its emitted checkout/guard guidance, initialize and complete review artifacts with `scripts/pr review-artifacts-init <PR>`, validate them with `scripts/pr review-validate-artifacts <PR>`, then run `OPENCLAW_TESTBOX=1 scripts/pr prepare-run <PR>` and `scripts/pr merge-run <PR>`. The Testbox flag is mandatory for agents so prepare verifies hosted CI/Testbox on the current head or reuses a patch-identical pre-rebase run green within 24 hours instead of running full gates locally. For owner-approved reviewed fork code without hosted Testbox, use `OPENCLAW_PR_GATES_REMOTE=testbox` instead. Do not rebase only because `main` advanced; merge drift is advisory unless strict drift is explicitly enabled, while GitHub still blocks conflicts. Do not idle on `auto-response` or `check-docs`.
- `scripts/pr` review JSON: land-ready recommendation `READY FOR /prepare-pr`, `issueValidation.status=valid`; never `APPROVE`.
## Code
+3 -1
View File
@@ -2775,7 +2775,9 @@ describe("ci workflow guards", () => {
expect(smokeRunStep.run).toContain("createQaSmokeCiPart");
expect(smokeRunStep.run).toContain("createQaSmokeCiMatrix");
expect(smokeRunStep.run).toContain("readQaScenarioPack");
expect(smokeRunStep.run).toContain("scenarioIdsByKind");
expect(smokeRunStep.run).toContain("isolate each scenario");
expect(smokeRunStep.run).toContain("scenario_ids: [scenarioId]");
expect(smokeRunStep.run).not.toContain("scenarioIdsByKind");
const compatibilityScenarioBlock = smokeRunStep.run.match(
/const compatibilityScenarioIds = new Set\(\[([\s\S]*?)\]\);/u,
)?.[1];