Skip to content
Merged
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
68 changes: 68 additions & 0 deletions .github/actions/cloudrun-rollback
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
########################################################################################
# Rollback Workflow (Cloud Run)
#---------------------------------------------------------------------------------------
# Purpose:
# This job is automatically triggered when the `deploy-backend` job fails.
# It safely rolls back the specified Google Cloud Run service to the
# previously deployed revision by shifting 100% traffic back to it.
#
# Use case:
# - Prevents broken deployments from impacting production
# - Ensures high availability by restoring last known good revision
#
# Trigger condition:
# - Runs only when a dependent job fails (`if: failure()`)
########################################################################################

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 }}"
76 changes: 76 additions & 0 deletions .github/workflows/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
...
60 changes: 60 additions & 0 deletions docs/cloudrun-rollback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## [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 reusable workflow is designed to make Cloud Run deployments safer and more reliable.

It deploys a new Docker image to a Cloud Run service while preserving the currently active revision.
If the deployment fails, parent workflows can automatically roll back traffic to the last stable revision.

This approach helps reduce production risk and ensures quick recovery from failed deployments.

### Features

* Deploys a Docker image to Google Cloud Run

* Captures the currently active revision before deployment

* Exposes the previous revision as a workflow output

* Enables automatic rollback on deployment failure

* Uses secure GCP authentication via Service Account

* Designed as a reusable workflow for multiple services

### Usage

### Workflow Location
```
.github/workflows/cloudrun-rollback.yml
```
#### Example
```yaml
name: Deploy to Cloud Run

on:
workflow_dispatch:

jobs:
deploy-backend:
uses: clouddrove/github-shared-workflows/.github/workflows/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)
```

#### Reference workflow:
The rollback logic used by this workflow is implemented in
```
actions/cloudrun-rollback
```
28 changes: 28 additions & 0 deletions docs/tfdrift.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## [terraform drifts Workflow](https://github.com/clouddrove/github-shared-workflows/blob/master/.github/workflows/tfdrifts.yml)

This workflow automates Terraform configuration drift detection by running terraform init/plan against your live infrastructure and signaling when resources have changed outside of code. The reusable workflow is stored at `.github/workflows/tfdrifts.yml` in the shared repo.

**Key capabilities**:
- Detect drift via terraform plan.
- Works with AWS, Azure, or GCP (select with provider).

#### Example
```yaml
name: TF-Drift
on:
push:
branches: [ master ]
pull_request:
workflow_dispatch:
jobs:
tf-lint:
uses: clouddrove/github-shared-workflows/.github/workflows/tfdrift.yml@master
with:
working_directory: #'./_example/complete/'
provider: #aws
aws_region: # AWS region
secrets:
AWS_ACCESS_KEY_ID: # Specify AWS Access key ID
AWS_SECRET_ACCESS_KEY: # Specify AWS Secret Access key ID
AWS_SESSION_TOKEN: # Specify Session ID
```
Loading