Files
memind/scripts/run-release-gate-runtime-cold-start.mjs
T
john b1577a16e9
Memind CI / Test, build, and release guards (push) Failing after 12m3s
fix: harden release gate and page delivery
2026-07-26 14:32:01 +08:00

61 lines
2.2 KiB
JavaScript

#!/usr/bin/env node
import mysql from 'mysql2/promise';
import path from 'node:path';
import { assertPortalRuntimePath, hashArtifact } from '../release-gate/artifact.mjs';
import { createLocalGateStack } from '../release-gate/local-stack.mjs';
const ROOT = path.resolve(new URL('..', import.meta.url).pathname);
const runtimeRoot = assertPortalRuntimePath(path.join(ROOT, '.runtime', 'portal'), { repoRoot: ROOT });
const artifactBefore = await hashArtifact(runtimeRoot);
const runId = `cold-${new Date().toISOString().replace(/\D/g, '').slice(0, 14)}`;
const port = Number(process.env.MEMIND_RELEASE_GATE_COLD_PORT ?? 19084);
const stack = await createLocalGateStack({
root: ROOT,
runId,
port,
portalRoot: runtimeRoot,
nodeEnv: 'production',
runtimeProfile: 'production',
});
try {
const firstStatus = await fetch(`${stack.baseUrl}/auth/status`, {
signal: AbortSignal.timeout(5_000),
});
if (!firstStatus.ok) throw new Error(`first health check failed: ${firstStatus.status}`);
const connection = await mysql.createConnection(stack.mysqlUrl);
let initializedTables;
try {
const [rows] = await connection.query(
`SELECT COUNT(*) AS count
FROM information_schema.tables
WHERE table_schema = DATABASE()`,
);
initializedTables = Number(rows[0]?.count ?? 0);
} finally {
await connection.end();
}
if (initializedTables < 10) {
throw new Error(`database initialization is incomplete: ${initializedTables} tables`);
}
await stack.restartPortal();
const restartedStatus = await fetch(`${stack.baseUrl}/auth/status`, {
signal: AbortSignal.timeout(5_000),
});
if (!restartedStatus.ok) throw new Error(`restart health check failed: ${restartedStatus.status}`);
console.log('PASS REL-06 packaged runtime cold-starts with NODE_ENV=production');
console.log(`PASS REL-06 isolated database initialized ${initializedTables} tables and restart is idempotent`);
} finally {
await stack.cleanup();
const artifactAfter = await hashArtifact(runtimeRoot);
if (artifactAfter.sha256 !== artifactBefore.sha256) {
throw new Error(
`packaged runtime mutated its own artifact during cold start: ${artifactBefore.sha256} -> ${artifactAfter.sha256}`,
);
}
}