Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions .github/workflows/shared-cloudrun-rollback.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
name: Cloud Run Deploy with Auto Rollback

on:
workflow_call:
inputs:
gcp_registry_host:
required: true
type: string
IMAGE_NAME:
required: true
type: string
IMAGE_TAG:
required: true
type: string
GCP_REPOSITORY:
required: true
type: string
SERVICE_NAME:
required: true
type: string
REGION:
required: true
type: string

secrets:
GCP_PROJECT_ID:
required: true
GCP_SA_KEY:
required: true

outputs:
revision:
description: "Previous revision"
value: ${{ jobs.deploy.outputs.revision }}
service_name:
description: "Service name"
value: ${{ inputs.SERVICE_NAME }}

jobs:
deploy:
runs-on: ubuntu-latest
outputs:
revision: ${{ steps.prev.outputs.revision }}

steps:
- name: Authenticate to GCP
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.GCP_SA_KEY }}

- name: Setup gcloud
uses: google-github-actions/setup-gcloud@v2

- name: Get current revision
id: prev
run: |
REVISION=$(gcloud run services describe ${{ inputs.SERVICE_NAME }} \
--region ${{ inputs.REGION }} \
--format="value(status.traffic[0].revisionName)")
echo "Current revision: $REVISION"
# Set for parent workflow (Environment file)
echo "revision=$REVISION" >> $GITHUB_OUTPUT

# 2️⃣ Deploy new image
- name: Deploy new image
id: deploy
run: |
IMAGE_URI="${{ inputs.gcp_registry_host }}/${{ secrets.GCP_PROJECT_ID }}/${{ inputs.GCP_REPOSITORY }}/${{ inputs.IMAGE_NAME }}:${{ inputs.IMAGE_TAG }}"
echo "🚀 Deploying $IMAGE_URI"
gcloud run deploy ${{ inputs.SERVICE_NAME }} \
--image "$IMAGE_URI" \
--region ${{ inputs.REGION }} \
--platform managed \
--quiet
...
File renamed without changes.
98 changes: 98 additions & 0 deletions docs/32.cloudrun-rollback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
## [Cloud Run Deploy with Auto Rollback reusable workflow](https://github.com/clouddrove/github-shared-workflows/blob/master/.github/workflows/shared-cloudrun-rollback.yml)



### Overview

The Cloud Run Deploy with Auto Rollback workflow:

* Deploys a new Docker image to a Cloud Run service

* Captures the currently active revision before deployment

* Exposes the previous revision as an output for rollback

* Enables parent workflows to trigger rollback automatically on failure

This workflow helps ensure safer production deployments and faster recovery in case of issues.

### Workflow Location
```
.github/workflows/shared-cloudrun-rollback.yml
```
#### Example
```yaml

name: Deploy to Cloud Run

on:
workflow_dispatch:

jobs:
deploy-backend:
uses: clouddrove/github-shared-workflows/.github/workflows/shared-cloudrun-rollback.yml@master
with:
gcp_registry_host: # GCP Artifact Registry host
IMAGE_NAME: # Docker image name
IMAGE_TAG: # Image tag to deploy
SERVICE_NAME: # Cloud Run service name
REGION: # GCP region
GCP_REPOSITORY: # Artifact Registry repository
secrets:
GCP_PROJECT_ID: # GCP Project ID
GCP_SA_KEY: # GCP Service Account key (JSON)

rollback-all:
needs:
- deploy-backend
if: ${{ failure() }}
runs-on: ubuntu-latest

steps:
- name: Authenticate to GCP
uses: google-github-actions/auth@v2
with:
credentials_json: # GCP Service Account key (JSON)

- name: Setup gcloud
uses: google-github-actions/setup-gcloud@v2
with:
project_id: # GCP Project ID

- name: Rollback Cloud Run services (if needed)
run: |
echo "🚨 Rollback triggered because a deployment failed"

REGION= # GCP region
PROJECT= # GCP Project ID

rollback_if_needed () {
SERVICE_NAME=$1
PREV_REV=$2

if [ -z "$PREV_REV" ]; then
echo "ℹ️ $SERVICE_NAME was not deployed, skipping rollback"
return
fi

CURRENT_REV=$(gcloud run services describe "$SERVICE_NAME" \
--region "$REGION" \
--project "$PROJECT" \
--format="value(status.traffic[0].revisionName)")

if [ "$CURRENT_REV" = "$PREV_REV" ]; then
echo "✅ $SERVICE_NAME rollback not required — traffic already on previous revision ($PREV_REV)"
else
echo "🔄 Rolling back $SERVICE_NAME to revision: $PREV_REV"
gcloud run services update-traffic "$SERVICE_NAME" \
--to-revisions="$PREV_REV=100" \
--region "$REGION" \
--project "$PROJECT" \
&& echo "✅ $SERVICE_NAME rollback successful" \
|| echo "⚠️ $SERVICE_NAME rollback failed — traffic may already be correct"
fi
}

rollback_if_needed "# Cloud Run service name" "${{ needs.deploy-backend.outputs.revision }}"

```