Skip to content

Add comprehensive E2E test suite for admin and member flows #104

Add comprehensive E2E test suite for admin and member flows

Add comprehensive E2E test suite for admin and member flows #104

Workflow file for this run

# CI pipeline — runs on every PR to main and dev
# Validates code quality, types, build, tests, and database integrity
name: CI
on:
pull_request:
branches: [main, dev]
concurrency:
group: ci-${{ github.head_ref || github.ref_name }}
cancel-in-progress: true
env:
# Turborepo remote cache (optional — works without these)
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
# Filter to only packages affected since the PR base branch
TURBO_FILTER: --filter=...[origin/${{ github.base_ref }}]
jobs:
# ─── Lint & Type-check (parallel) ─────────────────────────────
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# Fetch base branch so turbo filter can diff against it
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Turbo lint
run: npx turbo run lint ${{ env.TURBO_FILTER }}
- name: Summary
if: always()
run: echo "### Lint ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"
typecheck:
name: Type-check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Turbo check-types
run: npx turbo run check-types ${{ env.TURBO_FILTER }}
- name: Summary
if: always()
run: echo "### Type-check ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"
# ─── Build & Test (parallel, after lint+typecheck) ────────────
build:
name: Build
needs: [lint, typecheck]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Turbo build
run: npx turbo run build ${{ env.TURBO_FILTER }}
- name: Summary
if: always()
run: echo "### Build ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"
test:
name: Test
needs: [lint, typecheck]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Start local Supabase (db + API only)
run: supabase start -x realtime,storage,imgproxy,inbucket,studio,edge-runtime,logflare,vector,supavisor
working-directory: packages/db
- name: Reset DB (migrations + seed)
run: supabase db reset
working-directory: packages/db
- name: Turbo test
run: npx turbo run test ${{ env.TURBO_FILTER }}
- name: Stop local Supabase
if: always()
run: supabase stop
working-directory: packages/db
- name: Summary
if: always()
run: echo "### Test ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"
# ─── E2E (after lint+typecheck) ───────────────────────────────
e2e:
name: E2E
needs: [lint, typecheck]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Start local Supabase
run: supabase start
working-directory: packages/db
- name: Export Supabase keys
id: supabase-keys
run: |
eval "$(supabase status -o env)"
echo "anon_key=${ANON_KEY}" >> "$GITHUB_OUTPUT"
echo "service_role_key=${SERVICE_ROLE_KEY}" >> "$GITHUB_OUTPUT"
working-directory: packages/db
- name: Reset DB (migrations + seed)
run: supabase db reset
working-directory: packages/db
- name: Wait for Supabase services to be ready
run: |
for i in $(seq 1 30); do
if curl -sf http://127.0.0.1:54321/rest/v1/ -H "apikey: $SUPABASE_ANON_KEY" > /dev/null 2>&1; then
echo "Supabase is ready"
exit 0
fi
echo "Waiting for Supabase... ($i/30)"
sleep 2
done
echo "Supabase failed to start"
exit 1
env:
SUPABASE_ANON_KEY: ${{ steps.supabase-keys.outputs.anon_key }}
- name: Install Playwright browsers (chromium)
run: npx playwright install --with-deps chromium
working-directory: apps/web
- name: Run Playwright tests
run: npx playwright test
working-directory: apps/web
env:
NEXT_PUBLIC_SUPABASE_URL: http://127.0.0.1:54321
NEXT_PUBLIC_SUPABASE_PUB_KEY: ${{ steps.supabase-keys.outputs.anon_key }}
SUPABASE_SECRET_KEY: ${{ steps.supabase-keys.outputs.service_role_key }}
- name: Upload Playwright report
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: apps/web/playwright-report/
retention-days: 7
- name: Stop local Supabase
if: always()
run: supabase stop
working-directory: packages/db
- name: Summary
if: always()
run: echo "### E2E ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"
# ─── Supabase database checks ────────────────────────────────
db-lint:
name: DB Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Link to dev project
run: supabase link --project-ref "${{ secrets.SUPABASE_DEV_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: Summary
if: always()
run: echo "### DB Lint ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"
schema-drift:
name: Schema Drift Detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Link to dev project
run: supabase link --project-ref "${{ secrets.SUPABASE_DEV_PROJECT_REF }}"
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
- name: Check for schema drift
# Warn-only — non-zero exit is informational, not blocking
continue-on-error: true
run: |
OUTPUT=$(supabase db diff --linked 2>&1) || true
if [ -n "$OUTPUT" ] && [ "$OUTPUT" != "No changes found" ]; then
echo "::warning::Schema drift detected against dev project"
echo "### ⚠️ Schema Drift Detected" >> "$GITHUB_STEP_SUMMARY"
echo '```sql' >> "$GITHUB_STEP_SUMMARY"
echo "$OUTPUT" >> "$GITHUB_STEP_SUMMARY"
echo '```' >> "$GITHUB_STEP_SUMMARY"
else
echo "### Schema Drift — None ✅" >> "$GITHUB_STEP_SUMMARY"
fi
working-directory: packages/db
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_DB_PASSWORD: ${{ secrets.SUPABASE_DEV_DB_PASSWORD }}
migration-dry-run:
name: Migration Dry Run
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Start local Supabase (db only)
# Only start the db service — skip realtime, storage, studio, etc. for speed
run: supabase start -x realtime,storage,imgproxy,inbucket,postgrest,gotrue,studio,edge-runtime,logflare,vector,supavisor
working-directory: packages/db
- name: Reset DB (replay all migrations + seed)
run: supabase db reset
working-directory: packages/db
- name: Stop local Supabase
if: always()
run: supabase stop
working-directory: packages/db
- name: Summary
if: always()
run: echo "### Migration Dry Run ${{ job.status == 'success' && '✅' || '❌' }}" >> "$GITHUB_STEP_SUMMARY"