- 新增只读发布 smoke runner 和 dry-run 测试\n- 将生产部署 workflow 从单点版本检查升级为 smoke test\n- 补充 Docker web runtime 脚本复制、package script 和部署文档\n\nCo-Authored-By: GPT-5 Codex <codex@openai.com>
101 lines
3.2 KiB
JavaScript
101 lines
3.2 KiB
JavaScript
import { spawnSync } from 'node:child_process';
|
|
import { mkdtempSync, writeFileSync, existsSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join, resolve } from 'node:path';
|
|
import { describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
const root = resolve(import.meta.dirname, '..');
|
|
|
|
function runScript(script, args) {
|
|
return spawnSync(process.execPath, [join(root, script), ...args], {
|
|
cwd: root,
|
|
encoding: 'utf8',
|
|
});
|
|
}
|
|
|
|
describe('production ops scripts', () => {
|
|
it('prints a pg_dump command in dry-run mode without writing the target file', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'ftb-pg-backup-'));
|
|
const output = join(dir, 'backup.dump');
|
|
|
|
const result = runScript('scripts/backup-postgres.mjs', [
|
|
'--dry-run',
|
|
'--env-file',
|
|
'.env.production.example',
|
|
'--output',
|
|
output,
|
|
]);
|
|
|
|
assert.equal(result.status, 0, result.stderr);
|
|
assert.match(result.stdout, /docker compose/);
|
|
assert.match(result.stdout, /pg_dump/);
|
|
assert.match(result.stdout, /backup\.dump/);
|
|
assert.equal(existsSync(output), false);
|
|
});
|
|
|
|
it('refuses restore by default unless --confirm-overwrite is supplied', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'ftb-pg-restore-'));
|
|
const input = join(dir, 'backup.dump');
|
|
writeFileSync(input, 'not-a-real-dump');
|
|
|
|
const result = runScript('scripts/restore-postgres.mjs', [
|
|
'--env-file',
|
|
'.env.production.example',
|
|
'--input',
|
|
input,
|
|
]);
|
|
|
|
assert.notEqual(result.status, 0);
|
|
assert.match(result.stderr, /--confirm-overwrite/);
|
|
});
|
|
|
|
it('prints fresh database restore steps in dry-run mode after explicit overwrite confirmation', () => {
|
|
const dir = mkdtempSync(join(tmpdir(), 'ftb-pg-restore-dry-'));
|
|
const input = join(dir, 'backup.dump');
|
|
writeFileSync(input, 'not-a-real-dump');
|
|
|
|
const result = runScript('scripts/restore-postgres.mjs', [
|
|
'--dry-run',
|
|
'--confirm-overwrite',
|
|
'--env-file',
|
|
'.env.production.example',
|
|
'--input',
|
|
input,
|
|
]);
|
|
|
|
assert.equal(result.status, 0, result.stderr);
|
|
assert.match(result.stdout, /dropdb/);
|
|
assert.match(result.stdout, /createdb/);
|
|
assert.match(result.stdout, /pg_restore/);
|
|
});
|
|
|
|
it('prints a server_data volume tar backup command in dry-run mode', () => {
|
|
const result = runScript('scripts/backup-server-data.mjs', [
|
|
'--dry-run',
|
|
'--env-file',
|
|
'.env.production.example',
|
|
]);
|
|
|
|
assert.equal(result.status, 0, result.stderr);
|
|
assert.match(result.stdout, /docker run/);
|
|
assert.match(result.stdout, /ftb_pm_server_data/);
|
|
assert.match(result.stdout, /tar -czf/);
|
|
});
|
|
|
|
it('prints read-only release smoke checks in dry-run mode', () => {
|
|
const result = runScript('scripts/smoke-test-release.mjs', [
|
|
'--dry-run',
|
|
'--base-url',
|
|
'http://localhost',
|
|
]);
|
|
|
|
assert.equal(result.status, 0, result.stderr);
|
|
assert.match(result.stdout, /\/api\/v1\/health\/version/);
|
|
assert.match(result.stdout, /\/products/);
|
|
assert.match(result.stdout, /\/api\/v1\/products/);
|
|
assert.match(result.stdout, /\/api\/v1\/v2\.2\/requirements\?productId=__smoke__/);
|
|
assert.match(result.stdout, /\/api\/v1\/config\/ai/);
|
|
});
|
|
});
|