2026-02-21 13:34:18 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
set -e
|
|
|
|
|
|
fix(deploy): self-healing pre-migrate bootstrap for SecretBackend rollout
Why: clusters upgrading from the pre-SecretBackend schema crash-loop on the
first rollout. `prisma db push` applies the Phase 0 migration as three
sequential steps — add Secret.backendId column (default ''), create
SecretBackend table, add FK — and the FK fails because empty-string values
reference no row in the empty SecretBackend table. This happened on the live
cluster today; I fixed it by hand with psql. This PR makes the fix
automatic so a fresh cluster or anyone replaying the migration doesn't hit
the same trap.
- New `src/db/src/scripts/pre-migrate-bootstrap.ts` — idempotent node script.
Checks if SecretBackend table exists; if so, ensures a default row exists
(insert on conflict noop), then backfills any Secret.backendId = '' to
point at it. Uses Prisma raw queries so it runs against a partially-
migrated schema.
- `deploy/entrypoint.sh` now catches a failed first push, runs the
bootstrap, and retries. Fresh installs and fully-migrated clusters take
the happy path (one push, no bootstrap needed). Pre-Phase-0 upgrades take
the healing path (push fails → bootstrap seeds → retry succeeds).
- The bootstrap is deliberately non-fatal — even on unexpected errors it
logs and exits 0 so the retry still runs. If that retry also fails, the
push error surfaces normally and the pod crash-loops visibly rather than
silently starting in a half-migrated state.
Verified the idempotent path logically: on the already-bootstrapped cluster
(1 backend row, 0 empty-backendId Secrets), the script's UPDATE matches
zero rows and the INSERT hits ON CONFLICT DO NOTHING — pure no-op.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 22:59:07 +01:00
|
|
|
# Self-healing schema push:
|
|
|
|
|
# 1. Try once — for fresh installs and already-migrated clusters this is all
|
|
|
|
|
# that's needed.
|
|
|
|
|
# 2. On failure (typically a Phase 0 upgrade where the new SecretBackend FK
|
|
|
|
|
# can't attach because pre-existing Secret rows reference nothing), run
|
|
|
|
|
# the pre-migrate bootstrap to seed a default SecretBackend + backfill
|
|
|
|
|
# Secret.backendId, then retry.
|
|
|
|
|
# 3. If the retry still fails, let the error surface so the pod crashes
|
|
|
|
|
# visibly rather than starting in a half-migrated state.
|
2026-02-21 13:34:18 +00:00
|
|
|
echo "mcpd: pushing database schema..."
|
fix(deploy): self-healing pre-migrate bootstrap for SecretBackend rollout
Why: clusters upgrading from the pre-SecretBackend schema crash-loop on the
first rollout. `prisma db push` applies the Phase 0 migration as three
sequential steps — add Secret.backendId column (default ''), create
SecretBackend table, add FK — and the FK fails because empty-string values
reference no row in the empty SecretBackend table. This happened on the live
cluster today; I fixed it by hand with psql. This PR makes the fix
automatic so a fresh cluster or anyone replaying the migration doesn't hit
the same trap.
- New `src/db/src/scripts/pre-migrate-bootstrap.ts` — idempotent node script.
Checks if SecretBackend table exists; if so, ensures a default row exists
(insert on conflict noop), then backfills any Secret.backendId = '' to
point at it. Uses Prisma raw queries so it runs against a partially-
migrated schema.
- `deploy/entrypoint.sh` now catches a failed first push, runs the
bootstrap, and retries. Fresh installs and fully-migrated clusters take
the happy path (one push, no bootstrap needed). Pre-Phase-0 upgrades take
the healing path (push fails → bootstrap seeds → retry succeeds).
- The bootstrap is deliberately non-fatal — even on unexpected errors it
logs and exits 0 so the retry still runs. If that retry also fails, the
push error surfaces normally and the pod crash-loops visibly rather than
silently starting in a half-migrated state.
Verified the idempotent path logically: on the already-bootstrapped cluster
(1 backend row, 0 empty-backendId Secrets), the script's UPDATE matches
zero rows and the INSERT hits ON CONFLICT DO NOTHING — pure no-op.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 22:59:07 +01:00
|
|
|
if pnpm -F @mcpctl/db exec prisma db push --schema=prisma/schema.prisma --accept-data-loss 2>&1; then
|
|
|
|
|
:
|
|
|
|
|
else
|
|
|
|
|
echo "mcpd: schema push failed — running pre-migrate bootstrap + retrying..."
|
|
|
|
|
node src/db/dist/scripts/pre-migrate-bootstrap.js || true
|
|
|
|
|
pnpm -F @mcpctl/db exec prisma db push --schema=prisma/schema.prisma --accept-data-loss 2>&1
|
|
|
|
|
fi
|
2026-02-21 13:34:18 +00:00
|
|
|
|
2026-02-22 22:24:35 +00:00
|
|
|
echo "mcpd: seeding templates..."
|
|
|
|
|
TEMPLATES_DIR=templates node src/mcpd/dist/seed-runner.js
|
2026-02-21 13:34:18 +00:00
|
|
|
|
|
|
|
|
echo "mcpd: starting server..."
|
|
|
|
|
exec node src/mcpd/dist/main.js
|