Files
cfw-autumn/scripts/setup/setup-test.ts
amianthus 25e920bbd3 feat(dw): 🎸 parallel agent worktrees with isolated infra + test harness
bun dw spins up a fully isolated per-worktree dev stack: Neon DB branch,
Dragonfly + ElasticMQ via docker compose, portless aliases, tmux
session, and emulate.dev Google OAuth. Workers, dev server, vite,
checkout, and stripe-listen run as concurrently siblings. bun setup-test
auto-runs on first dw and seeds unit-test-org via
clearOrg+setupOrg+ensureDefaultStripeAccount with 13 features + team
invites for all 5 useautumn.com members. Hardcoded localhost URLs in
test scenarios now read AUTUMN_TEST_BASE_URL/AUTUMN_TEST_VITE_URL.
preload-env.ts loads .env.local so bun t/cm/setup-test route to the
worktree server. 1265-line scripts/dw.ts split into scripts/dw/ module
(index + commands + helpers). server/src/db/initDrizzle.ts reverted to
upstream (search_path concerns solved by per-branch Neon isolation).
Workers enabled in agent worktrees now that SQS is per-worktree via
ElasticMQ.
2026-05-16 02:02:43 +01:00

79 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
import chalk from "chalk";
import inquirer from "inquirer";
import {
createTestOrg,
TEST_ORG_CONFIG,
} from "../setupTestUtils/createTestOrg.js";
// Worktree .env.local loading happens in scripts/preload-env.ts (auto-run by
// Bun via bunfig.toml's `preload`). DATABASE_URL flips to the worktree branch
// before this module's top-level statements execute.
function maskDatabaseUrl(url: string | undefined): string {
if (!url) return "(unset)";
try {
const u = new URL(url);
const host = u.host;
const db = u.pathname.replace(/^\//, "");
return `${u.protocol}//***@${host}/${db}`;
} catch {
return "(unparseable)";
}
}
async function maybeConfirm(yes: boolean): Promise<boolean> {
if (yes) return true;
if (!process.stdin.isTTY) return true;
const target = maskDatabaseUrl(process.env.DATABASE_URL);
const { ready } = await inquirer.prompt([
{
type: "confirm",
name: "ready",
message: chalk.cyan(
`About to seed '${TEST_ORG_CONFIG.slug}' into DATABASE_URL=${target}. Continue?`,
),
default: true,
},
]);
return Boolean(ready);
}
async function main() {
const yes = process.argv.includes("--yes");
console.log(
chalk.magentaBright(
`\n================ Autumn setup-test ================\n`,
),
);
console.log(
chalk.cyan(`Target: ${maskDatabaseUrl(process.env.DATABASE_URL)}\n`),
);
const proceed = await maybeConfirm(yes);
if (!proceed) {
console.log(chalk.yellow("Cancelled."));
process.exit(0);
}
try {
const { db } = await import("@server/db/initDrizzle.js");
const autumnSecretKey = await createTestOrg({ db });
console.log(chalk.greenBright("\n✅ setup-test complete"));
console.log(chalk.cyan("Org:"));
console.log(chalk.whiteBright(` slug: ${TEST_ORG_CONFIG.slug}`));
console.log(chalk.whiteBright(` id: ${TEST_ORG_CONFIG.id}`));
console.log(chalk.whiteBright(` key: ${autumnSecretKey}\n`));
process.exit(0);
} catch (error) {
console.error(
chalk.red("\n❌ setup-test failed:"),
error instanceof Error ? error.message : error,
);
process.exit(1);
}
}
main();