Skip to content

Commit 276ddc3

Browse files
committed
add SEA fuse more reliably
1 parent 245dcf9 commit 276ddc3

2 files changed

Lines changed: 54 additions & 6 deletions

File tree

packages/server-v3/scripts/build-sea.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import esbuild from "esbuild";
2323
import { getRepoRootDir } from "./runtimePaths.js";
2424

2525
const repoDir = getRepoRootDir();
26+
const seaFuse = "NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2";
2627

2728
const argValue = (name: string) => {
2829
const prefix = `--${name}=`;
@@ -119,6 +120,14 @@ const runOptional = (
119120
spawnSync(cmd, args, { stdio: "ignore", ...opts });
120121
};
121122

123+
const hasSeaFuse = (binaryPath: string): boolean => {
124+
try {
125+
return fs.readFileSync(binaryPath).includes(Buffer.from(seaFuse));
126+
} catch {
127+
return false;
128+
}
129+
};
130+
122131
const download = (url: string, dest: string): Promise<void> =>
123132
new Promise((resolve, reject) => {
124133
https
@@ -167,15 +176,20 @@ const resolveNodeBinary = async (): Promise<string> => {
167176
`Cross-platform builds are not supported. Host=${process.platform}, target=${targetPlatform}`,
168177
);
169178
}
170-
if (targetArch === process.arch) {
179+
if (targetArch === process.arch && hasSeaFuse(process.execPath)) {
171180
return process.execPath;
172181
}
182+
if (targetArch === process.arch) {
183+
console.warn(
184+
`Current Node binary at ${process.execPath} does not include ${seaFuse}; falling back to the official ${process.version} distribution for SEA injection.`,
185+
);
186+
}
173187

174188
const version = process.version;
175189
const distPlatform = targetPlatform === "win32" ? "win" : targetPlatform;
176190
const archiveBase = `node-${version}-${distPlatform}-${targetArch}`;
177191
const archiveExt = distPlatform === "win" ? "zip" : "tar.xz";
178-
const tmpRoot = `${os.tmpdir()}/stagehand-sea/${archiveBase}`;
192+
const tmpRoot = `${os.tmpdir()}/stagehand-server-v3-sea/${archiveBase}`;
179193
const archivePath = `${tmpRoot}/${archiveBase}.${archiveExt}`;
180194
const extractRoot = `${tmpRoot}/${archiveBase}`;
181195
const binaryPath =
@@ -184,6 +198,11 @@ const resolveNodeBinary = async (): Promise<string> => {
184198
: `${extractRoot}/bin/node`;
185199

186200
if (fs.existsSync(binaryPath)) {
201+
if (!hasSeaFuse(binaryPath)) {
202+
throw new Error(
203+
`Node binary at ${binaryPath} does not include ${seaFuse}; unable to build SEA binary.`,
204+
);
205+
}
187206
return binaryPath;
188207
}
189208

@@ -208,6 +227,11 @@ const resolveNodeBinary = async (): Promise<string> => {
208227
if (!fs.existsSync(binaryPath)) {
209228
throw new Error(`Missing Node binary at ${binaryPath}`);
210229
}
230+
if (!hasSeaFuse(binaryPath)) {
231+
throw new Error(
232+
`Node binary at ${binaryPath} does not include ${seaFuse}; unable to build SEA binary.`,
233+
);
234+
}
211235
return binaryPath;
212236
};
213237

@@ -477,7 +501,7 @@ const main = async () => {
477501
"NODE_SEA_BLOB",
478502
`${repoDir}/packages/server-v3/dist/sea/sea-prep.blob`,
479503
"--sentinel-fuse",
480-
"NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2",
504+
seaFuse,
481505
];
482506
if (targetPlatform === "darwin") {
483507
postjectArgs.push("--macho-segment-name", "NODE_SEA");

packages/server-v4/scripts/build-sea.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import esbuild from "esbuild";
2323
import { getRepoRootDir } from "./runtimePaths.js";
2424

2525
const repoDir = getRepoRootDir();
26+
const seaFuse = "NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2";
2627

2728
const argValue = (name: string) => {
2829
const prefix = `--${name}=`;
@@ -119,6 +120,14 @@ const runOptional = (
119120
spawnSync(cmd, args, { stdio: "ignore", ...opts });
120121
};
121122

123+
const hasSeaFuse = (binaryPath: string): boolean => {
124+
try {
125+
return fs.readFileSync(binaryPath).includes(Buffer.from(seaFuse));
126+
} catch {
127+
return false;
128+
}
129+
};
130+
122131
const download = (url: string, dest: string): Promise<void> =>
123132
new Promise((resolve, reject) => {
124133
https
@@ -167,15 +176,20 @@ const resolveNodeBinary = async (): Promise<string> => {
167176
`Cross-platform builds are not supported. Host=${process.platform}, target=${targetPlatform}`,
168177
);
169178
}
170-
if (targetArch === process.arch) {
179+
if (targetArch === process.arch && hasSeaFuse(process.execPath)) {
171180
return process.execPath;
172181
}
182+
if (targetArch === process.arch) {
183+
console.warn(
184+
`Current Node binary at ${process.execPath} does not include ${seaFuse}; falling back to the official ${process.version} distribution for SEA injection.`,
185+
);
186+
}
173187

174188
const version = process.version;
175189
const distPlatform = targetPlatform === "win32" ? "win" : targetPlatform;
176190
const archiveBase = `node-${version}-${distPlatform}-${targetArch}`;
177191
const archiveExt = distPlatform === "win" ? "zip" : "tar.xz";
178-
const tmpRoot = `${os.tmpdir()}/stagehand-sea/${archiveBase}`;
192+
const tmpRoot = `${os.tmpdir()}/stagehand-server-v4-sea/${archiveBase}`;
179193
const archivePath = `${tmpRoot}/${archiveBase}.${archiveExt}`;
180194
const extractRoot = `${tmpRoot}/${archiveBase}`;
181195
const binaryPath =
@@ -184,6 +198,11 @@ const resolveNodeBinary = async (): Promise<string> => {
184198
: `${extractRoot}/bin/node`;
185199

186200
if (fs.existsSync(binaryPath)) {
201+
if (!hasSeaFuse(binaryPath)) {
202+
throw new Error(
203+
`Node binary at ${binaryPath} does not include ${seaFuse}; unable to build SEA binary.`,
204+
);
205+
}
187206
return binaryPath;
188207
}
189208

@@ -208,6 +227,11 @@ const resolveNodeBinary = async (): Promise<string> => {
208227
if (!fs.existsSync(binaryPath)) {
209228
throw new Error(`Missing Node binary at ${binaryPath}`);
210229
}
230+
if (!hasSeaFuse(binaryPath)) {
231+
throw new Error(
232+
`Node binary at ${binaryPath} does not include ${seaFuse}; unable to build SEA binary.`,
233+
);
234+
}
211235
return binaryPath;
212236
};
213237

@@ -477,7 +501,7 @@ const main = async () => {
477501
"NODE_SEA_BLOB",
478502
`${repoDir}/packages/server-v4/dist/sea/sea-prep.blob`,
479503
"--sentinel-fuse",
480-
"NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2",
504+
seaFuse,
481505
];
482506
if (targetPlatform === "darwin") {
483507
postjectArgs.push("--macho-segment-name", "NODE_SEA");

0 commit comments

Comments
 (0)