fix: harden release artifact checks and fixture isolation

This commit is contained in:
jb
2026-09-19 10:01:23 -04:00
parent 99436225f6
commit 197e6a3a70
7 changed files with 108 additions and 20 deletions
+27 -4
View File
@@ -1,16 +1,38 @@
import { createServer } from 'node:net';
import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
const port = Number(process.env.SMOKE_WEB_PORT ?? 15173);
async function freePort(): Promise<number> {
return await new Promise((resolve, reject) => {
const probe = createServer();
probe.once('error', reject);
probe.listen(0, '127.0.0.1', () => {
const address = probe.address();
const port = typeof address === 'object' && address ? address.port : 0;
probe.close((error) => error ? reject(error) : resolve(port));
});
});
}
const configuredPort = process.env.SMOKE_WEB_PORT;
const port = configuredPort === undefined ? await freePort() : Number(configuredPort);
if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error('SMOKE_WEB_PORT must be a valid TCP port');
const base = `http://127.0.0.1:${port}`;
const root = await mkdtemp(join(tmpdir(), 'eden-fixture-'));
let server: Bun.Subprocess | undefined;
// Never pass ambient vault/session/provider variables into repository-controlled
// fixture processes. The fixture only needs a minimal, non-secret environment.
const safeEnv = {
PATH: process.env.PATH ?? '/usr/bin:/bin',
HOME: process.env.HOME ?? '/tmp',
TMPDIR: process.env.TMPDIR ?? '/tmp',
};
async function compileFixture(directory: string): Promise<void> {
const child = Bun.spawn(['bun', 'workers/reference.ts', '--fixture', '--directory', directory], {
stdout: 'pipe', stderr: 'pipe', stdin: 'ignore',
env: { ...process.env, APP_MODE: 'demo', REFERENCE_DIR: directory },
env: { ...safeEnv, APP_MODE: 'demo', REFERENCE_DIR: directory },
});
const code = await child.exited;
if (code !== 0) throw new Error('Fixture reference compilation failed');
@@ -21,7 +43,7 @@ async function waitForServer(): Promise<void> {
while (Date.now() < deadline) {
try {
const response = await fetch(base);
if (response.status === 200) return;
if (response.status === 200 && response.headers.get('x-application-release') === 'fixture') return;
} catch { /* startup race */ }
await Bun.sleep(250);
}
@@ -33,10 +55,11 @@ try {
server = Bun.spawn(['bun', 'build/index.js'], {
stdout: 'pipe', stderr: 'pipe', stdin: 'ignore',
env: {
...process.env,
...safeEnv,
APP_MODE: 'demo', APP_ORIGIN: base, ORIGIN: base,
HOST: '127.0.0.1', PORT: String(port), REFERENCE_DIR: root,
APP_RELEASE_ID: 'fixture',
APP_CAPABILITY_ALLOWLIST: 'asset_search,asset_valuation,asset_sync,assistant_dispatch,session_token,identity,subscriptions',
},
});
await waitForServer();