147 lines
No EOL
5.1 KiB
YAML
147 lines
No EOL
5.1 KiB
YAML
name: Deploy Frontend
|
|
|
|
on:
|
|
push:
|
|
branches: [ main ]
|
|
paths:
|
|
- 'frontend/**'
|
|
- '.github/workflows/cd-frontend.yml'
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
|
|
GCP_REGION: us-central1
|
|
BUCKET_NAME: ${{ secrets.FRONTEND_BUCKET_NAME }}
|
|
CDN_URL_MAP: accessible-video-frontend
|
|
NODE_VERSION: "20"
|
|
|
|
jobs:
|
|
build-and-deploy:
|
|
name: Build and Deploy Frontend
|
|
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: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: ${{ env.NODE_VERSION }}
|
|
cache: 'npm'
|
|
cache-dependency-path: frontend/package-lock.json
|
|
|
|
- name: Install dependencies
|
|
working-directory: ./frontend
|
|
run: npm ci
|
|
|
|
- name: Build for production
|
|
working-directory: ./frontend
|
|
env:
|
|
VITE_API_BASE_URL: ${{ secrets.PRODUCTION_API_URL }}
|
|
VITE_APP_ENV: production
|
|
VITE_SENTRY_DSN: ${{ secrets.FRONTEND_SENTRY_DSN }}
|
|
run: npm run build
|
|
|
|
- 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: Deploy to Cloud Storage
|
|
working-directory: ./frontend
|
|
run: |
|
|
# Sync build files to Cloud Storage bucket
|
|
gsutil -m rsync -r -d dist/ gs://${{ env.BUCKET_NAME }}/
|
|
|
|
# Set public read permissions for web assets
|
|
gsutil -m acl ch -r -u AllUsers:R gs://${{ env.BUCKET_NAME }}
|
|
|
|
# Set cache headers for different file types
|
|
gsutil -m setmeta -h "Cache-Control:public, max-age=31536000, immutable" "gs://${{ env.BUCKET_NAME }}/**/*.js"
|
|
gsutil -m setmeta -h "Cache-Control:public, max-age=31536000, immutable" "gs://${{ env.BUCKET_NAME }}/**/*.css"
|
|
gsutil -m setmeta -h "Cache-Control:public, max-age=86400" "gs://${{ env.BUCKET_NAME }}/**/*.html"
|
|
gsutil -m setmeta -h "Cache-Control:public, max-age=86400" "gs://${{ env.BUCKET_NAME }}/index.html"
|
|
|
|
- name: Configure Load Balancer and CDN
|
|
run: |
|
|
# Create backend bucket if it doesn't exist
|
|
gcloud compute backend-buckets describe ${{ env.BUCKET_NAME }}-backend || \
|
|
gcloud compute backend-buckets create ${{ env.BUCKET_NAME }}-backend \
|
|
--gcs-bucket-name=${{ env.BUCKET_NAME }}
|
|
|
|
# Update the URL map to route to the bucket
|
|
gcloud compute url-maps describe ${{ env.CDN_URL_MAP }} || \
|
|
gcloud compute url-maps create ${{ env.CDN_URL_MAP }} \
|
|
--default-backend-bucket=${{ env.BUCKET_NAME }}-backend
|
|
|
|
# Create or update HTTPS proxy
|
|
gcloud compute target-https-proxies describe ${{ env.CDN_URL_MAP }}-https-proxy || \
|
|
gcloud compute target-https-proxies create ${{ env.CDN_URL_MAP }}-https-proxy \
|
|
--url-map=${{ env.CDN_URL_MAP }} \
|
|
--ssl-certificates=${{ secrets.SSL_CERT_NAME }}
|
|
|
|
# Create or update global forwarding rule
|
|
gcloud compute forwarding-rules describe ${{ env.CDN_URL_MAP }}-https-rule --global || \
|
|
gcloud compute forwarding-rules create ${{ env.CDN_URL_MAP }}-https-rule \
|
|
--global \
|
|
--target-https-proxy=${{ env.CDN_URL_MAP }}-https-proxy \
|
|
--ports=443
|
|
|
|
- name: Invalidate CDN cache
|
|
run: |
|
|
# Invalidate CDN cache for immediate deployment
|
|
gcloud compute url-maps invalidate-cdn-cache ${{ env.CDN_URL_MAP }} \
|
|
--path="/*" \
|
|
--async
|
|
|
|
- name: Run smoke tests
|
|
working-directory: ./frontend
|
|
env:
|
|
FRONTEND_URL: https://${{ secrets.FRONTEND_DOMAIN }}
|
|
run: |
|
|
# Wait a bit for CDN propagation
|
|
sleep 30
|
|
|
|
# Basic smoke test - check if main page loads
|
|
curl -f -s -o /dev/null -w "%{http_code}" "$FRONTEND_URL" | grep -q "200" || {
|
|
echo "Frontend smoke test failed - main page not accessible"
|
|
exit 1
|
|
}
|
|
|
|
# Check if assets are loading
|
|
curl -f -s -o /dev/null -w "%{http_code}" "$FRONTEND_URL/assets/" | grep -qE "(200|404)" || {
|
|
echo "Frontend smoke test failed - assets not accessible"
|
|
exit 1
|
|
}
|
|
|
|
echo "✅ Frontend smoke tests passed"
|
|
|
|
notify-deployment:
|
|
name: Notify Deployment Status
|
|
runs-on: ubuntu-latest
|
|
needs: [build-and-deploy]
|
|
if: always()
|
|
|
|
steps:
|
|
- name: Notify success
|
|
if: needs.build-and-deploy.result == 'success'
|
|
run: |
|
|
echo "✅ Frontend deployment completed successfully"
|
|
echo "Frontend is now live at: https://${{ secrets.FRONTEND_DOMAIN }}"
|
|
# Add Slack/email notification here if needed
|
|
|
|
- name: Notify failure
|
|
if: needs.build-and-deploy.result == 'failure'
|
|
run: |
|
|
echo "❌ Frontend deployment failed"
|
|
# Add Slack/email notification here if needed |