DevOps – Build A CI/CD Pipeline
# cloudbuild.yaml — The Recipe for Your Pipeline
steps:
# ============================================
# STEP 1: Run Tests
# ============================================
- name: 'python:3.11-slim'
entrypoint: 'bash'
args:
- '-c'
- |
pip install pytest pytest-cov
pip install -r requirements.txt
pytest tests/ – cov=app/
id: 'Run Tests'
# ============================================
# STEP 2: Build Docker Image
# ============================================
- name: 'gcr.io/cloud-builders/docker'
args:
- 'build'
- '-t'
- '$_ARTIFACT_REGISTRY/$_IMAGE_NAME:$COMMIT_SHA'
- '-t'
- '$_ARTIFACT_REGISTRY/$_IMAGE_NAME:latest'
- '.'
id: 'Build Image'
# ============================================
# STEP 3: Push to Artifact Registry
# ============================================
- name: 'gcr.io/cloud-builders/docker'
args:
- 'push'
- '$_ARTIFACT_REGISTRY/$_IMAGE_NAME:$COMMIT_SHA'
id: 'Push Image'
# ============================================
# STEP 4: Deploy to Cloud Run
# ============================================
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'run'
- 'deploy'
- '$_SERVICE_NAME'
- '--image'
- '$_ARTIFACT_REGISTRY/$_IMAGE_NAME:$COMMIT_SHA'
- '--region'
- '$_REGION'
- '--platform'
- 'managed'
- '--allow-unauthenticated'
- '--service-account'
- '$_SERVICE_ACCOUNT'
- '--set-env-vars'
- 'MODEL_VERSION=$_MODEL_VERSION'
id: 'Deploy to Cloud Run'
# ============================================
# Store images with version tags
# ============================================
images:
- '$_ARTIFACT_REGISTRY/$_IMAGE_NAME:$COMMIT_SHA'
- '$_ARTIFACT_REGISTRY/$_IMAGE_NAME:latest'
# ============================================
# Use a service account for the pipeline
# ============================================
serviceAccount: 'projects/$PROJECT_ID/serviceAccounts/cloud-build-sa@$PROJECT_ID.iam.gserviceaccount.com'
# cloudbuild.yaml with rollback
steps:
# ... deployment steps ...
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'run'
- 'services'
- 'describe'
- '$_SERVICE_NAME'
- '--region'
- '$_REGION'
- '--format'
- 'value(status.latestCreatedRevisionName)'
id: 'Get Revision'
- name: 'bash'
args:
- '-c'
- |
# Wait for new revision to be ready
sleep 30
# Check error rate (simplified)
REVISION=$(gcloud run services describe $_SERVICE_NAME – region $_REGION – format 'value(status.latestCreatedRevisionName)')
ERRORS=$(gcloud logging read "resource.type=cloud_run_revision AND resource.labels.revision_name=$REVISION AND severity=ERROR" – limit=10 – format='value(textPayload)' | wc -l)
if [ $ERRORS -gt 5 ]; then
echo "🔥 Too many errors! Rolling back..."
gcloud run services update-traffic $_SERVICE_NAME – to-revisions=$_PREVIOUS_REVISION=100 – region $_REGION
else
echo "✅ Deployment healthy!"
fi
id: 'Health Check & Rollback'
