Files
memind/scripts/run-release-gate-page-scenarios.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

91 lines
2.7 KiB
JavaScript

#!/usr/bin/env node
import { spawn } from 'node:child_process';
import path from 'node:path';
import {
createLocalGateStack,
selectBackendLlmProvider,
seedSelectedProviderKeys,
} from '../release-gate/local-stack.mjs';
const root = path.resolve(new URL('..', import.meta.url).pathname);
const scenarioIds = [
'john2-suzhou-page',
'long-content-rich-page',
];
async function runScenario(scenarioId, port) {
const childTimeoutMs = Math.max(
30_000,
Number(process.env.RELEASE_GATE_SCENARIO_PROCESS_TIMEOUT_MS ?? 360_000) || 360_000,
);
const code = await new Promise((resolve, reject) => {
const child = spawn(
process.execPath,
['scripts/run-scenario-test.mjs', '--scenario', scenarioId, '--port', String(port)],
{
cwd: root,
env: {
...process.env,
JOHN_PASSWORD: '888888',
RELEASE_GATE_SCENARIO_TIMEOUT_MS: String(
Number(process.env.RELEASE_GATE_SCENARIO_TIMEOUT_MS ?? 300_000) || 300_000,
),
},
stdio: 'inherit',
},
);
const timeout = setTimeout(() => {
child.kill('SIGTERM');
setTimeout(() => child.kill('SIGKILL'), 3_000).unref();
}, childTimeoutMs);
timeout.unref();
child.once('error', reject);
child.once('close', (status) => {
clearTimeout(timeout);
resolve(status ?? 1);
});
});
return code;
}
const runId = `page-${new Date().toISOString().replace(/[-:.TZ]/g, '').slice(0, 14)}`;
const stack = await createLocalGateStack({
root,
runId,
port: Number(process.env.MEMIND_RELEASE_GATE_PAGE_PORT ?? 19087),
portalRoot: path.join(root, '.runtime', 'portal'),
nodeEnv: 'test',
runtimeProfile: 'local',
});
await seedSelectedProviderKeys({ sourceUrl: stack.sourceDatabaseUrl, targetUrl: stack.mysqlUrl });
await selectBackendLlmProvider({ targetUrl: stack.mysqlUrl });
async function register(username) {
const response = await fetch(`${stack.baseUrl}/auth/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username,
password: '888888',
displayName: `Release Gate ${username}`,
email: `${username}@example.invalid`,
}),
});
if (!response.ok) throw new Error(`register ${username} failed: ${response.status}`);
}
try {
await register('john2');
const results = await Promise.all(scenarioIds.map(async (scenarioId) => ({
scenarioId,
code: await runScenario(scenarioId, new URL(stack.baseUrl).port),
})));
for (const result of results) {
console.log(`${result.code === 0 ? 'PASS' : 'FAIL'} ${result.scenarioId}`);
}
if (results.some((result) => result.code !== 0)) process.exitCode = 1;
} finally {
await stack.cleanup();
}