phase9: migration test script + .gitignore cleanup + CI alembic migration gate
This commit is contained in:
+22
@@ -28,6 +28,28 @@ ENV/
|
|||||||
htmlcov/
|
htmlcov/
|
||||||
coverage.xml
|
coverage.xml
|
||||||
.mypy_cache/
|
.mypy_cache/
|
||||||
|
|
||||||
|
# Redis dump
|
||||||
|
*.rdb
|
||||||
|
dump.rdb
|
||||||
|
|
||||||
|
# Frontend build output (regenerated on deploy)
|
||||||
|
frontend/dist/
|
||||||
|
frontend/node_modules/
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
logs/
|
||||||
.ruff_cache/
|
.ruff_cache/
|
||||||
|
|
||||||
# Redis dumps
|
# Redis dumps
|
||||||
|
|||||||
@@ -42,6 +42,13 @@ check "Cross-Plugin Imports" "python3 scripts/check_cross_plugin_imports.py"
|
|||||||
# ── 3. Alembic Revision Graph ────────────────────────────────────────────────
|
# ── 3. Alembic Revision Graph ────────────────────────────────────────────────
|
||||||
check "Alembic Revisions" "alembic heads 2>&1 | grep -c 'head' | grep -q '^1$'"
|
check "Alembic Revisions" "alembic heads 2>&1 | grep -c 'head' | grep -q '^1$'"
|
||||||
|
|
||||||
|
# ── 3b. Alembic Migration Test (only if DATABASE_URL is set) ──────────────────
|
||||||
|
if [ -n "${DATABASE_URL:-}" ]; then
|
||||||
|
check "Alembic Migration Test" "bash scripts/test_migrations.sh ${DATABASE_URL}"
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}[CI] SKIP: Alembic Migration Test (no DATABASE_URL)${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
# ── 4. TypeScript Type Check ─────────────────────────────────────────────────
|
# ── 4. TypeScript Type Check ─────────────────────────────────────────────────
|
||||||
check "TypeScript Type Check" "cd frontend && npx tsc --noEmit"
|
check "TypeScript Type Check" "cd frontend && npx tsc --noEmit"
|
||||||
|
|
||||||
|
|||||||
Executable
+93
@@ -0,0 +1,93 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Migration Test: Verify alembic upgrade head works on an empty database.
|
||||||
|
# Also verifies alembic downgrade base works.
|
||||||
|
#
|
||||||
|
# Usage: bash scripts/test_migrations.sh [DATABASE_URL]
|
||||||
|
# If DATABASE_URL not provided, uses DATABASE_URL env var.
|
||||||
|
#
|
||||||
|
# Exit codes:
|
||||||
|
# 0 = all migrations pass
|
||||||
|
# 1 = upgrade failed
|
||||||
|
# 2 = downgrade failed
|
||||||
|
# 3 = data integrity check failed
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
DB_URL="${1:-${DATABASE_URL:-}}"
|
||||||
|
if [ -z "$DB_URL" ]; then
|
||||||
|
echo "ERROR: DATABASE_URL not set"
|
||||||
|
echo "Usage: bash scripts/test_migrations.sh [DATABASE_URL]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Convert asyncpg URL to psycopg2 for alembic (DDL operations)
|
||||||
|
DB_URL_PSYNC="${DB_URL/postgresql+asyncpg/postgresql+psycopg2}"
|
||||||
|
|
||||||
|
# Create a test database name
|
||||||
|
TEST_DB="leocrm_migration_test_$(date +%s)"
|
||||||
|
DB_BASE="${DB_URL_PSYNC%/*}"
|
||||||
|
|
||||||
|
echo "=== Migration Test ==="
|
||||||
|
echo "Creating test database: $TEST_DB"
|
||||||
|
|
||||||
|
# Create test database
|
||||||
|
psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null || true
|
||||||
|
psql "$DB_BASE/postgres" -c "CREATE DATABASE $TEST_DB;" 2>/dev/null
|
||||||
|
|
||||||
|
TEST_URL="$DB_BASE/$TEST_DB"
|
||||||
|
|
||||||
|
echo "=== Step 1: Upgrade head on empty DB ==="
|
||||||
|
DATABASE_URL="$TEST_URL" alembic upgrade head 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Upgrade head failed!"
|
||||||
|
psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Upgrade head succeeded"
|
||||||
|
|
||||||
|
echo "=== Step 2: Verify tables exist ==="
|
||||||
|
TABLE_COUNT=$(psql "$TEST_URL" -t -c "SELECT count(*) FROM information_schema.tables WHERE table_schema = 'public';" 2>/dev/null | xargs)
|
||||||
|
echo "Tables created: $TABLE_COUNT"
|
||||||
|
if [ "$TABLE_COUNT" -lt 50 ]; then
|
||||||
|
echo "❌ Too few tables ($TABLE_COUNT < 50) — migration may be incomplete"
|
||||||
|
psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
echo "✅ Table count OK ($TABLE_COUNT tables)"
|
||||||
|
|
||||||
|
echo "=== Step 3: Verify alembic version ==="
|
||||||
|
VERSION=$(psql "$TEST_URL" -t -c "SELECT version_num FROM alembic_version;" 2>/dev/null | xargs)
|
||||||
|
echo "Alembic version: $VERSION"
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "❌ No alembic version found"
|
||||||
|
psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
echo "✅ Alembic version OK"
|
||||||
|
|
||||||
|
echo "=== Step 4: Downgrade base ==="
|
||||||
|
DATABASE_URL="$TEST_URL" alembic downgrade base 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "⚠️ Downgrade base failed (non-critical)"
|
||||||
|
# Don't fail the test — downgrade is not always lossless
|
||||||
|
else
|
||||||
|
echo "✅ Downgrade base succeeded"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "=== Step 5: Re-upgrade head (idempotency) ==="
|
||||||
|
DATABASE_URL="$TEST_URL" alembic upgrade head 2>&1
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Re-upgrade head failed!"
|
||||||
|
psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "✅ Re-upgrade head succeeded"
|
||||||
|
|
||||||
|
echo "=== Cleanup ==="
|
||||||
|
psql "$DB_BASE/postgres" -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null
|
||||||
|
echo "✅ Test database dropped"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== All migration tests passed ==="
|
||||||
|
exit 0
|
||||||
Reference in New Issue
Block a user