feat(FN-3189): add explicit slow-lane CI gating and inline priority picker
Merges FN-3183/FN-3186 (priority picker in quick-entry box) and FN-3189 (CLI slow-lane test gating and CI lane) into the codebase. The quick-entry box gains inline priority selection, while the test suite introduces explicit slow/pre-release lane classification and a corresponding CI gate in the wor Fusion-Task-Id: FN-3189
This commit is contained in:
@@ -41,7 +41,9 @@ function nativeTarget(): string | null {
|
||||
// Cross-compiling native binaries pegs CPU for ~60s per target. Skip by
|
||||
// default locally; opt in with FUSION_TEST_BUILD_EXE=1 or run on CI.
|
||||
const SHOULD_RUN_BUILD_EXE =
|
||||
Boolean(process.env.FUSION_TEST_BUILD_EXE) || Boolean(process.env.CI);
|
||||
process.env.FUSION_TEST_BUILD_EXE === "1" ||
|
||||
process.env.FUSION_TEST_BUILD_EXE === "true" ||
|
||||
Boolean(process.env.CI);
|
||||
|
||||
describe.skipIf(!SHOULD_RUN_BUILD_EXE)("build-exe-cross: single target", () => {
|
||||
beforeAll(() => {
|
||||
|
||||
@@ -24,6 +24,10 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
|
||||
let content: string;
|
||||
let ciSteps: any[];
|
||||
let contributingContent: string;
|
||||
let cliPackageJsonContent: string;
|
||||
let extensionSuiteContent: string;
|
||||
let agentExportSuiteContent: string;
|
||||
let buildExeSuiteContent: string;
|
||||
|
||||
beforeAll(() => {
|
||||
const result = loadWorkflow("ci.yml");
|
||||
@@ -31,10 +35,26 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
|
||||
content = result.content;
|
||||
ciSteps = workflow.jobs?.ci?.steps ?? [];
|
||||
contributingContent = readFileSync(join(workspaceRoot, "docs", "contributing.md"), "utf-8");
|
||||
cliPackageJsonContent = readFileSync(join(workspaceRoot, "packages", "cli", "package.json"), "utf-8");
|
||||
extensionSuiteContent = readFileSync(
|
||||
join(workspaceRoot, "packages", "cli", "src", "__tests__", "extension.test.ts"),
|
||||
"utf-8",
|
||||
);
|
||||
agentExportSuiteContent = readFileSync(
|
||||
join(workspaceRoot, "packages", "cli", "src", "commands", "__tests__", "agent-export.test.ts"),
|
||||
"utf-8",
|
||||
);
|
||||
buildExeSuiteContent = readFileSync(
|
||||
join(workspaceRoot, "packages", "cli", "src", "__tests__", "build-exe-cross.test.ts"),
|
||||
"utf-8",
|
||||
);
|
||||
});
|
||||
|
||||
const findStepByRun = (runSnippet: string) => ciSteps.find((step) => typeof step.run === "string" && step.run.includes(runSnippet));
|
||||
|
||||
const findStepByRunExact = (runCommand: string) =>
|
||||
ciSteps.find((step) => typeof step.run === "string" && step.run.trim() === runCommand);
|
||||
|
||||
const findStepIndexByRun = (runSnippet: string) =>
|
||||
ciSteps.findIndex((step) => typeof step.run === "string" && step.run.includes(runSnippet));
|
||||
|
||||
@@ -63,33 +83,58 @@ describe("CI workflow (.github/workflows/ci.yml)", () => {
|
||||
expect(verifyStep).toBeDefined();
|
||||
expect(verifyStep.name).toContain("bootstrap contract");
|
||||
|
||||
const directLintStep = findStepByRun("pnpm lint");
|
||||
const directTestStep = findStepByRun("pnpm test");
|
||||
const directBuildStep = findStepByRun("pnpm build");
|
||||
const directLintStep = findStepByRunExact("pnpm lint");
|
||||
const directTestStep = findStepByRunExact("pnpm test");
|
||||
const directBuildStep = findStepByRunExact("pnpm build");
|
||||
expect(directLintStep).toBeUndefined();
|
||||
expect(directTestStep).toBeUndefined();
|
||||
expect(directBuildStep).toBeUndefined();
|
||||
});
|
||||
|
||||
it("runs workspace verification before binary packaging", () => {
|
||||
it("runs workspace verification before slow lane and binary packaging", () => {
|
||||
const verifyIdx = findStepIndexByRun("pnpm verify:workspace");
|
||||
const slowLaneIdx = findStepIndexByRun("pnpm test:slow-cli");
|
||||
const buildExeIdx = findStepIndexByRun("build:exe");
|
||||
expect(verifyIdx).toBeGreaterThanOrEqual(0);
|
||||
expect(buildExeIdx).toBeGreaterThan(verifyIdx);
|
||||
expect(slowLaneIdx).toBeGreaterThan(verifyIdx);
|
||||
expect(buildExeIdx).toBeGreaterThan(slowLaneIdx);
|
||||
});
|
||||
|
||||
it("keeps contributing docs aligned with the clean-worktree verification contract", () => {
|
||||
it("keeps contributing docs aligned with verification and slow-lane contracts", () => {
|
||||
expect(contributingContent).toContain("pnpm test` must be runnable in a clean worktree without requiring a prior `pnpm build`.");
|
||||
expect(contributingContent).toContain("`pnpm verify:workspace` is the canonical pre-merge gate");
|
||||
expect(contributingContent).toContain("1. `pnpm lint`");
|
||||
expect(contributingContent).toContain("2. `pnpm test`");
|
||||
expect(contributingContent).toContain("3. `pnpm build`");
|
||||
|
||||
expect(contributingContent).toContain("pnpm test:slow-cli");
|
||||
expect(contributingContent).toContain("test:pre-release");
|
||||
expect(contributingContent).toContain("test:extension-integration");
|
||||
});
|
||||
|
||||
it("includes binary build step", () => {
|
||||
expect(content).toContain("build:exe");
|
||||
});
|
||||
|
||||
it("keeps explicit gating for audited CLI integration suites", () => {
|
||||
expect(cliPackageJsonContent).toContain('"test:slow-cli"');
|
||||
expect(cliPackageJsonContent).toContain("FUSION_TEST_SLOW_CLI=1");
|
||||
expect(cliPackageJsonContent).toContain('"test:extension-integration"');
|
||||
expect(cliPackageJsonContent).toContain("FUSION_TEST_EXTENSION_INTEGRATION=1");
|
||||
expect(cliPackageJsonContent).toContain('"test:build-exe"');
|
||||
expect(cliPackageJsonContent).toContain("FUSION_TEST_BUILD_EXE=1");
|
||||
|
||||
expect(extensionSuiteContent).toContain("describe.skipIf(!SHOULD_RUN_EXTENSION_INTEGRATION)");
|
||||
expect(extensionSuiteContent).toContain("FUSION_TEST_EXTENSION_INTEGRATION");
|
||||
|
||||
expect(agentExportSuiteContent).toContain("describe.skipIf(!SHOULD_RUN_SLOW_CLI)");
|
||||
expect(agentExportSuiteContent).toContain("FUSION_TEST_SLOW_CLI");
|
||||
|
||||
expect(buildExeSuiteContent).toContain('process.env.FUSION_TEST_BUILD_EXE === "1"');
|
||||
expect(buildExeSuiteContent).toContain('process.env.FUSION_TEST_BUILD_EXE === "true"');
|
||||
expect(buildExeSuiteContent).not.toContain("Boolean(process.env.FUSION_TEST_BUILD_EXE)");
|
||||
});
|
||||
|
||||
it("includes Bun setup", () => {
|
||||
expect(content).toContain("oven-sh/setup-bun");
|
||||
});
|
||||
|
||||
@@ -118,12 +118,15 @@ async function removeDirWithRetries(path: string) {
|
||||
|
||||
// ── Tests ──────────────────────────────────────────────────────────
|
||||
|
||||
// Skipped: 39 tests × ~1-4s each (~62s total) exercise every fn pi tool
|
||||
// through the real ExtensionAPI + TaskStore/MissionStore stack with
|
||||
// per-test temp workspaces. Coverage overlaps with command-level tests
|
||||
// (task.test.ts, mission-related suites). Re-enable for full pre-release
|
||||
// validation or when adding new extension tools.
|
||||
describe.skip("fn pi extension", () => {
|
||||
// Audited in FN-3189: this suite is expensive (~62s) and currently stale
|
||||
// against modern extension behavior/tooling (see FN-3204). Keep an explicit,
|
||||
// discoverable gate so it never silently disappears behind unconditional skip,
|
||||
// but do not include it in the default slow lane until the failures are fixed.
|
||||
const SHOULD_RUN_EXTENSION_INTEGRATION =
|
||||
process.env.FUSION_TEST_EXTENSION_INTEGRATION === "1" ||
|
||||
process.env.FUSION_TEST_EXTENSION_INTEGRATION === "true";
|
||||
|
||||
describe.skipIf(!SHOULD_RUN_EXTENSION_INTEGRATION)("fn pi extension", () => {
|
||||
let tmpDir: string;
|
||||
let api: ReturnType<typeof createMockAPI>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user