diff --git a/src/commands/migrate/verify.ts b/src/commands/migrate/verify.ts index 5b40def..6bdd2d2 100644 --- a/src/commands/migrate/verify.ts +++ b/src/commands/migrate/verify.ts @@ -20,6 +20,10 @@ export default class MigrateVerify extends BaseCommand { description: "The migration file to run", required: true, }), + "skip-build": Flags.boolean({ + description: "Use the existing dist/ build instead of building first", + default: false, + }), json: Flags.boolean({ description: "Print the result as JSON", default: false, @@ -32,7 +36,8 @@ export default class MigrateVerify extends BaseCommand { process.cwd(), path.resolve(flags.baseline), flags.migration, - cliBinPath(this.config.root) + cliBinPath(this.config.root), + flags["skip-build"] ); report( (s) => this.log(s), diff --git a/src/commands/test/smoke.ts b/src/commands/test/smoke.ts index ce917c6..f191a1a 100644 --- a/src/commands/test/smoke.ts +++ b/src/commands/test/smoke.ts @@ -10,6 +10,10 @@ export default class TestSmoke extends BaseCommand { static examples = [`$ apso test smoke`]; static flags = { + "skip-build": Flags.boolean({ + description: "Use the existing dist/ build instead of building first", + default: false, + }), json: Flags.boolean({ description: "Print the result as JSON", default: false, @@ -21,7 +25,9 @@ export default class TestSmoke extends BaseCommand { const { entities, auth } = parseApsorc(); // With auth configured every entity route needs a session, so only /health is checked. const names = auth ? [] : entities.map((e) => e.name); - const result = await smokeTest(process.cwd(), names); + const result = await smokeTest(process.cwd(), names, { + skipBuild: flags["skip-build"], + }); report( (s) => this.log(s), result, diff --git a/src/lib/verify/index.ts b/src/lib/verify/index.ts index 36d4205..282b2cb 100644 --- a/src/lib/verify/index.ts +++ b/src/lib/verify/index.ts @@ -202,7 +202,8 @@ export async function verifyMigration( projectDir: string, baselineApsorc: string, migrationFile: string, - cliBin: string + cliBin: string, + skipBuild = false ): Promise { const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "apso-pglite-")); const steps: Step[] = []; @@ -213,7 +214,7 @@ export async function verifyMigration( try { if (!done(await buildBaseline(projectDir, baselineApsorc, dataDir, cliBin))) return { ok: false, steps }; - if (!done(step("build", await build(projectDir)))) + if (!skipBuild && !done(step("build", await build(projectDir)))) return { ok: false, steps }; const compiled = path @@ -252,13 +253,16 @@ const freePort = () => const get = (url: string) => new Promise<{ status: number; body: string }>((resolve) => { http - .get(url, (res) => { + .get(url, { timeout: 15_000 }, (res) => { let body = ""; res.on("data", (d) => { body += d; }); res.on("end", () => resolve({ status: res.statusCode ?? 0, body })); }) + .on("timeout", function (this: http.ClientRequest) { + this.destroy(new Error("No response within 15s")); + }) .on("error", (e) => resolve({ status: 0, body: e.message })); }); @@ -271,7 +275,7 @@ const get = (url: string) => export async function smokeTest( projectDir: string, entityNames: string[], - timeoutMs = 60_000 + { skipBuild = false, timeoutMs = 60_000 } = {} ): Promise { const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), "apso-pglite-")); const steps: Step[] = []; @@ -281,7 +285,7 @@ export async function smokeTest( }; let server: ReturnType | undefined; try { - if (!done(step("build", await build(projectDir)))) + if (!skipBuild && !done(step("build", await build(projectDir)))) return { ok: false, steps }; if ( !done(