fix(build): preserve resource controls in strict Turbo tasks (#1809)

This commit is contained in:
Ysopwnable
2026-10-11 19:50:50 +08:00
committed by GitHub
parent ffaf2c12f1
commit 2e22330037
3 changed files with 49 additions and 4 deletions
+5
View File
@@ -945,6 +945,11 @@ it or select another revision.
Source typechecking needs no compiled runtime or generated test metadata.
`npm run build:cached` compiles the CLI/MCP runtime and its packaged skill.
Turbo's strict task environment preserves caller-selected `GOMAXPROCS`,
`GOMEMLIMIT`, and `UV_THREADPOOL_SIZE` for resource-constrained builds and
checks. These execution controls do not change artifact content, so changing
their values retains cache reuse. They control individual runtimes; monitor
the complete process family separately when enforcing a total memory budget.
`npm run test:prepare` also generates the MCP contract test catalog, product
catalog, and portable managed evidence used by the complete suite. Focused
tests prepare those extra outputs only when their selected files consume them.
@@ -141,6 +141,39 @@ describe("dependency install freshness", () => {
expect(cached.status, cached.stderr).toBe(0);
expect(`${cached.stdout}${cached.stderr}`).toMatch(/cache hit/u);
}, 60_000);
it("preserves caller resource controls in strict cached builds without hashing their values", async () => {
const root = await createBuildCacheFixture();
const environment = {
...process.env,
TURBO_ENV_MODE: "strict",
GOMAXPROCS: "1",
GOMEMLIMIT: "384MiB",
UV_THREADPOOL_SIZE: "2",
REA_TEST_UNLISTED_ENV: "filtered",
};
const built = await runNpm(root, ["run", "build:cached"], environment);
expect(built.status, `${built.stdout}${built.stderr}`).toBe(0);
expect(
JSON.parse(await readFile(join(root, "resource-controls.json"), "utf8")),
).toEqual({
GOMAXPROCS: "1",
GOMEMLIMIT: "384MiB",
UV_THREADPOOL_SIZE: "2",
REA_TEST_UNLISTED_ENV: null,
});
const cached = await runTurbo(root, {
...environment,
GOMAXPROCS: "2",
GOMEMLIMIT: "512MiB",
UV_THREADPOOL_SIZE: "4",
});
expect(cached.status, `${cached.stdout}${cached.stderr}`).toBe(0);
expect(`${cached.stdout}${cached.stderr}`).toMatch(/cache hit/u);
expect(`${cached.stdout}${cached.stderr}`).not.toMatch(/cache miss/u);
}, 60_000);
});
const createBuildCacheFixture = async (): Promise<string> => {
@@ -192,6 +225,7 @@ const createBuildCacheFixture = async (): Promise<string> => {
await writeFile(
join(root, "scripts/cache-fixture-build.mjs"),
`import { mkdir, writeFile } from "node:fs/promises";
await writeFile("resource-controls.json", JSON.stringify(Object.fromEntries(["GOMAXPROCS", "GOMEMLIMIT", "UV_THREADPOOL_SIZE", "REA_TEST_UNLISTED_ENV"].map((name) => [name, process.env[name] ?? null]))));
await mkdir("dist", { recursive: true });
await writeFile("dist/cache-fixture.js", "built");
await writeFile("dist/catalogIdentity.js", "export const CATALOG_IDENTITY = { counts: { mcp_tools: 1 } };\\n");
@@ -232,10 +266,13 @@ const createNodeModulesLinks = async (root: string): Promise<void> => {
}
};
const runNpm = (cwd: string, arguments_: readonly string[]) =>
run("npm", arguments_, cwd);
const runNpm = (
cwd: string,
arguments_: readonly string[],
environment: NodeJS.ProcessEnv = process.env,
) => run("npm", arguments_, cwd, environment);
const runTurbo = (cwd: string) =>
const runTurbo = (cwd: string, environment: NodeJS.ProcessEnv = process.env) =>
run(
process.execPath,
[
@@ -245,12 +282,14 @@ const runTurbo = (cwd: string) =>
"--output-logs=full",
],
cwd,
environment,
);
const run = (
command: string,
arguments_: readonly string[],
cwd: string,
environment: NodeJS.ProcessEnv,
): Promise<{
readonly status: number;
readonly stdout: string;
@@ -259,7 +298,7 @@ const run = (
new Promise((resolve, reject) => {
const child = spawn(command, [...arguments_], {
cwd,
env: process.env,
env: environment,
shell: process.platform === "win32",
stdio: ["ignore", "pipe", "pipe"],
});
+1
View File
@@ -1,5 +1,6 @@
{
"$schema": "https://turborepo.dev/schema.json",
"globalPassThroughEnv": ["GOMAXPROCS", "GOMEMLIMIT", "UV_THREADPOOL_SIZE"],
"tasks": {
"compile": {
"dependsOn": ["metadata:check"],