perf(ci): gate QA smoke by smoke-visible changes and isolate the prompt snapshot lane (#108202)

* perf(ci): diff-gate QA smoke by CLI import graph and isolate prompt snapshots lane

* fix(ci): run prompt snapshot lane unconditionally

* fix(ci): treat QA lane orchestration files as QA-impacting
This commit is contained in:
Peter Steinberger
2026-07-15 02:51:19 -07:00
committed by GitHub
parent 580938097f
commit 9c8a006d0c
5 changed files with 76 additions and 26 deletions

View File

@@ -56,7 +56,20 @@ describe("CI changed Node test plan", () => {
expect(hasBuildArtifactAffectingChange(["src/agents/foo.ts"])).toBe(true);
expect(hasQaSmokeAffectingChange(["extensions/qa-lab/src/ci-smoke-plan.ts"])).toBe(true);
expect(hasQaSmokeAffectingChange(["ui/src/app.ts"])).toBe(true);
expect(hasQaSmokeAffectingChange(["src/infra/retry.ts"])).toBe(false);
// Inside the packaged CLI's import graph -> the smoke scenarios can see it.
expect(hasQaSmokeAffectingChange(["src/infra/retry.ts"])).toBe(true);
// Smoke drives matrix + telegram; other channel plugins are invisible to it.
expect(hasQaSmokeAffectingChange(["extensions/telegram/src/index.ts"])).toBe(true);
expect(hasQaSmokeAffectingChange(["extensions/discord/src/index.ts"])).toBe(false);
expect(hasQaSmokeAffectingChange(["scripts/run-vitest.mjs"])).toBe(false);
expect(hasQaSmokeAffectingChange(["test/scripts/ci-node-test-plan.test.ts"])).toBe(false);
// The QA lane's own orchestration must not be able to skip the lane.
expect(hasQaSmokeAffectingChange([".github/workflows/ci.yml"])).toBe(true);
expect(hasQaSmokeAffectingChange([".github/actions/setup-node-env/action.yml"])).toBe(true);
expect(hasQaSmokeAffectingChange(["scripts/lib/ci-changed-node-test-plan.mjs"])).toBe(true);
expect(hasQaSmokeAffectingChange([".github/workflows/labeler.yml"])).toBe(false);
// Deleted source files cannot be graphed; fail safe to running QA smoke.
expect(hasQaSmokeAffectingChange(["src/infra/definitely-deleted-module.ts"])).toBe(true);
});
it("fails safe to the full plan for broad changes", () => {

View File

@@ -109,12 +109,14 @@ async function waitForChildClose(
}
describe("run-additional-boundary-checks", () => {
it("runs prompt snapshot drift checks in CI", () => {
expect(BOUNDARY_CHECKS[0]).toEqual({
label: "prompt:snapshots:check",
command: "pnpm",
args: ["prompt:snapshots:check"],
});
it("keeps prompt snapshot drift checks in their dedicated CI lane", () => {
// The snapshot check regenerates prompts with real embedded-agent turns
// (~2min); packing it into a boundary shard makes that shard the PR wall
// clock, so it owns the check-prompt-snapshots lane instead.
expect(BOUNDARY_CHECKS.some((check) => check.label === "prompt:snapshots:check")).toBe(false);
const workflow = fs.readFileSync(".github/workflows/ci.yml", "utf8");
expect(workflow).toContain("check_name: check-prompt-snapshots");
expect(workflow).toContain('run_check "prompt:snapshots:check" pnpm prompt:snapshots:check');
});
it("normalizes concurrency input", () => {