Strengthen release verification gates

This commit is contained in:
2026-06-25 07:05:08 -07:00
parent 3d7dca8773
commit 99881b608b
7 changed files with 298 additions and 20 deletions

View File

@@ -1,4 +1,7 @@
import { spawn } from "node:child_process";
import { spawn, spawnSync } from "node:child_process";
import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
const command = process.argv[2];
const args = process.argv.slice(3);
@@ -7,9 +10,12 @@ if (!command) {
throw new Error("usage: node scripts/smoke-web-search.mjs <command> [args...]");
}
const tmpDir = mkdtempSync(join(tmpdir(), "context-kit-web-search-smoke-"));
const cidFile = join(tmpDir, "container.cid");
const child = spawn(command, args, {
cwd: new URL("..", import.meta.url).pathname,
env: process.env,
env: { ...process.env, CONTEXT_KIT_DOCKER_CIDFILE: cidFile },
stdio: ["pipe", "pipe", "pipe"]
});
@@ -19,18 +25,28 @@ let stdoutBuffer = "";
let stderrBuffer = "";
let childExited = false;
child.once("exit", () => {
child.once("exit", (code, signal) => {
childExited = true;
if (pending.size > 0) {
const error = new Error(`MCP child exited before responding (code=${code}, signal=${signal}). stderr: ${stderrBuffer.slice(-2000)}`);
for (const { reject } of pending.values()) reject(error);
pending.clear();
}
});
function stopChild() {
return new Promise(resolve => {
if (childExited) {
stopContainer();
rmSync(tmpDir, { recursive: true, force: true });
resolve();
return;
}
child.stdin.end();
const stopTimer = setTimeout(() => {
stopContainer();
}, 1000);
const termTimer = setTimeout(() => {
if (!childExited) child.kill("SIGTERM");
}, 3000);
@@ -39,13 +55,23 @@ function stopChild() {
}, 6000);
child.once("exit", () => {
stopContainer();
clearTimeout(stopTimer);
clearTimeout(termTimer);
clearTimeout(killTimer);
rmSync(tmpDir, { recursive: true, force: true });
resolve();
});
});
}
function stopContainer() {
if (!existsSync(cidFile)) return;
const containerId = readFileSync(cidFile, "utf8").trim();
if (!containerId) return;
spawnSync("docker", ["stop", containerId], { stdio: "ignore" });
}
const timeout = setTimeout(async () => {
await stopChild();
console.error(`MCP smoke timed out. stderr: ${stderrBuffer.slice(-2000)}`);
@@ -79,6 +105,9 @@ child.stdout.on("data", chunk => {
});
function request(method, params = {}) {
if (childExited) {
return Promise.reject(new Error(`MCP child already exited. stderr: ${stderrBuffer.slice(-2000)}`));
}
const id = nextId++;
child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}\n`);
return new Promise((resolve, reject) => pending.set(id, { resolve, reject }));