Skip to content

Commit 2365bf5

Browse files
committed
fix embedded web ui release smoke
1 parent fa61e97 commit 2365bf5

9 files changed

Lines changed: 83 additions & 15 deletions

File tree

‎.changeset/green-bobcats-shop.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"executor": patch
3+
---
4+
5+
Fix compiled web serving so embedded UI assets are bundled into release binaries, and extend the bootstrap smoke test to verify the root web page and docs routes respond successfully.

‎.changeset/pre.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@executor/ui": "1.4.0-beta.0"
2727
},
2828
"changesets": [
29+
"green-bobcats-shop",
2930
"kind-cycles-hang",
3031
"ripe-yaks-sniff",
3132
"tiny-melons-jump"

‎apps/cli/package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "executor",
3-
"version": "1.4.0-beta.4",
3+
"version": "1.4.0-beta.5",
44
"private": true,
55
"type": "module",
66
"bin": {

‎apps/cli/src/build.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ const createEmbeddedWebUISource = async () => {
121121
// Build platform binaries
122122
// ---------------------------------------------------------------------------
123123

124+
const EMBEDDED_WEB_UI_STUB = `const files: Record<string, string> | null = null;\n\nexport default files;\n`;
125+
124126
const buildBinaries = async (targets: Target[]) => {
125127
const meta = await readMetadata();
126128
const binaries: Record<string, string> = {};
@@ -143,7 +145,7 @@ const buildBinaries = async (targets: Target[]) => {
143145
console.log(`Building ${name}...`);
144146

145147
await Bun.build({
146-
entrypoints: [join(cliRoot, "src/main.ts"), embeddedWebUIPath],
148+
entrypoints: [join(cliRoot, "src/main.ts")],
147149
minify: true,
148150
compile: {
149151
target: bunTarget(target) as any,
@@ -183,7 +185,7 @@ const buildBinaries = async (targets: Target[]) => {
183185

184186
return binaries;
185187
} finally {
186-
await rm(embeddedWebUIPath, { force: true });
188+
await writeFile(embeddedWebUIPath, EMBEDDED_WEB_UI_STUB);
187189
}
188190
};
189191

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
declare const files: Record<string, string>;
1+
declare const files: Record<string, string> | null;
22
export default files;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const files: Record<string, string> | null = null;
2+
3+
export default files;

‎apps/cli/src/main.ts‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,7 @@ const DEFAULT_PORT = 8788;
4040
const DEFAULT_BASE_URL = `http://localhost:${DEFAULT_PORT}`;
4141

4242
// Embedded web UI — baked into compiled binaries via `with { type: "file" }`
43-
const embeddedWebUI: Record<string, string> | null =
44-
await import("./embedded-web-ui.gen")
45-
.then((m) => m.default as Record<string, string>)
46-
.catch(() => null);
43+
import embeddedWebUI from "./embedded-web-ui.gen";
4744

4845
// ---------------------------------------------------------------------------
4946
// Helpers

‎bun.lock‎

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎tests/release-bootstrap-smoke.test.ts‎

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,75 @@ describe("release bootstrap smoke", () => {
161161
const installedBinaryStat = await readFile(installedBinaryPath);
162162
expect(installedBinaryStat.byteLength).toBeGreaterThan(0);
163163

164-
const secondRun = await runCommand(
164+
const probeServer = createServer((_, response) => {
165+
response.statusCode = 204;
166+
response.end();
167+
});
168+
const webPort = await listen(probeServer);
169+
await closeServer(probeServer);
170+
171+
const webProcess = spawn(
165172
process.execPath,
166-
[join(installedPackageDir, "bin", "executor"), "--help"],
167-
installedPackageDir,
173+
[join(installedPackageDir, "bin", "executor"), "web", "--port", String(webPort)],
174+
{
175+
cwd: installedPackageDir,
176+
stdio: ["ignore", "pipe", "pipe"],
177+
},
168178
);
169-
const secondCombinedOutput = `${secondRun.stdout}\n${secondRun.stderr}`;
170179

171-
expect(secondRun.exitCode, secondCombinedOutput).toBe(0);
172-
expect(secondCombinedOutput).not.toContain("downloading release asset");
180+
let webStdout = "";
181+
let webStderr = "";
182+
webProcess.stdout.setEncoding("utf8");
183+
webProcess.stdout.on("data", (chunk) => {
184+
webStdout += chunk;
185+
});
186+
webProcess.stderr.setEncoding("utf8");
187+
webProcess.stderr.on("data", (chunk) => {
188+
webStderr += chunk;
189+
});
190+
191+
try {
192+
const deadline = Date.now() + 30_000;
193+
let rootResponse: Response | null = null;
194+
while (Date.now() < deadline) {
195+
await new Promise((resolveDelay) => setTimeout(resolveDelay, 250));
196+
try {
197+
rootResponse = await fetch(`http://127.0.0.1:${webPort}/`);
198+
if (rootResponse.ok) {
199+
break;
200+
}
201+
} catch {
202+
// keep polling until the server is ready
203+
}
204+
}
205+
206+
expect(rootResponse, `${webStdout}\n${webStderr}`).not.toBeNull();
207+
expect(rootResponse!.status, `${webStdout}\n${webStderr}`).toBe(200);
208+
const rootHtml = await rootResponse!.text();
209+
expect(rootHtml.toLowerCase()).toContain("<html");
210+
211+
const docsResponse = await fetch(`http://127.0.0.1:${webPort}/docs`);
212+
expect(docsResponse.status, `${webStdout}\n${webStderr}`).toBe(200);
213+
214+
const secondRun = await runCommand(
215+
process.execPath,
216+
[join(installedPackageDir, "bin", "executor"), "--help"],
217+
installedPackageDir,
218+
);
219+
const secondCombinedOutput = `${secondRun.stdout}\n${secondRun.stderr}`;
220+
221+
expect(secondRun.exitCode, secondCombinedOutput).toBe(0);
222+
expect(secondCombinedOutput).not.toContain("downloading release asset");
223+
} finally {
224+
webProcess.kill("SIGTERM");
225+
await Promise.race([
226+
new Promise((resolveClose) => webProcess.once("close", () => resolveClose(undefined))),
227+
new Promise((resolveClose) => setTimeout(resolveClose, 5_000)),
228+
]);
229+
if (webProcess.exitCode === null) {
230+
webProcess.kill("SIGKILL");
231+
}
232+
}
173233
} finally {
174234
await closeServer(server);
175235
await rm(tempRoot, { recursive: true, force: true });

0 commit comments

Comments
 (0)