#!/usr/bin/env bash # # Run all VYNDR migrations (011 onward) against Supabase in order. # # Every statement in the migrations is idempotent (IF NOT EXISTS, CREATE # OR REPLACE, DROP IF EXISTS), so this script is safe to re-run. # # Usage: # scripts/run-migrations.sh # runs against $SUPABASE_DB_URL # scripts/run-migrations.sh --dry-run # prints concatenated SQL to stdout # (paste into Supabase SQL Editor) # scripts/run-migrations.sh --from 015 # only run migrations >= 015 # # Requires for live run: # psql (PostgreSQL client) and SUPABASE_DB_URL env var. # Dry run requires only bash + the files in supabase/migrations/. set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" MIGRATIONS_DIR="$ROOT/supabase/migrations" DRY_RUN=0 FROM_PREFIX="" while [[ $# -gt 0 ]]; do case "$1" in --dry-run) DRY_RUN=1; shift ;; --from) FROM_PREFIX="$2"; shift 2 ;; --help) sed -n '/^# Usage:/,/^# Requires/p' "$0" exit 0 ;; *) echo "Unknown arg: $1" >&2; exit 2 ;; esac done # Migrations 001-010 were applied to production long before the VYNDR # rebuild. Default skipping straight to 011. Use --from to override. DEFAULT_FROM="011" FROM="${FROM_PREFIX:-$DEFAULT_FROM}" # Collect files >= FROM in numeric order. MIGRATIONS=() while IFS= read -r f; do base="$(basename "$f")" prefix="${base%%_*}" # Bash [[ ]] doesn't have a portable >= for strings; use numeric compare. # Strip leading zeros to avoid octal interpretation. pnum=$((10#$prefix)) fnum=$((10#$FROM)) if (( pnum >= fnum )); then MIGRATIONS+=("$f") fi done < <(find "$MIGRATIONS_DIR" -maxdepth 1 -type f -name '*.sql' | sort) if [[ ${#MIGRATIONS[@]} -eq 0 ]]; then echo "No migrations found at $MIGRATIONS_DIR matching --from $FROM" >&2 exit 1 fi # Concatenate with header banners so output is auditable. concat_sql() { for f in "${MIGRATIONS[@]}"; do printf -- '-- ============================================================\n' printf -- '-- %s\n' "$(basename "$f")" printf -- '-- ============================================================\n\n' cat "$f" printf '\n\n' done } if [[ "$DRY_RUN" -eq 1 ]]; then concat_sql exit 0 fi if [[ -z "${SUPABASE_DB_URL:-}" ]]; then echo "ERROR: SUPABASE_DB_URL is not set. Re-run with --dry-run to inspect SQL." >&2 exit 1 fi if ! command -v psql >/dev/null 2>&1; then echo "ERROR: psql is not installed. Install postgresql-client or use --dry-run." >&2 exit 1 fi echo "[migrations] applying ${#MIGRATIONS[@]} files to $(echo "$SUPABASE_DB_URL" | sed 's/:[^:@]*@/:***@/')" concat_sql | psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 echo "[migrations] complete"