name: Database Migrations on: push: branches: [main, 'feat/*'] paths: - 'migrations/*.sql' pull_request: paths: - 'migrations/*.sql' workflow_dispatch: env: DB_HOST: memory-db-rw.poimen.svc.cluster.local DB_PORT: "5432" DB_NAME: memory jobs: test-migrations: name: Test Migrations runs-on: rust steps: - name: Checkout code uses: actions/checkout@v4 - name: Install psql run: apt-get update && apt-get install -y postgresql-client - name: Detect changed migrations id: changed run: | git fetch origin main --depth=2 CHANGED=$(git diff --name-only HEAD~1 HEAD -- migrations/ 2>/dev/null || echo "") if [ -z "$CHANGED" ]; then echo "No migrations changed, running all" CHANGED=$(ls migrations/*.sql 2>/dev/null) fi echo "changed-migrations=$CHANGED" >> $GITHUB_OUTPUT echo "Migration files: $CHANGED" - name: Test migrations on clean database run: | export PGPASSWORD="${DB_PASSWORD}" export PGHOST="${DB_HOST}" export PGPORT="${DB_PORT}" export PGUSER="${DB_USER}" echo "=== Testing Migrations on Clean Database ===" echo "" # Try to create test database (may fail if user lacks permission) TEST_DB="memory_test_$$" echo "Creating test database: $TEST_DB" psql -d postgres -c "CREATE DATABASE $TEST_DB;" 2>/dev/null || { echo "Cannot create test DB (permission denied), using main DB instead" TEST_DB="${DB_NAME}" } echo "" echo "=== Applying migrations ===" FAILED=0 for f in $(ls migrations/*.sql 2>/dev/null | sort); do MIGRATION_NAME=$(basename "$f") echo "" echo "Applying: $MIGRATION_NAME" if psql -d "$TEST_DB" -f "$f" 2>&1 | grep -v "^$" | head -20; then echo "✓ $MIGRATION_NAME passed" else echo "✗ $MIGRATION_NAME failed" FAILED=1 fi done echo "" echo "=== Schema Verification ===" psql -d "$TEST_DB" -c "SELECT COUNT(*) as total_tables FROM pg_tables WHERE schemaname='public';" echo "" echo "Agent memory tables:" psql -d "$TEST_DB" -c "SELECT tablename FROM pg_tables WHERE tablename LIKE 'agent_%' ORDER BY tablename;" echo "" echo "Agent memory indices:" psql -d "$TEST_DB" -c "SELECT COUNT(*) as agent_indices FROM pg_indexes WHERE tablename LIKE 'agent_%';" # Cleanup if [ "$TEST_DB" != "${DB_NAME}" ]; then psql -d postgres -c "DROP DATABASE IF EXISTS $TEST_DB;" 2>/dev/null || true fi if [ $FAILED -eq 1 ]; then echo "" echo "✗ MIGRATION TEST FAILED" exit 1 fi echo "" echo "✓ ALL MIGRATIONS PASSED" env: DB_USER: ${{ secrets.DB_USER }} DB_PASSWORD: ${{ secrets.DB_PASSWORD }} apply-migrations: name: Apply Migrations to Production runs-on: rust needs: test-migrations if: github.event_name == 'push' && github.ref == 'refs/heads/main' steps: - name: Checkout code uses: actions/checkout@v4 - name: Install psql run: apt-get update && apt-get install -y postgresql-client - name: Apply migrations to production run: | export PGPASSWORD="${DB_PASSWORD}" export PGHOST="${DB_HOST}" export PGPORT="${DB_PORT}" export PGUSER="${DB_USER}" echo "=== Applying Migrations to Production ===" echo "" git fetch origin main --depth=2 CHANGED=$(git diff --name-only HEAD~1 HEAD -- migrations/ 2>/dev/null || echo "") if [ -z "$CHANGED" ]; then echo "No migrations changed" exit 0 fi echo "Changed migrations: $CHANGED" echo "" FAILED=0 for f in $CHANGED; do if [ -f "$f" ]; then MIGRATION_NAME=$(basename "$f") echo "Applying: $MIGRATION_NAME" if psql -d "${DB_NAME}" -f "$f" 2>&1 | grep -v "^$" | head -20; then echo "✓ $MIGRATION_NAME applied" else echo "✗ $MIGRATION_NAME failed" FAILED=1 fi echo "" fi done if [ $FAILED -eq 1 ]; then echo "✗ PRODUCTION MIGRATION FAILED" exit 1 fi echo "=== Production Schema After Migrations ===" psql -d "${DB_NAME}" -c "SELECT COUNT(*) as total_tables FROM pg_tables WHERE schemaname='public';" psql -d "${DB_NAME}" -c "SELECT tablename FROM pg_tables WHERE tablename LIKE 'agent_%' ORDER BY tablename;" echo "" echo "✓ PRODUCTION MIGRATIONS APPLIED SUCCESSFULLY" env: DB_USER: ${{ secrets.DB_USER }} DB_PASSWORD: ${{ secrets.DB_PASSWORD }} gate-on-migrations: name: Gate PR on Migrations runs-on: rust needs: test-migrations if: github.event_name == 'pull_request' steps: - name: Check migration tests run: | if [ "${{ needs.test-migrations.result }}" != "success" ]; then echo "❌ Migration tests failed" echo "" echo "This PR modifies migration files. The migrations must pass tests before merge." exit 1 fi echo "✅ Migration tests passed - PR is ready to merge"