mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-07-26 22:25:41 +00:00
ci: automated Telegram-gated Supabase deploy (edge functions + migrations)
Adds a deploy-supabase job to the quality gate so the self-hosted Supabase side ships the same way as the frontend/backend instead of by hand: - gated by the existing telegram-gate (owner approves once, in Telegram) - runs on main-push in parallel with deploy-app, so edge functions, DB migrations and the new frontend go live in one post-approval window - rsyncs the edge-function dirs into the edge-runtime volume (hot-reloaded, no restart; --no-delete preserves the telegram-* functions) - applies pending migrations via deploy/apply-migrations.sh: idempotent and transactional, tracked in supabase_migrations.schema_migrations, skips non-versioned files (COMBINED_*), never half-records a failed migration - post-deploy health check verifies the fund-custody guards took effect (anon lost EXECUTE on the escrow/withdraw RPCs; both freeze triggers exist) - Telegram alert on success/failure Requires repo secrets SUPABASE_VPS_HOST/USER/SSH_KEY/PORT.
This commit is contained in:
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# apply-migrations.sh — idempotent, tracked migration applier for the self-hosted
|
||||
# Supabase Postgres. Runs ON the Supabase host (invoked by the deploy-supabase CI
|
||||
# job over SSH). Applies every versioned migration in $MIGRATIONS_DIR that is not
|
||||
# yet recorded in supabase_migrations.schema_migrations, in ascending version
|
||||
# order, each inside a single transaction together with its own tracking-row
|
||||
# insert — so a failed migration rolls back cleanly and is never half-recorded.
|
||||
#
|
||||
# Safe to re-run: already-recorded versions are skipped. Non-versioned files
|
||||
# (e.g. COMBINED_*.sql consolidated snapshots) are ignored.
|
||||
#
|
||||
# Usage: apply-migrations.sh <migrations_dir> [db_container]
|
||||
set -euo pipefail
|
||||
|
||||
MIGRATIONS_DIR="${1:?migrations dir required}"
|
||||
DB_CONTAINER="${2:-supabase-db}"
|
||||
PSQL=(docker exec -i "$DB_CONTAINER" psql -U postgres -v ON_ERROR_STOP=1 --single-transaction -q)
|
||||
PSQL_Q=(docker exec -i "$DB_CONTAINER" psql -U postgres -tAq)
|
||||
|
||||
echo "▶ apply-migrations: dir=$MIGRATIONS_DIR container=$DB_CONTAINER"
|
||||
|
||||
# Ensure the tracking schema/table exists (matches the Supabase CLI layout).
|
||||
"${PSQL[@]}" >/dev/null <<'SQL'
|
||||
CREATE SCHEMA IF NOT EXISTS supabase_migrations;
|
||||
CREATE TABLE IF NOT EXISTS supabase_migrations.schema_migrations (
|
||||
version text PRIMARY KEY,
|
||||
statements text[],
|
||||
name text
|
||||
);
|
||||
SQL
|
||||
|
||||
# Snapshot the already-applied versions once.
|
||||
applied="$("${PSQL_Q[@]}" -c "SELECT version FROM supabase_migrations.schema_migrations;")"
|
||||
is_applied() { grep -qxF "$1" <<<"$applied"; }
|
||||
|
||||
pending=0 done=0
|
||||
# Sort by filename so version order == chronological order (14-digit timestamps
|
||||
# and zero-padded legacy 0NN prefixes both sort correctly).
|
||||
for f in $(ls "$MIGRATIONS_DIR"/*.sql 2>/dev/null | sort); do
|
||||
base="$(basename "$f")"
|
||||
# Versioned migrations only: <digits>_<name>.sql. Skips COMBINED_*, README, etc.
|
||||
if [[ ! "$base" =~ ^([0-9]+)_(.+)\.sql$ ]]; then
|
||||
echo " ↷ skip (not a versioned migration): $base"
|
||||
continue
|
||||
fi
|
||||
version="${BASH_REMATCH[1]}"
|
||||
name="${BASH_REMATCH[2]}"
|
||||
|
||||
if is_applied "$version"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
pending=$((pending+1))
|
||||
if [[ "${DRY_RUN:-}" == "1" ]]; then
|
||||
echo " → [dry-run] WOULD apply $version ($name)"
|
||||
continue
|
||||
fi
|
||||
echo " → applying $version ($name)"
|
||||
# Migration body + its tracking insert in ONE transaction (--single-transaction):
|
||||
# if the body errors, ON_ERROR_STOP aborts and the whole tx (including the insert)
|
||||
# rolls back, so the version is never recorded for a failed apply.
|
||||
# version is always digits and name always [a-z0-9_] (captured from the filename
|
||||
# regex above), so direct single-quoting is safe — no injection surface.
|
||||
{
|
||||
cat "$f"
|
||||
printf "\nINSERT INTO supabase_migrations.schema_migrations(version,name) VALUES ('%s','%s');\n" \
|
||||
"$version" "$name"
|
||||
} | "${PSQL[@]}"
|
||||
echo " ✓ applied and recorded $version"
|
||||
done=$((done+1))
|
||||
done
|
||||
|
||||
if [[ $pending -eq 0 ]]; then
|
||||
echo "✔ up to date — no pending migrations"
|
||||
else
|
||||
echo "✔ applied $done migration(s)"
|
||||
fi
|
||||
Reference in New Issue
Block a user