diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh index 7c89216..4822b40 100644 --- a/docker/docker-entrypoint.sh +++ b/docker/docker-entrypoint.sh @@ -6,15 +6,38 @@ MIGRATION_RETRY_DELAY_SECONDS="${MIGRATION_RETRY_DELAY_SECONDS:-2}" ATTEMPT=1 # Auto-resolve any previously failed migrations so deploy can proceed. -# This handles the case where a migration partially applied and was fixed -# in a subsequent deploy — without this, Prisma refuses to run anything. +# This handles the case where a migration failed mid-flight and was then +# fixed in a subsequent deploy — without this, Prisma refuses to run +# anything else (P3009). +# +# We query `_prisma_migrations` directly rather than parsing the output of +# `prisma migrate status`, because that output's wording has shifted between +# Prisma versions and any drift means failed migrations slip through and +# the container crash-loops. Truth lives in the table: a row with +# `finished_at IS NULL AND rolled_back_at IS NULL` is an unresolved failure. echo "==> Checking for failed migrations..." -MIGRATE_STATUS=$(npx prisma migrate status 2>&1 || true) -FAILED=$(echo "$MIGRATE_STATUS" | sed -n 's/.*The `\([^`]*\)` migration.*failed.*/\1/p' | head -1) -if [ -n "$FAILED" ]; then +RESOLVE_ATTEMPTS=0 +while [ "$RESOLVE_ATTEMPTS" -lt 5 ]; do + FAILED=$(node -e " + const { PrismaClient } = require('@prisma/client'); + const p = new PrismaClient(); + p.\$queryRaw\` + SELECT migration_name FROM _prisma_migrations + WHERE finished_at IS NULL AND rolled_back_at IS NULL + ORDER BY started_at ASC LIMIT 1 + \`.then(r => { console.log(r[0]?.migration_name || ''); p.\$disconnect(); }) + .catch(() => { console.log(''); p.\$disconnect(); }); + " 2>/dev/null || echo "") + if [ -z "$FAILED" ]; then + break + fi echo "==> Found failed migration: $FAILED — marking as rolled back..." - npx prisma migrate resolve --rolled-back "$FAILED" -fi + npx prisma migrate resolve --rolled-back "$FAILED" || { + echo "WARNING: prisma migrate resolve failed for $FAILED" + break + } + RESOLVE_ATTEMPTS=$((RESOLVE_ATTEMPTS + 1)) +done echo "==> Running database migrations (with retry)..." until npx prisma migrate deploy; do