Fix Google OAuth hanging issue with clean Supabase SSR implementation #46
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: π CI Pipeline | |
| on: | |
| push: | |
| branches: [ main, develop, fix/ci-pipeline ] | |
| pull_request: | |
| branches: [ main, develop ] | |
| # Permissions for GitHub token | |
| permissions: | |
| contents: write # Changed to write to allow commit comments | |
| pull-requests: write | |
| issues: write | |
| deployments: write | |
| # Concurrency settings to cancel outdated runs | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| NODE_VERSION: '18' | |
| jobs: | |
| # Stage 1: Code Quality | |
| lint-and-typecheck: | |
| name: π Code Quality | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: π₯ Checkout code | |
| uses: actions/checkout@v4 | |
| - name: π¦ Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: π¦ Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| - name: π Run ESLint | |
| run: npm run lint | |
| - name: π TypeScript check | |
| run: npm run type-check | |
| # Stage 2: Build | |
| build: | |
| name: ποΈ Build | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: lint-and-typecheck | |
| steps: | |
| - name: π₯ Checkout code | |
| uses: actions/checkout@v4 | |
| - name: π¦ Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: π¦ Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| - name: ποΈ Build application | |
| run: npm run build | |
| env: | |
| NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }} | |
| NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }} | |
| # Stage 3: Tests | |
| test: | |
| name: π§ͺ Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| needs: lint-and-typecheck | |
| steps: | |
| - name: π₯ Checkout code | |
| uses: actions/checkout@v4 | |
| - name: π¦ Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: π¦ Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| - name: π§ͺ Run tests | |
| run: npm run test:ci | |
| # Stage 4: E2E Tests (Simplified approach) | |
| e2e: | |
| name: π E2E Tests | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 # Back to reasonable timeout since we're using dev server | |
| needs: test # Only need tests to pass, not build | |
| if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main' || github.ref == 'refs/heads/fix/ci-pipeline' | |
| steps: | |
| - name: π₯ Checkout code | |
| uses: actions/checkout@v4 | |
| - name: π¦ Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: π¦ Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| - name: π Install Playwright browsers | |
| run: npx playwright install --with-deps | |
| - name: π Run E2E tests | |
| run: npx playwright test --config=playwright.ci.config.ts | |
| env: | |
| CI: true | |
| NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }} | |
| NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }} | |
| - name: π Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: e2e-results | |
| path: | | |
| test-results/ | |
| playwright-report/ | |
| retention-days: 7 | |
| # Stage 5: Deploy (Production only) | |
| deploy: | |
| name: π Deploy | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| needs: [build, test, e2e] | |
| env: | |
| VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} | |
| VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }} | |
| steps: | |
| - name: π₯ Checkout code | |
| uses: actions/checkout@v4 | |
| - name: π¦ Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: 'npm' | |
| - name: π¦ Install dependencies | |
| run: npm ci --legacy-peer-deps | |
| - name: π¦ Install Vercel CLI | |
| run: npm install --global vercel@latest | |
| - name: π Pull Vercel Environment Information | |
| run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }} | |
| - name: ποΈ Build Project Artifacts | |
| run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }} | |
| - name: π Deploy Project Artifacts to Vercel | |
| id: vercel-deploy | |
| run: | | |
| DEPLOYMENT_URL=$(vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}) | |
| echo "deployment-url=$DEPLOYMENT_URL" >> $GITHUB_OUTPUT | |
| echo "β Deployed to: $DEPLOYMENT_URL" | |
| - name: π¬ Comment on commit | |
| if: always() | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const deploymentUrl = '${{ steps.vercel-deploy.outputs.deployment-url }}'; | |
| const sha = context.sha; | |
| const commitUrl = `${context.payload.repository.html_url}/commit/${sha}`; | |
| // Create comment body | |
| const commentBody = `## π Production Deployment Complete | |
| **Deployment URL:** ${deploymentUrl} | |
| **Commit:** [${sha.slice(0, 7)}](${commitUrl}) | |
| **Branch:** ${context.ref.replace('refs/heads/', '')} | |
| **Workflow:** [${context.workflow}](${context.payload.repository.html_url}/actions/runs/${context.runId}) | |
| β Your application has been successfully deployed to production!`; | |
| // Post comment on commit | |
| await github.rest.repos.createCommitComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| commit_sha: sha, | |
| body: commentBody | |
| }); | |
| health-check: | |
| needs: [deploy] | |
| runs-on: ubuntu-latest | |
| if: github.ref == 'refs/heads/main' | |
| steps: | |
| - name: π₯ Wait for deployment to be ready | |
| run: sleep 30 | |
| - name: π₯ Health Check with Retry Logic | |
| id: health-check | |
| run: | | |
| MAX_ATTEMPTS=5 | |
| DELAY=15 | |
| URL="https://local-loop-qa.vercel.app/api/health" | |
| echo "π Starting health check for $URL" | |
| for i in $(seq 1 $MAX_ATTEMPTS); do | |
| echo "Attempt $i/$MAX_ATTEMPTS..." | |
| RESPONSE=$(curl -s -w "%{http_code}" "$URL" || echo "000") | |
| HTTP_CODE="${RESPONSE: -3}" | |
| BODY="${RESPONSE%???}" | |
| echo "HTTP Code: $HTTP_CODE" | |
| if [ "$HTTP_CODE" = "200" ]; then | |
| echo "β Health check passed!" | |
| echo "Response: $BODY" | |
| echo "success=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| elif [ "$HTTP_CODE" = "503" ]; then | |
| echo "β οΈ Service temporarily unavailable (503). Retrying..." | |
| else | |
| echo "β Health check failed with HTTP $HTTP_CODE" | |
| echo "Response: $BODY" | |
| fi | |
| if [ $i -lt $MAX_ATTEMPTS ]; then | |
| echo "β³ Waiting ${DELAY}s before retry..." | |
| sleep $DELAY | |
| fi | |
| done | |
| echo "β Health check failed after $MAX_ATTEMPTS attempts" | |
| echo "success=false" >> $GITHUB_OUTPUT | |
| exit 1 | |
| - name: π¨ Trigger Rollback on Health Check Failure | |
| if: steps.health-check.outputs.success == 'false' | |
| run: | | |
| echo "π¨ Deployment health check failed - triggering rollback workflow" | |
| curl -X POST \ | |
| -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| https://api.github.com/repos/${{ github.repository }}/actions/workflows/rollback.yml/dispatches \ | |
| -d '{"ref":"main","inputs":{"reason":"Health check failure after deployment"}}' |