feat(FN-3262): harden CLI native bundle externalization with tests
The merge adds Step 2 of the native externalization hardening for the CLI package, including a minor changeset for `@runfusion/fusion` and tests validating bundle output and package configuration behavior. The changes strengthen the contract governing how native modules are handled during the build Fusion-Task-Id: FN-3262
This commit is contained in:
5
.changeset/fn-3262-cli-native-build-hardening.md
Normal file
5
.changeset/fn-3262-cli-native-build-hardening.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@runfusion/fusion": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Hardened CLI packaging against native module build regressions by asserting `dockerode`/`ssh2`/`cpu-features` remain externalized in tsup bundle config, preventing native `.node` artifact strings from being inlined into the bundle, and declaring `dockerode` as a runtime dependency for published installs.
|
||||||
@@ -57,6 +57,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mariozechner/pi-ai": "^0.72.1",
|
"@mariozechner/pi-ai": "^0.72.1",
|
||||||
"@mariozechner/pi-coding-agent": "^0.72.1",
|
"@mariozechner/pi-coding-agent": "^0.72.1",
|
||||||
|
"dockerode": "^4.0.12",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
"ink": "^6.8.0",
|
"ink": "^6.8.0",
|
||||||
"ink-spinner": "^5.0.0",
|
"ink-spinner": "^5.0.0",
|
||||||
|
|||||||
@@ -80,6 +80,14 @@ describe("CLI bundle output", () => {
|
|||||||
expect(tsupConfig).toContain("cpSync(dashboardClientSrc, dashboardClientDest, { recursive: true });");
|
expect(tsupConfig).toContain("cpSync(dashboardClientSrc, dashboardClientDest, { recursive: true });");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps native module loaders externalized in tsup config", () => {
|
||||||
|
const tsupConfig = readFileSync(tsupConfigPath, "utf-8");
|
||||||
|
|
||||||
|
expect(tsupConfig).toContain('"dockerode"');
|
||||||
|
expect(tsupConfig).toContain('"ssh2"');
|
||||||
|
expect(tsupConfig).toContain('"cpu-features"');
|
||||||
|
});
|
||||||
|
|
||||||
it("loads sqlite from Node built-ins and never from bare sqlite npm package", () => {
|
it("loads sqlite from Node built-ins and never from bare sqlite npm package", () => {
|
||||||
const content = readFileSync(bundlePath, "utf-8");
|
const content = readFileSync(bundlePath, "utf-8");
|
||||||
// The bundle must resolve sqlite through Node's built-in module.
|
// The bundle must resolve sqlite through Node's built-in module.
|
||||||
@@ -89,6 +97,12 @@ describe("CLI bundle output", () => {
|
|||||||
expect(content).not.toMatch(/from\s+["']sqlite["'][^s]/);
|
expect(content).not.toMatch(/from\s+["']sqlite["'][^s]/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not inline native artifact filenames into the bundled CLI", () => {
|
||||||
|
const content = readFileSync(bundlePath, "utf-8");
|
||||||
|
expect(content).not.toContain("sshcrypto.node");
|
||||||
|
expect(content).not.toContain("cpufeatures.node");
|
||||||
|
});
|
||||||
|
|
||||||
it("provides require via createRequire banner", () => {
|
it("provides require via createRequire banner", () => {
|
||||||
const content = readFileSync(bundlePath, "utf-8");
|
const content = readFileSync(bundlePath, "utf-8");
|
||||||
// Banner should inject createRequire for ESM CJS interop
|
// Banner should inject createRequire for ESM CJS interop
|
||||||
|
|||||||
@@ -78,6 +78,14 @@ describe("CLI package.json publishing config", () => {
|
|||||||
const deps = Object.keys(pkg.dependencies || {});
|
const deps = Object.keys(pkg.dependencies || {});
|
||||||
expect(deps).toContain("ioredis");
|
expect(deps).toContain("ioredis");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("declares dockerode as a runtime dependency when kept external in CLI bundling", () => {
|
||||||
|
const deps = Object.keys(pkg.dependencies || {});
|
||||||
|
const devDeps = Object.keys(pkg.devDependencies || {});
|
||||||
|
|
||||||
|
expect(deps).toContain("dockerode");
|
||||||
|
expect(devDeps).not.toContain("dockerode");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Scoped @fusion/* packages publishing config", () => {
|
describe("Scoped @fusion/* packages publishing config", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user