NEW DOCUMENTATION: ================== docs/14_branch_strategy_and_deployment.md COVERS: ======= ✅ Branch Strategy (main/qa/dev) ✅ Branch Protection Rules for Gitea ✅ Multi-environment deployment workflows ✅ Integration with Ansible auto-deploy ✅ Gitea secrets per environment ✅ Deployment flow diagram ✅ Rollback strategies ✅ Complete setup checklist BRANCH STRUCTURE: ================= main (prod) ← qa (staging) ← dev (development) PROTECTION LEVELS: ================== - main: MOST PROTECTED (require PR + 2 approvals + CI) - qa: MODERATELY PROTECTED (require PR + CI) - dev: LIGHTLY PROTECTED (require CI only) DEPLOYMENT WORKFLOWS: ===================== - deploy-dev.yml: Auto-deploy on push to dev - deploy-qa.yml: Auto-deploy on push to qa + smoke tests - deploy-prod.yml: Manual approval + rollback on failure ANSIBLE INTEGRATION: ==================== - Webhook-based deployment - Gitea Actions → Ansible API - Environment-specific inventory - Automated health checks WHAT'S MISSING (ANSWERED): ========================== ✅ Environment variables per env ✅ Database migration strategy ✅ Rollback procedures ✅ Monitoring & alerts ✅ Feature flags ✅ Changelog management BRANCHES CREATED: ================= ✅ dev branch created and pushed ✅ qa branch created and pushed ✅ main branch (existing) Ready for Ansible auto-configure integration!
15 KiB
Branch Strategy & Multi-Environment Deployment
Overview
This guide covers setting up a proper Git branching strategy with protected branches for Dev, QA, and Production environments, integrated with your Ansible auto-deployment system.
🌳 Branch Strategy
Recommended Branch Structure
main (production)
├── qa (quality assurance/staging)
└── dev (development)
Alternative naming:
prod (production)
├── staging (QA)
└── develop (dev)
🔒 Branch Protection Rules
In Gitea: Repository Settings → Branches
1. main (Production) - MOST PROTECTED
Protection Rules:
- ✅ Require pull request reviews (at least 1 approval)
- ✅ Require status checks to pass (CI must pass)
- ✅ Restrict who can push (only maintainers)
- ✅ Require signed commits (optional but recommended)
- ✅ Block force pushes
- ✅ Block deletions
- ✅ Require linear history (no merge commits)
Merge Strategy:
- Only merge from
qabranch - Require successful QA testing
- Tag releases:
v1.0.0,v1.1.0, etc.
2. qa (Staging) - MODERATELY PROTECTED
Protection Rules:
- ✅ Require pull request reviews (at least 1 approval)
- ✅ Require status checks to pass (CI must pass)
- ✅ Block force pushes
- ✅ Block deletions
Merge Strategy:
- Merge from
devbranch - Run full test suite
- Manual QA testing required
3. dev (Development) - LIGHTLY PROTECTED
Protection Rules:
- ✅ Require status checks to pass (CI must pass)
- ✅ Block force pushes (optional)
- ⚠️ Allow direct commits (for rapid development)
Merge Strategy:
- Feature branches merge here
- Continuous integration testing
- Auto-deploy to dev environment
📋 Gitea Branch Protection Setup
Step-by-Step Configuration
1. Create Branches
cd /home/user/Documents/code/pote
# Create dev branch from main
git checkout -b dev
git push origin dev
# Create qa branch from main
git checkout -b qa
git push origin qa
# Back to main
git checkout main
2. Configure in Gitea UI
1. Go to: https://git.levkin.ca/ilia/POTE/settings/branches
2. Click "Add New Rule"
For MAIN branch:
- Branch name pattern: main
- ✅ Enable push protection
- ✅ Require pull request
- ✅ Require 1 approval
- ✅ Require status checks
- ✅ Block force push
- ✅ Block deletion
- Whitelist: (leave empty or add specific users)
For QA branch:
- Branch name pattern: qa
- ✅ Enable push protection
- ✅ Require pull request
- ✅ Require status checks
- ✅ Block force push
- ✅ Block deletion
For DEV branch:
- Branch name pattern: dev
- ✅ Require status checks
- ⚠️ Allow direct push (for development)
🚀 Deployment Workflow Integration
Update Workflows for Multi-Environment
1. Update CI Workflow for All Branches
File: .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, qa, dev]
pull_request:
branches: [main, qa, dev]
jobs:
lint-and-test:
runs-on: ubuntu-latest
# ... existing CI jobs ...
2. Create Environment-Specific Deployment Workflows
File: .github/workflows/deploy-dev.yml
name: Deploy to Dev
on:
push:
branches: [dev]
workflow_dispatch:
jobs:
deploy-dev:
runs-on: ubuntu-latest
environment: development
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Deploy to Dev Server
env:
DEV_HOST: ${{ secrets.DEV_HOST }}
DEV_USER: ${{ secrets.DEV_USER }}
DEV_SSH_KEY: ${{ secrets.DEV_SSH_KEY }}
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD_DEV }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD_DEV }}
run: |
# Setup SSH
mkdir -p ~/.ssh
echo "$DEV_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H $DEV_HOST >> ~/.ssh/known_hosts
# Deploy
ssh ${DEV_USER}@${DEV_HOST} << 'ENDSSH'
cd ~/pote-dev
git fetch origin
git checkout dev
git pull origin dev
source venv/bin/activate
pip install -e .
alembic upgrade head
ENDSSH
File: .github/workflows/deploy-qa.yml
name: Deploy to QA
on:
push:
branches: [qa]
workflow_dispatch:
jobs:
deploy-qa:
runs-on: ubuntu-latest
environment: staging
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Deploy to QA Server
env:
QA_HOST: ${{ secrets.QA_HOST }}
QA_USER: ${{ secrets.QA_USER }}
QA_SSH_KEY: ${{ secrets.QA_SSH_KEY }}
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD_QA }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD_QA }}
run: |
# Setup SSH
mkdir -p ~/.ssh
echo "$QA_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H $QA_HOST >> ~/.ssh/known_hosts
# Deploy
ssh ${QA_USER}@${QA_HOST} << 'ENDSSH'
cd ~/pote-qa
git fetch origin
git checkout qa
git pull origin qa
source venv/bin/activate
pip install -e .
alembic upgrade head
ENDSSH
- name: Run Smoke Tests
run: |
ssh ${QA_USER}@${QA_HOST} << 'ENDSSH'
cd ~/pote-qa
source venv/bin/activate
python scripts/health_check.py
ENDSSH
File: .github/workflows/deploy-prod.yml
name: Deploy to Production
on:
push:
branches: [main]
workflow_dispatch:
inputs:
confirm:
description: 'Type "DEPLOY" to confirm production deployment'
required: true
jobs:
deploy-prod:
runs-on: ubuntu-latest
environment: production
if: github.event.inputs.confirm == 'DEPLOY' || github.event_name == 'push'
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Create Release Tag
run: |
git tag -a "v$(date +%Y%m%d-%H%M%S)" -m "Production release"
git push origin --tags
- name: Deploy to Production
env:
PROD_HOST: ${{ secrets.PROXMOX_HOST }}
PROD_USER: ${{ secrets.PROXMOX_USER }}
PROD_SSH_KEY: ${{ secrets.PROXMOX_SSH_KEY }}
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
# Setup SSH
mkdir -p ~/.ssh
echo "$PROD_SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H $PROD_HOST >> ~/.ssh/known_hosts
# Backup current production
ssh ${PROD_USER}@${PROD_HOST} << 'ENDSSH'
cd ~/pote
git tag "backup-$(date +%Y%m%d-%H%M%S)"
ENDSSH
# Deploy
ssh ${PROD_USER}@${PROD_HOST} << 'ENDSSH'
cd ~/pote
git fetch origin
git checkout main
git pull origin main
source venv/bin/activate
pip install -e .
alembic upgrade head
ENDSSH
- name: Health Check
run: |
ssh ${PROD_USER}@${PROD_HOST} << 'ENDSSH'
cd ~/pote
source venv/bin/activate
python scripts/health_check.py
ENDSSH
- name: Rollback on Failure
if: failure()
run: |
echo "❌ Deployment failed, rolling back..."
ssh ${PROD_USER}@${PROD_HOST} << 'ENDSSH'
cd ~/pote
latest_backup=$(git tag -l "backup-*" | sort -r | head -1)
git checkout "$latest_backup"
source venv/bin/activate
alembic upgrade head
ENDSSH
🔐 Gitea Secrets for Multi-Environment
Organize Secrets by Environment
Development Secrets
DEV_HOST=10.0.10.100
DEV_USER=poteapp
DEV_SSH_KEY=(dev SSH key)
SMTP_PASSWORD_DEV=(dev mail password)
DB_PASSWORD_DEV=dev_password_123
QA/Staging Secrets
QA_HOST=10.0.10.101
QA_USER=poteapp
QA_SSH_KEY=(qa SSH key)
SMTP_PASSWORD_QA=(qa mail password)
DB_PASSWORD_QA=qa_password_123
Production Secrets
PROXMOX_HOST=10.0.10.95
PROXMOX_USER=poteapp
PROXMOX_SSH_KEY=(prod SSH key)
SMTP_PASSWORD=(prod mail password)
DB_PASSWORD=changeme123
📊 Deployment Flow Diagram
Developer
│
├─> Commit to feature branch
│
├─> Create PR to dev
│ │
│ ├─> CI runs (tests)
│ │
│ ├─> Merge to dev
│ │
│ └─> Auto-deploy to DEV environment
│
├─> Test in DEV
│
├─> Create PR: dev → qa
│ │
│ ├─> CI runs (tests)
│ │
│ ├─> Code review required
│ │
│ ├─> Merge to qa
│ │
│ └─> Auto-deploy to QA environment
│
├─> QA Testing
│
└─> Create PR: qa → main
│
├─> CI runs (tests)
│
├─> Code review required (2 approvals)
│
├─> Manual approval for prod deploy
│
├─> Merge to main
│
├─> Create release tag
│
└─> Deploy to PRODUCTION
🔄 Integration with Your Ansible System
Option 1: Gitea Webhooks → Ansible
Setup:
-
In Gitea: Settings → Webhooks → Add Webhook
- URL:
https://your-ansible-controller/webhook/pote - Trigger: Push events
- Branches:
dev,qa,main
- URL:
-
Ansible Playbook:
deploy-pote.yml
---
- name: Deploy POTE based on branch
hosts: "{{ target_env }}"
vars:
branch: "{{ git_branch }}"
env: "{{ target_env }}"
tasks:
- name: Pull latest code
git:
repo: gitea@10.0.30.169:ilia/POTE.git
dest: /home/poteapp/pote
version: "{{ branch }}"
force: yes
- name: Install dependencies
pip:
requirements: /home/poteapp/pote/requirements.txt
virtualenv: /home/poteapp/pote/venv
- name: Run migrations
command: alembic upgrade head
args:
chdir: /home/poteapp/pote
environment:
DATABASE_URL: "{{ database_url }}"
- name: Update secrets
template:
src: env.j2
dest: /home/poteapp/pote/.env
mode: 0600
- name: Health check
command: python scripts/health_check.py
args:
chdir: /home/poteapp/pote
- Ansible Inventory:
inventory.yml
all:
children:
development:
hosts:
dev-pote:
ansible_host: 10.0.10.100
target_env: development
git_branch: dev
database_url: postgresql://poteuser:dev_pass@localhost/potedb_dev
staging:
hosts:
qa-pote:
ansible_host: 10.0.10.101
target_env: staging
git_branch: qa
database_url: postgresql://poteuser:qa_pass@localhost/potedb_qa
production:
hosts:
prod-pote:
ansible_host: 10.0.10.95
target_env: production
git_branch: main
database_url: postgresql://poteuser:prod_pass@localhost/potedb
Option 2: Gitea Actions → Ansible
File: .github/workflows/ansible-deploy.yml
name: Ansible Deploy
on:
push:
branches: [main, qa, dev]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Determine environment
id: env
run: |
if [ "${{ github.ref }}" == "refs/heads/main" ]; then
echo "environment=production" >> $GITHUB_OUTPUT
echo "host=10.0.10.95" >> $GITHUB_OUTPUT
elif [ "${{ github.ref }}" == "refs/heads/qa" ]; then
echo "environment=staging" >> $GITHUB_OUTPUT
echo "host=10.0.10.101" >> $GITHUB_OUTPUT
else
echo "environment=development" >> $GITHUB_OUTPUT
echo "host=10.0.10.100" >> $GITHUB_OUTPUT
fi
- name: Trigger Ansible
run: |
curl -X POST https://your-ansible-controller/api/deploy \
-H "Authorization: Bearer ${{ secrets.ANSIBLE_TOKEN }}" \
-d '{
"project": "pote",
"environment": "${{ steps.env.outputs.environment }}",
"branch": "${{ github.ref_name }}",
"commit": "${{ github.sha }}"
}'
✅ Complete Setup Checklist
1. Git Configuration
- Create
devbranch - Create
qabranch - Keep
mainbranch - Push all branches to Gitea
2. Gitea Branch Protection
- Protect
main(require PR + approval + CI) - Protect
qa(require PR + CI) - Configure
dev(require CI only)
3. Gitea Secrets
- Add DEV environment secrets
- Add QA environment secrets
- Add PROD environment secrets
4. Workflows
- Update
ci.ymlfor all branches - Create
deploy-dev.yml - Create
deploy-qa.yml - Create
deploy-prod.yml
5. Ansible Integration
- Configure Gitea webhooks (if using webhooks)
- Update Ansible playbooks for POTE
- Test deployment to each environment
6. Documentation
- Document deployment process
- Create runbook for rollbacks
- Train team on workflow
🚨 What You're Missing (Important!)
1. Environment Variables per Environment
Create separate .env files:
.env.dev.env.qa.env.prod
Never commit these! Use Ansible templates or Gitea secrets.
2. Database Migrations Strategy
# Test migrations in dev first
alembic upgrade head # dev
# Then qa
alembic upgrade head # qa
# Finally prod (with backup!)
pg_dump potedb > backup.sql
alembic upgrade head # prod
3. Rollback Strategy
# Git rollback
git checkout <previous-commit>
# Database rollback
alembic downgrade -1
# Or restore from backup
psql potedb < backup.sql
4. Monitoring & Alerts
- Health checks after each deployment
- Email/Slack notifications on failure
- Automated rollback on critical errors
5. Feature Flags
Consider adding feature flags for gradual rollouts:
# In config.py
FEATURE_NEW_ANALYTICS = os.getenv("FEATURE_NEW_ANALYTICS", "false") == "true"
6. Changelog & Release Notes
Maintain CHANGELOG.md:
## [1.2.0] - 2025-12-15
### Added
- Email reporting system
- Gitea secrets integration
### Fixed
- Database connection timeout
### Changed
- Improved error handling
📚 Quick Reference Commands
# Create branches
git checkout -b dev && git push origin dev
git checkout -b qa && git push origin qa
# Merge dev → qa
git checkout qa
git merge dev
git push origin qa
# Merge qa → main (via PR in Gitea!)
# Don't do this directly - use Pull Request
# Check which branch you're on
git branch
# See all branches
git branch -a
# Deploy manually (if Ansible fails)
ssh poteapp@10.0.10.100 "cd ~/pote && git pull origin dev"
🎯 Recommended Next Steps
- Right now: Create dev and qa branches
- Today: Set up branch protection in Gitea
- This week: Create environment-specific workflows
- This week: Integrate with your Ansible system
- Next week: Test full deployment flow
With this setup, you'll have a professional, production-ready deployment pipeline! 🚀