#!/bin/sh set -e # --------------------------------------------------------------------------- # Run prisma migrate deploy. On P3009 (a failed migration is blocking deploy), # extract the migration name from the error, resolve it as rolled-back, and # retry. All migration SQL in this repo is idempotent so a re-run is safe. # Loop handles multiple blocked migrations; max retries prevents infinite loops. # --------------------------------------------------------------------------- MAX_RETRIES=10 ATTEMPT=0 while [ $ATTEMPT -lt $MAX_RETRIES ]; do ATTEMPT=$((ATTEMPT + 1)) echo "[migrate] Running prisma migrate deploy (attempt $ATTEMPT)..." EXIT_CODE=0 DEPLOY_OUTPUT=$(bunx prisma migrate deploy 2>&1) || EXIT_CODE=$? echo "$DEPLOY_OUTPUT" if [ $EXIT_CODE -eq 0 ]; then echo "[migrate] All migrations applied successfully." exit 0 fi # P3009: a previously-failed migration is blocking deploy. # The error message contains the migration name in backticks: # The `20260402000000_fix_severity_typo` migration started at ... failed # Strip ANSI escape codes first (Prisma may colorize output even without TTY), # then use a simple backtick-content regex rather than a rigid format match. CLEAN_OUTPUT=$(printf '%s\n' "$DEPLOY_OUTPUT" | sed 's/\x1b\[[0-9;]*[mGKHFJr]//g') if printf '%s\n' "$CLEAN_OUTPUT" | grep -q "P3009"; then FAILED=$(printf '%s\n' "$CLEAN_OUTPUT" | grep -o '`[^`]*`' | grep '[0-9]' | tr -d '`' | head -1) if [ -n "$FAILED" ]; then echo "[migrate] Resolving failed migration as rolled-back: $FAILED" RESOLVE_OUTPUT="" RESOLVE_EXIT=0 RESOLVE_OUTPUT=$(bunx prisma migrate resolve --rolled-back "$FAILED" 2>&1) || RESOLVE_EXIT=$? echo "$RESOLVE_OUTPUT" if [ $RESOLVE_EXIT -ne 0 ]; then echo "[migrate] Failed to resolve migration $FAILED (exit $RESOLVE_EXIT). Aborting." exit 1 fi continue fi fi echo "[migrate] Migration failed with a non-recoverable error." exit 1 done echo "[migrate] Exceeded max retries ($MAX_RETRIES). Giving up." exit 1