Skip to content

chore(db): regenerate prod database types #26

chore(db): regenerate prod database types

chore(db): regenerate prod database types #26

Workflow file for this run

# Deploy to production — runs on push to main
# Migrations require manual approval via the "production" environment
name: Deploy Prod
on:
push:
branches: [main]
workflow_dispatch:
inputs:
force_migrations:
description: 'Force-push migrations (skip preflight diff check)'
type: boolean
default: true
# Never cancel in-flight migrations
concurrency:
group: deploy-prod
cancel-in-progress: false
jobs:
# ─── Preflight: detect if migrations changed ──────────────────
preflight:
name: Preflight
runs-on: ubuntu-latest
outputs:
has_new_migrations: ${{ steps.check.outputs.has_new_migrations }}
steps:
- uses: actions/checkout@v4
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Link to prod project
run: supabase link --project-ref "${{ secrets.SUPABASE_PROD_PROJECT_REF }}"
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
- name: Check for pending migrations
id: check
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_PROD_DB_PASSWORD }}
run: |
if [ "${{ github.event_name }}" = "workflow_dispatch" ] && [ "${{ inputs.force_migrations }}" = "true" ]; then
echo "has_new_migrations=true" >> "$GITHUB_OUTPUT"
echo "### Forced migrations via workflow_dispatch 🔄" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
OUTPUT=$(supabase db diff --linked 2>&1)
# Detect actual drift by checking for SQL statements (contain semicolons)
if echo "$OUTPUT" | grep -q ';'; then
echo "has_new_migrations=true" >> "$GITHUB_OUTPUT"
echo "### New migrations detected 🔄" >> "$GITHUB_STEP_SUMMARY"
else
echo "has_new_migrations=false" >> "$GITHUB_OUTPUT"
echo "### No new migrations ✅" >> "$GITHUB_STEP_SUMMARY"
fi
# ─── Migrate: only if new migrations, requires manual approval ─
migrate:
name: Push Migrations
needs: [preflight]
if: needs.preflight.outputs.has_new_migrations == 'true'
runs-on: ubuntu-latest
# Requires manual approval from reviewers configured on the "production" environment
environment: production
steps:
- uses: actions/checkout@v4
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Link to prod project
run: supabase link --project-ref "${{ secrets.SUPABASE_PROD_PROJECT_REF }}"
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
- name: Lint migrations
run: supabase db lint --linked
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
- name: Push migrations
run: supabase db push
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_PROD_DB_PASSWORD }}
- name: Verify no schema drift after push
run: |
OUTPUT=$(supabase db diff --linked 2>&1)
# Detect remaining drift by checking for SQL statements (contain semicolons)
if echo "$OUTPUT" | grep -q ';'; then
echo "::error::Schema drift remains after push — production may have manual changes"
echo '```sql' >> "$GITHUB_STEP_SUMMARY"
echo "$OUTPUT" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
exit 1
fi
echo "### Schema drift check — Clean ✅" >> "$GITHUB_STEP_SUMMARY"
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_PROD_DB_PASSWORD }}
- name: Summary
if: always()
run: echo "### Prod Migrate ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"
# ─── Generate prod types ──────────────────────────────────────
generate-types:
name: Generate Prod Types
needs: [preflight, migrate]
# Run after migrate succeeds, or if migrate was skipped (no new migrations)
if: always() && (needs.migrate.result == 'success' || needs.migrate.result == 'skipped')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: main
token: ${{ secrets.TYPES_PUSH_TOKEN }}
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Link to prod project
run: supabase link --project-ref "${{ secrets.SUPABASE_PROD_PROJECT_REF }}"
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
- name: Generate TypeScript types
run: supabase gen types typescript --linked > types/database.ts
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_PROD_DB_PASSWORD }}
- name: Push types if changed
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add packages/db/types/database.ts
if git diff --staged --quiet; then
echo "No type changes detected"
echo "TYPES_CHANGED=false" >> "$GITHUB_ENV"
else
git commit -m "chore(db): regenerate prod database types"
git push
echo "TYPES_CHANGED=true" >> "$GITHUB_ENV"
fi
- name: Summary
run: |
if [ "$TYPES_CHANGED" = "true" ]; then
echo "### Types — pushed to main ✅" >> "$GITHUB_STEP_SUMMARY"
else
echo "### Types — No changes ✅" >> "$GITHUB_STEP_SUMMARY"
fi
# ─── Smoke test: always runs (even if migration was skipped) ──
smoke-test:
name: Smoke Test
needs: [preflight, migrate]
# Run regardless of whether migrate ran or was skipped
if: always() && (needs.migrate.result == 'success' || needs.migrate.result == 'skipped')
runs-on: ubuntu-latest
steps:
- name: Health check
run: |
PROD_URL="${{ vars.PRODUCTION_URL }}"
if [ -z "$PROD_URL" ]; then
echo "::notice::PRODUCTION_URL variable not set — skipping smoke test"
echo "### Smoke Test — Skipped (no PRODUCTION_URL) ⏭️" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
# Retry up to 3 times with 10s wait (Vercel deploy may still be propagating)
for i in 1 2 3; do
STATUS=$(curl -sf -o /dev/null -w '%{http_code}' "${PROD_URL}/api/health" || true)
if [ "$STATUS" = "200" ]; then
echo "### Smoke Test — Healthy ✅" >> "$GITHUB_STEP_SUMMARY"
exit 0
fi
echo "Attempt $i: got status $STATUS, retrying in 10s..."
sleep 10
done
echo "::error::Health check failed after 3 attempts (last status: $STATUS)"
echo "### Smoke Test — Failed ❌ (status: $STATUS)" >> "$GITHUB_STEP_SUMMARY"
exit 1
# ─── Summary ──────────────────────────────────────────────────
summary:
name: Summary
needs: [preflight, migrate, generate-types, smoke-test]
if: always()
runs-on: ubuntu-latest
steps:
- name: Deployment summary
run: |
cat >> "$GITHUB_STEP_SUMMARY" <<EOF
## Production Deploy Summary
| Job | Status |
|-----|--------|
| Preflight | ${{ needs.preflight.result }} |
| Migrations | ${{ needs.migrate.result }} |
| Generate Types | ${{ needs.generate-types.result }} |
| Smoke Test | ${{ needs.smoke-test.result }} |
**New migrations:** ${{ needs.preflight.outputs.has_new_migrations }}
EOF