Last updated: Aug 12, 2025, 01:09 PM UTC

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

graph LR subgraph "Developer" PR[Pull Request] PUSH[Push to Main] end subgraph "GitHub Actions" TEST[Test & Lint] BUILD[Build Docker] SCAN[Security Scan] PERF[Performance Check] end subgraph "Deployments" STAGE[Staging] PROD[Production] ROLL[Rollback] end PR --> TEST TEST --> BUILD BUILD --> SCAN SCAN --> PERF PERF --> STAGE PUSH --> TEST TEST --> PROD PROD -.->|On Failure| ROLL

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 main branch β†’ Production deployment
  • Pull requests β†’ Staging deployment
  • Manual trigger β†’ Choose environment

Jobs:

  1. Test: Run tests and linting
  2. Deploy Staging: Deploy PR to staging environment
  3. Deploy Production: Deploy main branch to production
  4. Rollback: Automatic rollback on failure

PR Checks Workflow

File: .github/workflows/pr-checks.yml

Triggers:

  • Pull request opened/updated

Jobs:

  1. Code Quality: ESLint, type checking
  2. Docker Build: Test container build
  3. Security Scan: Vulnerability scanning
  4. Size Check: Bundle size analysis
  5. 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:

  1. Go to Settings β†’ Environments
  2. Create production environment
  3. Add protection rules:
    • Required reviewers
    • Deployment branches: main only
    • 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