fix(workflow): forward the tsconfig pin only in the unbuilt worker

This commit is contained in:
Huanqi Cao
2026-08-12 15:11:05 +08:00
committed by Chinesezjc
parent 095fde4ffd
commit 7593842ccf
2 changed files with 21 additions and 16 deletions

View File

@@ -38,18 +38,21 @@ interface ChildRecord {
* The unbuilt shape additionally forwards `TSX_TSCONFIG_PATH` for path
* resolution.
* @param platform - host platform; overridable so tests exercise both peer arms.
* @param tsconfigPath - the tsconfig pin to forward; only the unbuilt caller
* passes one, so the built worker never observes the host's pin.
* @returns the scrubbed worker environment object.
*/
export function workerSpawnEnv(platform: NodeJS.Platform = process.platform): NodeJS.ProcessEnv {
export function workerSpawnEnv(
platform: NodeJS.Platform = process.platform,
tsconfigPath: string | undefined = undefined,
): NodeJS.ProcessEnv {
const env: NodeJS.ProcessEnv = {}
if (platform === 'win32') {
const tmp = tmpdir()
env.TMP = tmp
env.TEMP = tmp
}
if (process.env.TSX_TSCONFIG_PATH !== undefined) {
env.TSX_TSCONFIG_PATH = process.env.TSX_TSCONFIG_PATH
}
if (tsconfigPath !== undefined) env.TSX_TSCONFIG_PATH = tsconfigPath
return env
}
@@ -81,7 +84,7 @@ function resolveWorkerSpawn(init: WorkerInit): { entry: string | URL; options: W
entry: new URL(`data:text/javascript,${encodeURIComponent(bootstrap)}`),
options: {
workerData: init,
env: workerSpawnEnv(),
env: workerSpawnEnv(undefined, process.env.TSX_TSCONFIG_PATH),
execArgv: [],
},
}

View File

@@ -570,6 +570,11 @@ describe('dsh-workflow-worker-thread', () => {
// inside the worker resolves instead of degrading to a cwd-relative
// `undefined\temp` (tsx writes its transform cache there).
process.env.WORKFLOW_ENV_CANARY = 'leak me'
// The unbuilt worker forwards TSX_TSCONFIG_PATH (a path pin, not a
// credential); clear it so this test observes the empty ambient case
// regardless of the parent's environment.
const tsconfigPath = process.env.TSX_TSCONFIG_PATH
delete process.env.TSX_TSCONFIG_PATH
try {
const result = await run(ctx, parent, scripted(`
const proc = ${ESCAPE}
@@ -579,6 +584,8 @@ describe('dsh-workflow-worker-thread', () => {
const expectedKeys = process.platform === 'win32' ? ['TEMP', 'TMP'] : []
expect(result.value).toEqual({ canary: null, keys: expectedKeys })
} finally {
if (tsconfigPath === undefined) delete process.env.TSX_TSCONFIG_PATH
else process.env.TSX_TSCONFIG_PATH = tsconfigPath
delete process.env.WORKFLOW_ENV_CANARY
}
})
@@ -591,17 +598,12 @@ describe('dsh-workflow-worker-thread', () => {
it('workerSpawnEnv forwards TSX_TSCONFIG_PATH when the snapshot harness pins it', () => {
const tsconfig = fileURLToPath(new URL('../../../../tsconfig.json', import.meta.url))
vi.stubEnv('TSX_TSCONFIG_PATH', tsconfig)
try {
expect(workerSpawnEnv('linux')).toEqual({ TSX_TSCONFIG_PATH: tsconfig })
expect(workerSpawnEnv('win32')).toEqual({
TMP: tmpdir(),
TEMP: tmpdir(),
TSX_TSCONFIG_PATH: tsconfig,
})
} finally {
vi.unstubAllEnvs()
}
expect(workerSpawnEnv('linux', tsconfig)).toEqual({ TSX_TSCONFIG_PATH: tsconfig })
expect(workerSpawnEnv('win32', tsconfig)).toEqual({
TMP: tmpdir(),
TEMP: tmpdir(),
TSX_TSCONFIG_PATH: tsconfig,
})
})
it('the unbuilt worker forwards exactly TSX_TSCONFIG_PATH through the scrub: the paths-map pin survives, secrets do not', async () => {