feat(dashboard-agent-db): add a pending-migration status check (#4037)

This commit is contained in:
Eric Allam
2026-06-25 13:15:34 +01:00
committed by GitHub
parent 82bdd1fe0e
commit 5379b744ff
2 changed files with 77 additions and 0 deletions
@@ -0,0 +1,76 @@
// Pending-status check for the `trigger_dashboard_agent` schema (sibling of
// migrate.mjs). Exit 0 = up to date, 1 = pending, 2 = error.
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import postgres from "postgres";
const MIGRATIONS_SCHEMA = "drizzle";
const MIGRATIONS_TABLE = "__dashboard_agent_migrations";
const connectionString = process.env.DASHBOARD_AGENT_DATABASE_URL ?? process.env.DATABASE_URL;
if (!connectionString) {
console.error(
"[dashboard-agent-db] DASHBOARD_AGENT_DATABASE_URL / DATABASE_URL not set; cannot check status."
);
process.exit(2);
}
// Match migrate.mjs: drop the Prisma-style `?schema=` param postgres.js forwards.
function normalizeConnectionString(value) {
try {
const url = new URL(value);
url.searchParams.delete("schema");
return url.toString();
} catch {
return value;
}
}
const journalPath = join(
dirname(fileURLToPath(import.meta.url)),
"drizzle/meta/_journal.json"
);
const sql = postgres(normalizeConnectionString(connectionString), {
max: 1,
prepare: false,
onnotice: () => {},
});
async function main() {
const journal = JSON.parse(readFileSync(journalPath, "utf-8"));
const entries = [...journal.entries].sort((a, b) => a.when - b.when);
let lastAppliedAt = -1;
try {
const rows = await sql`SELECT MAX(created_at)::bigint AS last FROM ${sql(
MIGRATIONS_SCHEMA
)}.${sql(MIGRATIONS_TABLE)}`;
lastAppliedAt = rows[0].last === null ? -1 : Number(rows[0].last);
} catch (err) {
// 42P01: journal table absent (fresh database), so nothing is applied.
if (err.code !== "42P01") throw err;
}
const pending = entries.filter((e) => e.when > lastAppliedAt);
console.log(
`${entries.length} migration(s) found, ${entries.length - pending.length} applied`
);
if (pending.length > 0) {
console.log(`${pending.length} pending migration(s):`);
for (const e of pending) console.log(` - ${e.tag}`);
return 1;
}
console.log("Dashboard agent schema is up to date");
return 0;
}
main()
.then((code) => sql.end({ timeout: 5 }).then(() => process.exit(code)))
.catch((err) => {
console.error(err);
sql.end({ timeout: 5 }).finally(() => process.exit(2));
});
@@ -17,6 +17,7 @@
"db:generate": "drizzle-kit generate",
"db:migrate": "drizzle-kit migrate",
"db:migrate:deploy": "node migrate.mjs",
"db:migrate:status": "node migrate-status.mjs",
"db:studio": "drizzle-kit studio"
}
}