diff --git a/scripts/build/compile-binary.ts b/scripts/build/compile-binary.ts index ba57874005..1c930042fa 100644 --- a/scripts/build/compile-binary.ts +++ b/scripts/build/compile-binary.ts @@ -11,6 +11,12 @@ export const DEFAULT_INCLUDES = [ "src/platform/polyfills", "src/proxy/main.ts", "src/security/sandbox/worker-script.ts", + // Spawned through a computed sibling URL in + // src/config/declarative-evaluator-worker-runner.ts, which compile cannot + // trace. Without this the binary boots and only fails when the declarative + // config evaluator first runs, and the unhandled child-worker error takes + // the process down instead of failing the single request. + "src/config/declarative-evaluator-worker-entry.ts", "extensions/ext-auth-jwt/src/index.ts", // Explicit extensions remain inert until selected. Default extensions are // activated by the normal builtin composition when their source is embedded. diff --git a/tests/unit/build/compile-binary-includes.test.ts b/tests/unit/build/compile-binary-includes.test.ts index 0efc744b9b..2f0f9184cf 100644 --- a/tests/unit/build/compile-binary-includes.test.ts +++ b/tests/unit/build/compile-binary-includes.test.ts @@ -110,4 +110,47 @@ describe("compile-binary includes", () => { ); } }); + + it("should include every worker entrypoint under src", async () => { + // Worker entrypoints are reached through a computed sibling URL, e.g. + // `new URL(`./name-worker-entry${extension}`, import.meta.url)`, which + // deno compile's module graph cannot follow. A missing entry compiles and + // boots fine, then throws "Module not found" the first time the worker is + // spawned. The child-worker failure is unhandled, so it takes the whole + // process down rather than degrading that one request. + // + // Regression: src/config/declarative-evaluator-worker-entry.ts was absent, + // which crashlooped veryfront-server in production once traffic reached + // the declarative config evaluator. + const workerEntrypoints: string[] = []; + async function collect(dir: string): Promise { + for await (const entry of Deno.readDir(dir)) { + const path = `${dir}/${entry.name}`; + if (entry.isDirectory) { + await collect(path); + continue; + } + if (!entry.isFile || entry.name.endsWith(".test.ts")) continue; + if (/-worker-entry\.ts$|(?:^|-)worker-script\.ts$/.test(entry.name)) { + workerEntrypoints.push(path); + } + } + } + await collect("src"); + + assertEquals( + workerEntrypoints.length > 0, + true, + "expected to discover at least one worker entrypoint under src", + ); + + const includeFlags = getIncludeFlags(); + for (const entrypoint of workerEntrypoints) { + assertEquals( + includeFlags.some((path) => entrypoint === path || entrypoint.startsWith(`${path}/`)), + true, + `${entrypoint} must be in compile-binary.ts DEFAULT_INCLUDES; deno compile cannot trace the computed worker URL, so the binary crashes when the worker is spawned`, + ); + } + }); });