From 01597f608f9805b29403c2864ef5677a2d2a5d59 Mon Sep 17 00:00:00 2001 From: ilia Date: Wed, 24 Dec 2025 21:46:24 -0500 Subject: [PATCH] Add comprehensive branch strategy and multi-environment deployment guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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! --- docs/14_branch_strategy_and_deployment.md | 681 ++++++++++++++++++++++ 1 file changed, 681 insertions(+) create mode 100644 docs/14_branch_strategy_and_deployment.md diff --git a/docs/14_branch_strategy_and_deployment.md b/docs/14_branch_strategy_and_deployment.md new file mode 100644 index 0000000..4b2a11d --- /dev/null +++ b/docs/14_branch_strategy_and_deployment.md @@ -0,0 +1,681 @@ +# 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 `qa` branch +- 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 `dev` branch +- 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 + +```bash +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` + +```yaml +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` + +```yaml +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` + +```yaml +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` + +```yaml +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:** + +1. **In Gitea:** Settings → Webhooks → Add Webhook + - URL: `https://your-ansible-controller/webhook/pote` + - Trigger: Push events + - Branches: `dev`, `qa`, `main` + +2. **Ansible Playbook:** `deploy-pote.yml` + +```yaml +--- +- 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 +``` + +3. **Ansible Inventory:** `inventory.yml` + +```yaml +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` + +```yaml +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 `dev` branch +- [ ] Create `qa` branch +- [ ] Keep `main` branch +- [ ] 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.yml` for 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** + +```bash +# 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** + +```bash +# Git rollback +git checkout + +# 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: + +```python +# In config.py +FEATURE_NEW_ANALYTICS = os.getenv("FEATURE_NEW_ANALYTICS", "false") == "true" +``` + +### 6. **Changelog & Release Notes** + +Maintain `CHANGELOG.md`: + +```markdown +## [1.2.0] - 2025-12-15 +### Added +- Email reporting system +- Gitea secrets integration + +### Fixed +- Database connection timeout + +### Changed +- Improved error handling +``` + +--- + +## 📚 Quick Reference Commands + +```bash +# 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 + +1. **Right now:** Create dev and qa branches +2. **Today:** Set up branch protection in Gitea +3. **This week:** Create environment-specific workflows +4. **This week:** Integrate with your Ansible system +5. **Next week:** Test full deployment flow + +--- + +**With this setup, you'll have a professional, production-ready deployment pipeline!** 🚀 +