GitHub Actions CI/CD Setup Guide
Generated: 2025-08-09 UTC
Platform: GitHub Actions + Google Cloud Run
Pipeline: Automated testing, staging, and production deployments
Overview
This guide explains how to set up automated CI/CD using GitHub Actions for deploying Sasha Studio to Google Cloud Run. The pipeline includes:
- Automated Testing: On every PR
- Staging Deployments: For PR previews
- Production Deployments: On merge to main
- Automatic Rollback: On deployment failures
- Security Scanning: Vulnerability detection
- Performance Monitoring: Bundle size and Lighthouse checks
Pipeline Architecture
Quick Setup
1. Create Service Account
# Create service account for GitHub Actions
PROJECT_ID=your-project-id
SA_NAME=github-actions
gcloud iam service-accounts create $SA_NAME \
--display-name="GitHub Actions Deploy"
# Grant necessary permissions
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/run.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/storage.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/cloudbuild.builds.editor"
# Create and download key
gcloud iam service-accounts keys create github-actions-key.json \
--iam-account=$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com
2. Add GitHub Secrets
Go to your GitHub repository β Settings β Secrets and variables β Actions
Add these secrets:
| Secret Name | Description | How to Get |
|---|---|---|
GCP_PROJECT_ID |
Your GCP project ID | gcloud config get-value project |
GCP_SA_KEY |
Service account JSON key | Contents of github-actions-key.json |
GCP_SA_KEY_STAGING |
Staging service account key | Same or separate account |
3. Enable Workflows
Push the workflow files to your repository:
git add .github/workflows/
git commit -m "Add GitHub Actions CI/CD workflows"
git push origin main
Workflow Configurations
Deploy to GCP Workflow
File: .github/workflows/deploy-to-gcp.yml
Triggers:
- Push to
mainbranch β Production deployment - Pull requests β Staging deployment
- Manual trigger β Choose environment
Jobs:
- Test: Run tests and linting
- Deploy Staging: Deploy PR to staging environment
- Deploy Production: Deploy main branch to production
- Rollback: Automatic rollback on failure
PR Checks Workflow
File: .github/workflows/pr-checks.yml
Triggers:
- Pull request opened/updated
Jobs:
- Code Quality: ESLint, type checking
- Docker Build: Test container build
- Security Scan: Vulnerability scanning
- Size Check: Bundle size analysis
- Lighthouse: Performance testing
Configuration Details
Environment Variables
Set in workflow files:
env:
PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
SERVICE_NAME: sasha-studio
REGION: us-central1
Staging vs Production
| Aspect | Staging | Production |
|---|---|---|
| Branch | Pull requests | main |
| Service Name | sasha-studio-staging | sasha-studio |
| Min Instances | 0 | 0-1 |
| Max Instances | 5 | 10 |
| Secrets Suffix | -staging | (none) |
Deployment Strategies
Blue-Green Deployment
Modify the production deployment step:
- name: Deploy with Blue-Green
run: |
# Deploy new version without traffic
gcloud run deploy $SERVICE_NAME \
--image $IMAGE \
--no-traffic \
--tag blue
# Test blue deployment
BLUE_URL=$(gcloud run services describe $SERVICE_NAME \
--region $REGION \
--format 'value(status.traffic[0].url)')
curl -f "$BLUE_URL/api/health"
# Switch traffic
gcloud run services update-traffic $SERVICE_NAME \
--to-tags blue=100
Canary Deployment
Gradual rollout:
- name: Canary Deployment
run: |
# Deploy with 10% traffic
gcloud run services update-traffic $SERVICE_NAME \
--to-latest=10
# Monitor for 5 minutes
sleep 300
# Increase to 50%
gcloud run services update-traffic $SERVICE_NAME \
--to-latest=50
# Monitor for 5 minutes
sleep 300
# Full rollout
gcloud run services update-traffic $SERVICE_NAME \
--to-latest=100
Security Best Practices
1. Least Privilege Access
Create separate service accounts for different environments:
# Staging service account (limited permissions)
gcloud iam service-accounts create github-staging \
--display-name="GitHub Staging Deploy"
# Production service account (production only)
gcloud iam service-accounts create github-production \
--display-name="GitHub Production Deploy"
2. Secret Rotation
Rotate service account keys regularly:
# List existing keys
gcloud iam service-accounts keys list \
--iam-account=github-actions@$PROJECT_ID.iam.gserviceaccount.com
# Create new key
gcloud iam service-accounts keys create new-key.json \
--iam-account=github-actions@$PROJECT_ID.iam.gserviceaccount.com
# Update GitHub secret
gh secret set GCP_SA_KEY < new-key.json
# Delete old key
gcloud iam service-accounts keys delete KEY_ID \
--iam-account=github-actions@$PROJECT_ID.iam.gserviceaccount.com
3. Environment Protection
Configure GitHub environment protection rules:
- Go to Settings β Environments
- Create
productionenvironment - Add protection rules:
- Required reviewers
- Deployment branches:
mainonly - Wait timer: 5 minutes
Monitoring & Alerts
GitHub Actions Monitoring
View workflow runs:
- Repository β Actions tab
- Filter by workflow, branch, or status
Set Up Notifications
- name: Notify Slack on Deployment
uses: slackapi/slack-github-action@v1
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
payload: |
{
"text": "Deployment to ${{ env.ENVIRONMENT }} completed",
"attachments": [{
"color": "good",
"fields": [{
"title": "Version",
"value": "${{ github.sha }}",
"short": true
}]
}]
}
Cloud Run Monitoring
- name: Create Uptime Check
run: |
gcloud monitoring uptime-checks create \
--display-name="Sasha Studio Production" \
--uri="${{ steps.deploy.outputs.url }}/api/health"
Troubleshooting
Common Issues
1. Authentication Failures
# Verify service account
gcloud iam service-accounts get-iam-policy \
github-actions@$PROJECT_ID.iam.gserviceaccount.com
# Check secret in GitHub
gh secret list
2. Build Timeouts
Increase timeout in workflow:
jobs:
deploy:
timeout-minutes: 45 # Increase from default 360
3. Deployment Failures
Check logs:
# GitHub Actions logs
gh run view RUN_ID --log
# Cloud Build logs
gcloud builds list --limit=5
gcloud builds log BUILD_ID
# Cloud Run logs
gcloud run services logs read sasha-studio --region=us-central1
Manual Deployment
Trigger deployment manually:
# Using GitHub CLI
gh workflow run deploy-to-gcp.yml \
-f environment=production
# Using GitHub UI
# Go to Actions β Deploy to GCP β Run workflow
Performance Optimization
1. Cache Dependencies
- uses: actions/cache@v3
with:
path: |
~/.npm
~/.cache
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
2. Parallel Jobs
jobs:
test:
strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
3. Docker Layer Caching
- uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max
Advanced Features
Matrix Deployments
Deploy to multiple regions:
strategy:
matrix:
region: [us-central1, europe-west2, asia-southeast1]
steps:
- name: Deploy to ${{ matrix.region }}
run: |
gcloud run deploy $SERVICE_NAME \
--region ${{ matrix.region }}
Approval Gates
Require manual approval for production:
jobs:
approve:
runs-on: ubuntu-latest
environment: production-approval
steps:
- name: Request Approval
run: echo "Waiting for approval..."
deploy:
needs: approve
# ... deployment steps
CI/CD Checklist
Before going live:
- Service account created with correct permissions
- GitHub secrets configured
- Branch protection rules enabled
- Environment protection for production
- Monitoring and alerts configured
- Rollback procedure tested
- Security scanning enabled
- Performance benchmarks established
- Documentation updated
- Team training completed
Getting Help
Last Updated: 2025-08-09
Maintained By: Sasha Studio DevOps Team