name: Deploy Backend on: push: branches: [ main ] paths: - 'backend/**' - '.github/workflows/cd-backend.yml' workflow_dispatch: env: GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }} GCP_REGION: us-central1 SERVICE_NAME: accessible-video-api WORKER_SERVICE_NAME: accessible-video-worker jobs: deploy-api: name: Deploy API to Cloud Run runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' permissions: contents: read id-token: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: workload_identity_provider: ${{ secrets.WIF_PROVIDER }} service_account: ${{ secrets.WIF_SERVICE_ACCOUNT }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v2 - name: Configure Docker auth run: gcloud auth configure-docker - name: Build and push Docker image working-directory: ./backend run: | # Build image with multi-stage optimization docker build \ --target production \ --tag gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.SERVICE_NAME }}:${{ github.sha }} \ --tag gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.SERVICE_NAME }}:latest \ . # Push images docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.SERVICE_NAME }}:${{ github.sha }} docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.SERVICE_NAME }}:latest - name: Deploy to Cloud Run run: | gcloud run deploy ${{ env.SERVICE_NAME }} \ --image gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.SERVICE_NAME }}:${{ github.sha }} \ --region ${{ env.GCP_REGION }} \ --platform managed \ --allow-unauthenticated \ --set-env-vars APP_ENV=prod \ --set-secrets JWT_SECRET=jwt-secret:latest,MONGODB_URI=mongodb-uri:latest,REDIS_URL=redis-url:latest,GEMINI_API_KEY=gemini-api-key:latest,SENDGRID_API_KEY=sendgrid-api-key:latest,SENTRY_DSN=sentry-dsn:latest \ --memory 2Gi \ --cpu 2 \ --max-instances 100 \ --min-instances 1 \ --port 8000 \ --timeout 300 \ --concurrency 80 - name: Update traffic to new revision run: | gcloud run services update-traffic ${{ env.SERVICE_NAME }} \ --region ${{ env.GCP_REGION }} \ --to-latest deploy-worker: name: Deploy Worker to Cloud Run runs-on: ubuntu-latest needs: [deploy-api] permissions: contents: read id-token: write steps: - name: Checkout code uses: actions/checkout@v4 - name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: workload_identity_provider: ${{ secrets.WIF_PROVIDER }} service_account: ${{ secrets.WIF_SERVICE_ACCOUNT }} - name: Set up Cloud SDK uses: google-github-actions/setup-gcloud@v2 - name: Configure Docker auth run: gcloud auth configure-docker - name: Build and push worker image working-directory: ./backend run: | # Build worker image docker build \ --target worker \ --tag gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.WORKER_SERVICE_NAME }}:${{ github.sha }} \ --tag gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.WORKER_SERVICE_NAME }}:latest \ . # Push images docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.WORKER_SERVICE_NAME }}:${{ github.sha }} docker push gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.WORKER_SERVICE_NAME }}:latest - name: Deploy worker to Cloud Run run: | gcloud run deploy ${{ env.WORKER_SERVICE_NAME }} \ --image gcr.io/${{ env.GCP_PROJECT_ID }}/${{ env.WORKER_SERVICE_NAME }}:${{ github.sha }} \ --region ${{ env.GCP_REGION }} \ --platform managed \ --no-allow-unauthenticated \ --set-env-vars APP_ENV=prod \ --set-secrets JWT_SECRET=jwt-secret:latest,MONGODB_URI=mongodb-uri:latest,REDIS_URL=redis-url:latest,GEMINI_API_KEY=gemini-api-key:latest,SENDGRID_API_KEY=sendgrid-api-key:latest,SENTRY_DSN=sentry-dsn:latest \ --memory 4Gi \ --cpu 2 \ --max-instances 50 \ --min-instances 0 \ --timeout 1800 \ --concurrency 1 smoke-tests: name: Run Smoke Tests runs-on: ubuntu-latest needs: [deploy-api, deploy-worker] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: ${{ env.PYTHON_VERSION }} - name: Install Poetry uses: snok/install-poetry@v1 - name: Install dependencies working-directory: ./backend run: poetry install - name: Run smoke tests against production working-directory: ./backend env: API_BASE_URL: https://${{ env.SERVICE_NAME }}-${{ secrets.GCP_REGION_HASH }}-uc.a.run.app SMOKE_TEST_EMAIL: ${{ secrets.SMOKE_TEST_EMAIL }} SMOKE_TEST_PASSWORD: ${{ secrets.SMOKE_TEST_PASSWORD }} run: | poetry run pytest tests/e2e/test_smoke.py -v notify-deployment: name: Notify Deployment Status runs-on: ubuntu-latest needs: [smoke-tests] if: always() steps: - name: Notify success if: needs.smoke-tests.result == 'success' run: | echo "✅ Backend deployment completed successfully" # Add Slack/email notification here if needed - name: Notify failure if: needs.smoke-tests.result == 'failure' run: | echo "❌ Backend deployment failed" # Add Slack/email notification here if needed