perf(cli): skip native-binary build tests by default
The build-exe and build-exe-cross suites invoke `bun build` in beforeAll hooks and pegged CPU for ~6 min on every test run (one cached-on-miss build plus three unconditional cross-target builds). Move them to a dedicated vitest project, skip them unless CI=1 or FUSION_TEST_BUILD_EXE=1 is set, and add cache guards so CI re-runs skip rebuilds when the target binary already exists. With build-exe out of the default cli run, the main config can enable fileParallelism. Run on demand via `pnpm --filter @runfusion/fusion test:build-exe`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -42,7 +42,8 @@
|
||||
"build:exe": "bun run build.ts",
|
||||
"build:exe:all": "bun run build.ts --all",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "vitest run --silent=passed-only --reporter=dot"
|
||||
"test": "vitest run --silent=passed-only --reporter=dot",
|
||||
"test:build-exe": "FUSION_TEST_BUILD_EXE=1 vitest run --config vitest.build-exe.config.ts --silent=passed-only --reporter=dot"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fusion/pi-claude-cli": "workspace:*",
|
||||
|
||||
@@ -38,9 +38,15 @@ function nativeTarget(): string | null {
|
||||
return `bun-${platform}-${arch}`;
|
||||
}
|
||||
|
||||
describe("build-exe-cross: single target", () => {
|
||||
// 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);
|
||||
|
||||
describe.skipIf(!SHOULD_RUN_BUILD_EXE)("build-exe-cross: single target", () => {
|
||||
beforeAll(() => {
|
||||
// Build for linux-x64 specifically
|
||||
const bin = join(distDir, "fn-linux-x64");
|
||||
if (existsSync(bin)) return;
|
||||
execSync("bun run build.ts --target bun-linux-x64", {
|
||||
cwd: cliRoot,
|
||||
stdio: "pipe",
|
||||
@@ -59,8 +65,10 @@ describe("build-exe-cross: single target", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("build-exe-cross: windows target has .exe extension", () => {
|
||||
describe.skipIf(!SHOULD_RUN_BUILD_EXE)("build-exe-cross: windows target has .exe extension", () => {
|
||||
beforeAll(() => {
|
||||
const bin = join(distDir, "fn-windows-x64.exe");
|
||||
if (existsSync(bin)) return;
|
||||
execSync("bun run build.ts --target bun-windows-x64", {
|
||||
cwd: cliRoot,
|
||||
stdio: "pipe",
|
||||
@@ -75,8 +83,12 @@ describe("build-exe-cross: windows target has .exe extension", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("build-exe-cross: --all builds all platforms", () => {
|
||||
describe.skipIf(!SHOULD_RUN_BUILD_EXE)("build-exe-cross: --all builds all platforms", () => {
|
||||
beforeAll(() => {
|
||||
const allBuilt = SUPPORTED_TARGETS.every((target) =>
|
||||
existsSync(join(distDir, expectedBinaryName(target))),
|
||||
);
|
||||
if (allBuilt) return;
|
||||
execSync("bun run build.ts --all", {
|
||||
cwd: cliRoot,
|
||||
stdio: "pipe",
|
||||
@@ -147,8 +159,11 @@ describe("build-exe-cross: --all builds all platforms", () => {
|
||||
}, 60_000);
|
||||
});
|
||||
|
||||
describe("build-exe-cross: default (no args) backward compatibility", () => {
|
||||
describe.skipIf(!SHOULD_RUN_BUILD_EXE)("build-exe-cross: default (no args) backward compatibility", () => {
|
||||
beforeAll(() => {
|
||||
const defaultName = process.platform === "win32" ? "fn.exe" : "fn";
|
||||
const bin = join(distDir, defaultName);
|
||||
if (existsSync(bin)) return;
|
||||
execSync("bun run build.ts", {
|
||||
cwd: cliRoot,
|
||||
stdio: "pipe",
|
||||
|
||||
@@ -61,7 +61,12 @@ async function stopChildProcess(child: ChildProcess | null): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
describe("build-exe", () => {
|
||||
// Native-binary build tests are expensive (~2 min of pegged CPU). 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);
|
||||
|
||||
describe.skipIf(!SHOULD_RUN_BUILD_EXE)("build-exe", () => {
|
||||
beforeAll(() => {
|
||||
// Build the executable (skip if already built to speed up re-runs)
|
||||
if (!existsSync(outBinary)) {
|
||||
|
||||
34
packages/cli/vitest.build-exe.config.ts
Normal file
34
packages/cli/vitest.build-exe.config.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
// Separate project for the native-binary build tests. These invoke `bun build`
|
||||
// and can peg CPU for minutes. They are skipped by default (see skipIf guards
|
||||
// inside the test files) and run via `pnpm test:build-exe` or when CI=1 /
|
||||
// FUSION_TEST_BUILD_EXE=1 is set.
|
||||
//
|
||||
// fileParallelism is false here because both suites write to packages/cli/dist/
|
||||
// and would race each other in parallel workers.
|
||||
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: [
|
||||
{ find: /^@fusion\/core\/gh-cli$/, replacement: resolve(__dirname, "../core/src/gh-cli.ts") },
|
||||
{ find: /^@fusion\/core$/, replacement: resolve(__dirname, "../core/src/index.ts") },
|
||||
{ find: /^@fusion\/dashboard\/planning$/, replacement: resolve(__dirname, "../dashboard/src/planning.ts") },
|
||||
{ find: /^@fusion\/dashboard$/, replacement: resolve(__dirname, "../dashboard/src/index.ts") },
|
||||
{ find: /^@fusion\/engine$/, replacement: resolve(__dirname, "../engine/src/index.ts") },
|
||||
{ find: /^@fusion\/test-utils$/, replacement: resolve(__dirname, "../core/src/__test-utils__/workspace.ts") },
|
||||
],
|
||||
},
|
||||
test: {
|
||||
include: ["src/__tests__/build-exe*.test.ts"],
|
||||
setupFiles: [
|
||||
"./src/__tests__/setup-test-isolation.ts",
|
||||
resolve(__dirname, "../core/src/__test-utils__/vitest-setup.ts"),
|
||||
],
|
||||
globalSetup: [resolve(__dirname, "../core/src/__test-utils__/vitest-teardown.ts")],
|
||||
fileParallelism: false,
|
||||
testTimeout: 360_000,
|
||||
hookTimeout: 360_000,
|
||||
},
|
||||
});
|
||||
@@ -23,6 +23,10 @@ export default defineConfig({
|
||||
},
|
||||
test: {
|
||||
include: ["src/**/*.test.ts"],
|
||||
// build-exe + build-exe-cross live in their own vitest project
|
||||
// (see vitest.build-exe.config.ts) so the rest of the CLI suite can
|
||||
// run with file parallelism enabled.
|
||||
exclude: ["**/node_modules/**", "**/dist/**", "src/__tests__/build-exe*.test.ts"],
|
||||
setupFiles: [
|
||||
"./src/__tests__/setup-test-isolation.ts",
|
||||
resolve(__dirname, "../core/src/__test-utils__/vitest-setup.ts"),
|
||||
@@ -30,9 +34,7 @@ export default defineConfig({
|
||||
globalSetup: [resolve(__dirname, "../core/src/__test-utils__/vitest-teardown.ts")],
|
||||
maxWorkers,
|
||||
poolOptions: { threads: { minThreads: 1, maxThreads: maxWorkers }, forks: { minForks: 1, maxForks: maxWorkers } },
|
||||
// build-exe and build-exe-cross suites both operate on packages/cli/dist/
|
||||
// and can race when run in parallel workers.
|
||||
fileParallelism: false,
|
||||
fileParallelism: true,
|
||||
coverage: {
|
||||
enabled: false,
|
||||
reporter: ["text", "html", "json"],
|
||||
|
||||
Reference in New Issue
Block a user