|
| 1 | +#!/bin/bash |
| 2 | +# Dump baseline schema from a fresh Supabase instance |
| 3 | +# |
| 4 | +# This script: |
| 5 | +# 1. Creates a fresh Supabase project (no pgflow) |
| 6 | +# 2. Verifies extension availability matches our assumptions |
| 7 | +# 3. Dumps the schema as our baseline |
| 8 | +# 4. Cleans up |
| 9 | +# |
| 10 | +# Run this when: |
| 11 | +# - Supabase CLI version changes |
| 12 | +# - Adding new Supabase-provided schemas to baseline |
| 13 | + |
| 14 | +set -euo pipefail |
| 15 | + |
| 16 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 17 | +cd "$SCRIPT_DIR" |
| 18 | + |
| 19 | +# Use npx to run supabase directly in this directory (not via pnpm which runs from pkgs/core) |
| 20 | +SUPA="npx supabase" |
| 21 | + |
| 22 | +echo "=== Cleaning up any previous temp project ===" |
| 23 | +rm -rf supabase/ || true |
| 24 | + |
| 25 | +echo "=== Initializing fresh Supabase project ===" |
| 26 | +$SUPA init --force |
| 27 | + |
| 28 | +echo "=== Stopping any running Supabase instances ===" |
| 29 | +$SUPA stop --all || true |
| 30 | + |
| 31 | +echo "=== Starting fresh Supabase ===" |
| 32 | +$SUPA start |
| 33 | + |
| 34 | +echo "=== Getting database URL ===" |
| 35 | +DB_URL=$($SUPA status --output json | jq -r '.DB_URL') |
| 36 | +echo "DB_URL: $DB_URL" |
| 37 | + |
| 38 | +echo "=== Matching hosted Supabase defaults ===" |
| 39 | +# Local CLI pre-installs pg_net, but hosted Supabase doesn't |
| 40 | +# Drop it to match hosted behavior (our migrations will create it) |
| 41 | +echo "Dropping pg_net to match hosted Supabase defaults..." |
| 42 | +psql "$DB_URL" -c "DROP EXTENSION IF EXISTS pg_net CASCADE;" 2>/dev/null || true |
| 43 | + |
| 44 | +echo "=== Verifying extension assumptions ===" |
| 45 | +# Query extension status (using --no-psqlrc to avoid extra output) |
| 46 | +EXTENSION_STATUS=$(PAGER='' psql "$DB_URL" --no-psqlrc -t -A -F'|' -c " |
| 47 | +SELECT |
| 48 | + name, |
| 49 | + CASE WHEN installed_version IS NOT NULL THEN 'installed' ELSE 'available' END as status |
| 50 | +FROM pg_available_extensions |
| 51 | +WHERE name IN ('pgmq', 'pg_cron', 'pg_net', 'supabase_vault') |
| 52 | +ORDER BY name; |
| 53 | +") |
| 54 | + |
| 55 | +echo "Extension status:" |
| 56 | +echo "$EXTENSION_STATUS" |
| 57 | + |
| 58 | +# Expected state matching HOSTED Supabase (not local CLI) |
| 59 | +# - supabase_vault: pre-installed |
| 60 | +# - pgmq, pg_cron, pg_net: available but NOT installed |
| 61 | +EXPECTED="pg_cron|available |
| 62 | +pg_net|available |
| 63 | +pgmq|available |
| 64 | +supabase_vault|installed" |
| 65 | + |
| 66 | +if [ "$EXTENSION_STATUS" != "$EXPECTED" ]; then |
| 67 | + echo "" |
| 68 | + echo "ERROR: Extension status does not match hosted Supabase assumptions!" |
| 69 | + echo "" |
| 70 | + echo "Expected (matching hosted Supabase):" |
| 71 | + echo "$EXPECTED" |
| 72 | + echo "" |
| 73 | + echo "Got:" |
| 74 | + echo "$EXTENSION_STATUS" |
| 75 | + echo "" |
| 76 | + echo "If hosted Supabase changed defaults, update this script's expectations." |
| 77 | + $SUPA stop |
| 78 | + rm -rf supabase/ |
| 79 | + exit 1 |
| 80 | +fi |
| 81 | + |
| 82 | +echo "" |
| 83 | +echo "Extension assumptions verified (matches hosted Supabase)!" |
| 84 | + |
| 85 | +echo "=== Dumping full \\dx output ===" |
| 86 | +psql "$DB_URL" -c '\dx' > fresh-extensions.txt |
| 87 | +echo "Saved to fresh-extensions.txt" |
| 88 | + |
| 89 | +echo "=== Dumping baseline schema ===" |
| 90 | +# Only dump schemas we need: |
| 91 | +# - realtime: we reference realtime.send() |
| 92 | +# - vault: supabase_vault is pre-installed here |
| 93 | +# Skip extensions schema - it contains Supabase internal event triggers |
| 94 | +# that reference roles not available in Atlas dev container |
| 95 | +atlas schema inspect \ |
| 96 | + --schema realtime,vault \ |
| 97 | + -u "$DB_URL?sslmode=disable" \ |
| 98 | + --format "{{ sql . }}" > supabase-baseline-schema.sql |
| 99 | + |
| 100 | +# Strip VERSION strings (they change between Supabase versions) |
| 101 | +sed -i 's/ VERSION "[^"]*"//g' supabase-baseline-schema.sql |
| 102 | + |
| 103 | +# Strip date-specific partitions (they change daily, we don't reference them) |
| 104 | +# e.g., messages_2025_12_04, messages_2025_12_05, etc. |
| 105 | +sed -i '/messages_20[0-9]\{2\}_[0-9]\{2\}_[0-9]\{2\}/d' supabase-baseline-schema.sql |
| 106 | + |
| 107 | +echo "Saved to supabase-baseline-schema.sql" |
| 108 | + |
| 109 | +echo "=== Stopping Supabase ===" |
| 110 | +$SUPA stop |
| 111 | + |
| 112 | +echo "=== Cleaning up temp project ===" |
| 113 | +rm -rf supabase/ |
| 114 | + |
| 115 | +echo "" |
| 116 | +echo "=== Done! ===" |
| 117 | +echo "Baseline regenerated from fresh Supabase." |
| 118 | +echo "Commit the updated supabase-baseline-schema.sql and fresh-extensions.txt" |
0 commit comments