Skip to content
67 changes: 67 additions & 0 deletions scripts/local/check-stack.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { captureCommand } from './helpers.mjs';

const targets = [
{ label: 'api', url: 'http://127.0.0.1:8788' },
{ label: 'admin', url: 'http://127.0.0.1:5174' },
{ label: 'web', url: 'http://127.0.0.1:4321' },
];

const checkHttpTarget = async ({ label, url }) => {
try {
const response = await fetch(url, { redirect: 'manual' });
return {
label,
ok: response.ok,
status: response.status,
detail: url,
};
} catch (error) {
return {
label,
ok: false,
status: null,
detail: error instanceof Error ? error.message : String(error),
};
}
};

const checkPostgresContainer = async () => {
try {
const { stdout } = await captureCommand('docker', [
'inspect',
'-f',
'{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}',
'rebase-postgres',
]);
const status = stdout.trim();

return {
label: 'postgres',
ok: status === 'healthy' || status === 'running',
status,
detail: 'rebase-postgres',
};
} catch (error) {
return {
label: 'postgres',
ok: false,
status: null,
detail: error instanceof Error ? error.message : String(error),
};
}
};

const results = await Promise.all([
...targets.map((target) => checkHttpTarget(target)),
checkPostgresContainer(),
]);

for (const result of results) {
const status = result.status ?? 'unreachable';
const mark = result.ok ? 'OK' : 'FAIL';
console.log(`${mark} ${result.label.padEnd(8)} ${status} ${result.detail}`);
}

if (results.some((result) => !result.ok)) {
process.exitCode = 1;
}
60 changes: 60 additions & 0 deletions scripts/local/test-stack.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { runCommand } from './helpers.mjs';

const cwd = new URL('../../', import.meta.url);
const command = process.argv[2] ?? 'help';
const extraArgs = process.argv.slice(3);

const runNodeScript = (scriptPath, args = []) =>
runCommand(process.execPath, [scriptPath, ...args], { cwd });

const runPnpm = (args = []) =>
runCommand('corepack', ['pnpm', ...args], { cwd });

const tasks = {
help: async () => {
console.log(`Usage:
node scripts/local/test-stack.mjs bootstrap
node scripts/local/test-stack.mjs content
node scripts/local/test-stack.mjs ready
node scripts/local/test-stack.mjs start [--services=api,admin,web]
node scripts/local/test-stack.mjs status
node scripts/local/test-stack.mjs smoke

Commands:
bootstrap Initialize postgres, migrations, seed data, and local admin account
content Reset imported WeChat drafts and re-import content items
ready Run bootstrap, then content
start Start local api/admin/web services
status Check postgres, api, admin, and web availability
smoke Run smoke tests
`);
},
bootstrap: async () => {
await runNodeScript('scripts/local/bootstrap-stack.mjs');
},
content: async () => {
await runPnpm(['--filter', '@rebase/api', 'reset-wechat-import-drafts', '--write']);
await runPnpm(['--filter', '@rebase/api', 'import-content-items', '--write']);
},
ready: async () => {
await tasks.bootstrap();
await tasks.content();
},
start: async () => {
await runNodeScript('scripts/local/dev-stack.mjs', extraArgs);
},
status: async () => {
await runNodeScript('scripts/local/check-stack.mjs');
},
smoke: async () => {
await runPnpm(['test:smoke']);
},
};

if (!(command in tasks)) {
console.error(`Unknown command: ${command}`);
await tasks.help();
process.exit(1);
}

await tasks[command]();
Loading