Overview
This document describes the Continuous Integration and Continuous Deployment (CI/CD) pipeline for the HandaUncle Backend application. The pipeline automates building, testing, security scanning, and deploying the application across multiple environments.The pipeline uses GitHub Actions for automation and Google Cloud Run for deployments with Workload Identity Federation for secure, keyless authentication.
Architecture
Environments
Development
Trigger: Manual (Claim β Deploy β Release)Project: Dev GCP ProjectPurpose: Feature development and testing
Staging
Branch:
developProject: Staging GCP ProjectPurpose: Pre-production testing and QAProduction
Branch:
mainProject: Production GCP ProjectPurpose: Live production environmentBranch Strategy
Git Flow
Branch Rules
feature/* - Development branches
feature/* - Development branches
- Created from
develop - Manual deployment to Dev environment (Claim β Deploy β Release)
- Must pass CI checks before merging
- Used for individual feature development
develop - Integration branch
develop - Integration branch
- Receives merges from feature branches via PR
- Auto-deploys to Staging environment on push
- Protected: Requires PR with passing checks
- Used for integration testing
main - Production branch
main - Production branch
- Only accepts PRs from
develop - Auto-deploys to Production on push
- Protected: Requires PR from develop only
- Never push directly to main
Dev Environment Lock System
The Dev environment uses a claim/release system to prevent multiple developers from overwriting each otherβs deployments during testing.
How It Works
Workflow Steps
Claim the Environment
Run π Claim Dev Environment workflow
- Blocks other developers from deploying
- Shows who has the environment claimed
Deploy Your Branch
Run π Deploy to Dev workflow
- Enter your branch name (e.g.,
feature/my-feature) - Only works if you own the claim
Test Your Changes
Test as long as needed
- Environment stays locked to you
- Other developers see βclaimed by @youβ
Emergency Release
If a developer forgets to release and is unavailable:- Run π Release Dev Environment
- Check the Force release checkbox
- This will release even if claimed by someone else
Workflow Files
CI Pipeline (ci.yml)
- Overview
- Jobs
Triggers:
- Push to:
main,develop,feature/** - Pull requests to:
main,develop
- Vulnerability report (JSON) - 30-day retention
Dev Environment Workflows
| Workflow | File | Purpose |
|---|---|---|
| π Claim Dev Environment | claim-dev.yml | Claim exclusive access to dev |
| π Deploy to Dev | deploy-dev.yml | Deploy a branch to dev (requires claim) |
| π Release Dev Environment | release-dev.yml | Release dev for others to use |
Deploy to Staging (deploy-staging.yml)
Concurrency: Only one staging deployment runs at a time (others queue)
PR Checks (pr-checks.yml)
| Job | Description |
|---|---|
| Branch Protection | Blocks direct PRs to main (must come from develop) |
| PR Summary | Displays PR information and merge path |
GCP Infrastructure
Projects
| Environment | Purpose |
|---|---|
| Dev | Feature development and testing |
| Staging | Pre-production QA |
| Production | Live environment |
Enabled APIs
Cloud Run Admin API
Container deployment and management
Artifact Registry API
Docker image storage
Secret Manager API
Secure secrets storage
IAM API
Identity and access management
Workload Identity Federation
Enables keyless authentication from GitHub Actions to GCP - no service account keys needed!
- GitHub Actions generates an OIDC token
- GCP exchanges it for a short-lived access token
- No long-lived credentials stored anywhere
Service Accounts
| Purpose | Description |
|---|---|
| GitHub Actions SA | Used by CI/CD to deploy |
| Cloud Run SA | Runtime identity for the application |
- Cloud Run Admin
- Artifact Registry Writer
- Service Account User
- Secret Manager Accessor
Secrets Management
GitHub Repository Secrets
| Category | Description |
|---|---|
| Workload Identity | Provider URLs for each environment |
| Service Accounts | Email addresses for GCP authentication |
GitHub Repository Variables
| Variable | Description |
|---|---|
DEV_CLAIMED_BY | Tracks who has claimed the dev environment |
GCP Secret Manager
Core Configuration
Core Configuration
Server port, backend secrets, environment settings
Database
Database
Database connection strings, Redis configuration
Authentication
Authentication
OAuth provider credentials, JWT secrets
AI Services
AI Services
API keys for various AI providers (LLMs, embeddings)
Vector DB & Memory
Vector DB & Memory
Vector database and memory service credentials
Observability
Observability
Monitoring and analytics service credentials
File Processing
File Processing
Document processing and storage credentials
Web Search
Web Search
Search API credentials
Payments
Payments
Payment gateway credentials
Feature Flags
Feature Flags
Feature configuration values
Development Workflow
Creating a New Feature
Deploying to Dev
Claim the environment
Go to Actions β π Claim Dev Environment β Run workflow
You now have exclusive access to dev!
Deploy your branch
Go to Actions β π Deploy to Dev β Run workflow
- Enter your branch name (e.g.,
feature/my-new-feature)Your code is deploying to Dev!
Promoting to Staging
Promoting to Production
Monitoring & Debugging
Viewing Workflow Runs
- Go to: GitHub Actions
- Select the workflow (CI Pipeline, Deploy Dev, etc.)
- Click on a specific run to see logs
Viewing Deployment Logs
Getting Deployment URLs
Downloading Security Reports
- Go to the CI Pipeline workflow run
- Scroll to βArtifactsβ section
- Download the vulnerability report
Troubleshooting
Dev Environment Claimed by Someone Else
Dev Environment Claimed by Someone Else
Error:
Dev environment is claimed by @usernameSolution:- Contact the developer and ask them to release
- If unavailable, use Force release option in the Release workflow
Deploy Blocked - Not Claimed
Deploy Blocked - Not Claimed
Error:
Dev environment is not claimedSolution:
Run π Claim Dev Environment workflow first, then deployWorkload Identity Authentication Failed
Workload Identity Authentication Failed
Error:
Unable to get federated tokenSolution:
Verify the Workload Identity pool and provider exist in GCPSecret Access Denied
Secret Access Denied
Error:
Permission denied on secretSolution:
Ensure the service account has Secret Manager Accessor roleCloud Run Deployment Failed
Cloud Run Deployment Failed
Error:
Could not find service accountSolution:
Verify the Cloud Run service account exists in the projectDocker Build Cache Miss
Docker Build Cache Miss
Symptom: Slow builds despite cachingSolution: GitHub Actions cache has a 10GB limit. Old caches are automatically evicted. This is normal behavior.
Security Considerations
Secrets Protection
- All secrets stored in GCP Secret Manager (encrypted at rest)
- Workload Identity Federation (no long-lived keys)
- Minimal IAM permissions (principle of least privilege)
- Security scanning on every build
Branch Protection
mainonly accepts PRs fromdevelop- CI checks must pass before merge
- Code review recommended
Container Security
- Multi-stage Docker builds (minimal attack surface)
- Non-root user in container
- Vulnerability scanning
- Secret scanning to prevent credential leaks
Network Security
- HTTPS only endpoints
- Cloud Run automatic TLS
- No exposed ports except 443
Maintenance
Updating Secrets
Adding New Secrets
Cleaning Up Old Images
Cost Optimization
| Service | Pricing Model |
|---|---|
| Cloud Run | Pay-per-use, scales to zero |
| Artifact Registry | Standard storage pricing |
| Secret Manager | Per-access operation pricing |
| GitHub Actions | Free for public repos, usage-based for private |