mike-backend / backend /scripts /tabularrr-runtime-smoke.mjs
bardd's picture
Deploy Mike backend-only Space
06671aa verified
Raw History Blame Contribute Delete
3.21 kB
#!/usr/bin/env node
import { createHash } from "node:crypto";
import { execFileSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const repoRoot = path.join(scriptDir, "../..");
const baseUrl = process.env.TABULARRR_SMOKE_BASE_URL ?? "http://127.0.0.1:3000";
function run(command, args) {
return execFileSync(command, args, {
cwd: repoRoot,
encoding: "utf8",
stdio: ["ignore", "pipe", "pipe"],
}).trim();
}
function sha256(filePath) {
return createHash("sha256")
.update(fs.readFileSync(filePath))
.digest("hex");
}
async function requirePage(route) {
let lastError;
for (let attempt = 1; attempt <= 30; attempt += 1) {
try {
const response = await fetch(`${baseUrl}${route}`, {
redirect: "follow",
signal: AbortSignal.timeout(20_000),
});
if (!response.ok) {
throw new Error(`${route} returned HTTP ${response.status}`);
}
const html = await response.text();
if (!html.includes("Tabularrr")) {
throw new Error(`${route} did not render Tabularrr branding`);
}
return html;
} catch (error) {
lastError = error;
if (attempt < 30) {
await new Promise((resolve) => setTimeout(resolve, 1_000));
}
}
}
throw new Error(
`${route} was not ready after 30 attempts: ${lastError?.message ?? lastError}`,
);
}
const runningServices = new Set(
run("docker", ["compose", "ps", "--status", "running", "--services"])
.split(/\r?\n/)
.filter(Boolean),
);
for (const service of [
"mike-postgres",
"python-service",
"backend",
"frontend",
]) {
if (!runningServices.has(service)) {
throw new Error(`Docker service ${service} is not running`);
}
}
const loginHtml = await requirePage("/login");
await requirePage("/signup");
if (!loginHtml.includes("Tabularrr - AI Legal Platform")) {
throw new Error("The runtime page title is not the canonical Tabularrr title");
}
const pythonTitle = run("docker", [
"compose",
"exec",
"-T",
"python-service",
"python",
"-c",
"from main import app; print(app.title)",
]);
if (pythonTitle !== "Tabularrr Playbook Review Service") {
throw new Error(`Unexpected Python service title: ${pythonTitle}`);
}
const containerManifestSha = run("docker", [
"compose",
"exec",
"-T",
"python-service",
"python",
"-c",
"from inference.config import manifest_sha256; print(manifest_sha256())",
]);
const hostManifestSha = sha256(
path.join(repoRoot, "backend/config/inference.manifest.json"),
);
if (containerManifestSha !== hostManifestSha) {
throw new Error(
`Python manifest SHA mismatch: container=${containerManifestSha} host=${hostManifestSha}`,
);
}
console.log("TABULARRR_RUNTIME_SMOKE_PASSED");
console.log(`BASE_URL=${baseUrl}`);
console.log(`PYTHON_MANIFEST_SHA256=${containerManifestSha}`);