# Codeänderungen pushen und deployen ## Übersicht Dieses Dokument erklärt, wie Codeänderungen gepusht werden und automatisch in Production deployed werden. **Quick Start:** ```bash git add . git commit -m "feat: Add new feature" git push origin main ``` → Automatisches Deployment startet (~8-15 Minuten) **📖 Verwandte Dokumentation:** - **[Application Stack Deployment](../reference/application-stack.md)** - Wie das Deployment genau funktioniert - **[CI/CD Status](../status/ci-cd-status.md)** - Aktueller Status der Pipeline --- ## Normaler Workflow: Codeänderungen deployen ### Schritt 1: Code lokal ändern ```bash # Änderungen in deinem lokalen Repository machen # z.B. Datei bearbeiten: src/App/Controller/HomeController.php # Änderungen anzeigen git status # Änderungen anschauen git diff ``` ### Schritt 2: Änderungen committen ```bash # Änderungen zum Staging hinzufügen git add . # Oder nur spezifische Dateien git add src/App/Controller/HomeController.php # Commit erstellen git commit -m "feat: Add new feature to home controller" ``` **Commit-Message Konventionen:** - `feat:` - Neue Feature - `fix:` - Bug-Fix - `refactor:` - Code-Refactoring - `docs:` - Dokumentation - `test:` - Tests - `chore:` - Wartungsaufgaben ### Schritt 3: Code zu Gitea pushen ```bash # Zu main branch pushen (triggert automatisches Deployment) git push origin main # Oder zu anderem Branch pushen (kein Auto-Deploy) git push origin feature/new-feature ``` ### Schritt 4: Automatisches Deployment **Was passiert automatisch:** 1. **Git Push** → Gitea erhält den Push 2. **Workflow wird getriggert** (bei Push zu `main` Branch) 3. **CI/CD Pipeline startet:** - Tests laufen - Docker Image wird gebaut - Image wird zur Registry gepusht - Ansible Deployment wird ausgeführt - Application Stack wird aktualisiert **Zeitdauer:** ~8-15 Minuten für komplettes Deployment --- ## Deployment-Trigger ### Automatisches Deployment (bei Push zu `main`) **Workflow:** `.gitea/workflows/production-deploy.yml` ```yaml on: push: branches: - main paths-ignore: - 'docs/**' - '**.md' - '.github/**' ``` **Bedeutung:** - ✅ Push zu `main` Branch → Deployment startet automatisch - ❌ Push zu anderen Branches → Kein Deployment - ❌ Push nur von Markdown-Dateien → Kein Deployment (wegen `paths-ignore`) **Beispiel:** ```bash # Triggert Deployment git push origin main # Triggert KEIN Deployment (nur Markdown) git commit -m "docs: Update README" --only README.md git push origin又问 # Triggert KEIN Deployment (anderer Branch) git checkout -b feature/new-feature git push origin feature/new-feature ``` ### Manuelles Deployment (Workflow-Dispatch) **Workflow kann manuell gestartet werden:** 1. Gehe zu: `https://git.michaelschiemer.de/michael/michaelschiemer/actions` 2. Wähle: "Production Deployment Pipeline" 3. Klicke: "Run workflow" 4. Wähle Branch (z.B. `main` oder anderer Branch) 5. Optionale Einstellungen: - `skip_tests`: `true` (nur in Notfällen!) 6. Klicke: "Run workflow" **Verwendung:** - Deployment von anderem Branch (z.B. `develop`, `staging`) - Deployment ohne Code-Änderung (z.B. nach Config-Änderung) - Notfall-Deployment mit `skip_tests: true` --- ## Workflow-Details ### Was passiert bei jedem Push zu `main`? #### Job 1: Tests (ca. 2-5 Minuten) ```yaml - PHP 8.3 Setup - Composer Dependencies installieren - Pest Tests ausführen - PHPStan Code Quality Check - Code Style Check (composer cs) ``` **Bei Fehler:** Pipeline stoppt, kein Deployment #### Job 2: Build (ca. 3-5 Minuten) ```yaml - Docker Buildx Setup - Image Metadata generieren (Tag: -) - Docker Image Build (Dockerfile.production) - Image mit Tags pushen: - registry.michaelschiemer.de/framework:latest - registry.michaelschiemer.de/framework: - registry.michaelschiemer.de/framework:git- ``` #### Job 3: Deploy (ca. 2-4 Minuten) ```yaml - SSH Setup (mit Secret) - Ansible Installation - Ansible Playbook ausführen: - Image Pull - docker-compose.yml Update - Stack Neustart - Health-Check (10x versuche) - Rollback bei Fehler ``` --- ## Branching-Strategie ### Empfohlener Workflow ``` main (Production) ↓ develop (Entwicklung/Testing) ↓ feature/* (Feature Branches) ``` ### Workflow-Beispiele #### 1. Feature entwickeln ```bash # Feature Branch erstellen git checkout -b feature/user-authentication # Änderungen machen # ... Code schreiben ... # Committen git add . git commit -m "feat: Add user authentication" # Zu Gitea pushen (kein Auto-Deploy) git push origin feature/user-authentication # Pull Request erstellen in Gitea # → Code Review # → Merge zu develop (oder main) ``` #### 2. Direkt zu Production deployen ```bash # Änderungen lokal git checkout main # ... Änderungen machen ... git add . git commit -m "fix: Critical bug fix" # Pushen → Triggert automatisches Deployment git push origin main # Pipeline läuft automatisch: # ✅ Tests # ✅ Build # ✅ Deploy ``` #### 3. Hotfix (Notfall) ```bash # Hotfix Branch von main git checkout -b hotfix/critical-security-fix main # Fix implementieren # ... Code schreiben ... git add . git commit -m "fix: Critical security vulnerability" # Direkt zu main mergen git checkout main git merge hotfix/critical-security-fix Ker # Pushen → Auto-Deploy git push origin main # Optional: Manuelles Deployment mit skip_tests # (nur wenn Tests lokal bereits erfolgreich) ``` --- ## Deployment-Status prüfen ### 1. Pipeline-Status in Gitea ``` https://git.michaelschiemer.de/michael/michaelschiemer/actions ``` **Status-Anzeigen:** - 🟢 Grüner Haken = Erfolgreich - 🔴 Roter Haken = Fehlgeschlagen - 🟡 Gelber Kreis = Läuft gerade ### 2. Logs ansehen 1. Gehe zu Actions 2. Klicke auf den Workflow-Run 3. Klicke auf Job (z.B. "Deploy to Production Server") 4. Klicke auf Step (z.B. "Deploy via Ansible") 5. Logs ansehen ### 3. Application-Status prüfen ```bash # SSH zum Production-Server ssh deploy@94.16.110.151 # Container-Status prüfen cd ~/deployment/stacks/production docker compose ps # Logs ansehen docker compose logs -f app # Health-Check manuell curl https://michaelschiemer.de/health ``` --- ## Deployment verhindern ### Temporäres Deployment verhindern **Option 1: Push zu anderem Branch** ```bash # Entwickle auf Feature-Branch git checkout -b feature/my-feature git push origin feature/my-feature # → Kein Auto-Deploy ``` **Option CT 2: [skip ci] in Commit-Message** ```bash # Workflow wird übersprungen git commit -m "docs: Update documentation [skip ci]" git push origin main ``` **Hinweis:** `[skip ci]` wird aktuell **nicht** unterstützt, da kein entsprechender Filter im Workflow ist. ### Deployment-Trigger deaktivieren **Temporär (Workflow anpassen):** ```yaml # In .gitea/workflows/production-deploy.yml on: push: branches: - main # workflow_dispatch: # Kommentiere aus für temporäres Deaktivieren ``` **Besser:** Nutze Feature-Branches für Entwicklung ohne Auto-Deploy. --- ## Häufige Szenarien ### Szenario 1: Kleine Bug-Fix ```bash # 1. Bug-Fix lokal implementieren git checkout main # ... Fix implementieren ... git add . git commit -m "fix: Resolve login issue" # 2. Pushen → Auto-Deploy git push origin main # 3. Pipeline beobachten # → Tests ✅ # → Build ✅ # → Deploy ✅ # 4. Verifizieren curl https://michaels chasing.de/health ``` ### Szenario 2: Große Feature-Entwicklung ```bash # 1. Feature-Branch erstellen git checkout -b feature/new-dashboard # 2. Feature entwickeln # ... viele Commits ... # 3. Regelmäßig pushen (kein Auto-Deploy) git push origin feature/new-dashboard # 4. Pull Request erstellen in Gitea # → Code Review # → Diskussion # 5. Merge zu main (triggert Auto-Deploy) # → Via Gitea UI: "Merge Pull Request" # → Oder lokal: git checkout main git merge feature/new-dashboard git push origin main ``` ### Szenario 3: Config-Änderung ohne Code-Änderung ```bash # Beispiel: .env Variablen ändern # (wird über Ansible Template generiert, daher direkt auf Server ändern) # Oder: docker-compose.yml anpassen # Änderungen machen git add . git commit -m "chore: Update docker-compose configuration" git push origin main # → Pipeline läuft # → Build: Keine Code-Änderung, aber Image wird neu getaggt # → Deploy: docker-compose.yml wird aktualisiert ``` ### Szenario 4: Notfall-Rollback ```bash # Option 1: Rollback via Ansible Playbook cd deployment/ansible ansible-playbook -i inventory/production.yml \ playbooks/rollback.yml \ -e "rollback_timestamp=2025-10-31T01-20-15Z" # Option 2: Alten Commit pushen git log --oneline # Finde letzten funktionierenden Commit git checkout git checkout -b rollback/previous-version git push origin rollback/previous-version # Manuell zu main mergen oder direkt: git checkout main git reset --hard git push origin main --force # ⚠️ Vorsicht! # → Triggert Auto-Deploy mit altem Code ``` --- ## Best Practices ### 1. Commits - ✅ Klare, beschreibende Commit-Messages entweder - ✅ Atomic Commits (ein Feature = ein Commit) - ✅ Regelmäßig pushen (nicht alles auf einmal) ### 2. Testing - ✅ Tests lokal ausführen vor Push: ```bash composer cs # Code Style make phpstan # Static Analysis ./vendor/bin/pest # Tests ``` ### 3. Deployment - ✅ **Niemals** direkt zu `main` pushen ohne lokale Tests - ✅ Feature-Branches für größere Änderungen - ✅ Pull Requests für Code Review - ✅ Pipeline-Status beobachten nach Push ### 4. Rollback-Plan - ✅ Immer Backup vor größeren Änderungen - ✅ Rollback-Playbook bereit halten - ✅ Deployment-Metadaten dokumentieren --- ## Troubleshooting ### Pipeline schlägt fehl **Problem:** Tests fehlgeschlagen ```bash # Tests lokal ausführen ./vendor/bin/pest # Fehler beheben # ... Code anpassen ... git add . git commit -m "fix: Fix failing tests" git push origin main ``` **Problem:** Build fehlgeschlagen ```bash # Docker Build lokal testen docker build -f Dockerfile.production -t test-image . # Fehler beheben # ... Dockerfile anpassen ... git add . git commit -m "fix: Fix Docker build" git push origin main ``` **Problem:** Deployment fehlgeschlagen ```bash # SSH zum Server ssh deploy@94.16.110.151 # Logs prüfen cd ~/deployment/stacks/production docker compose logs app # Manuell rollback cd ~/deployment/ansible ansible-playbook -i inventory/production.yml playbooks/rollback.yml ``` ### Deployment läuft zu lange **Pipeline hängt:** - Prüfe Runner-Status: `docker compose ps` in `deployment/gitea-runner` - Prüfe Runner-Logs: `docker compose logs gitea-runner` - Prüfe Workflow-Logs in Gitea UI **Deployment hängt:** - Prüfe Server-Status: `ssh deploy@94.16.110.151 "docker ps"` - Prüfe Container-Logs: `docker compose logs` - Prüfe Disk-Space: `df -h` --- ## Zusammenfassung ### Normaler Workflow 1. **Code ändern** lokal 2. **Committen** mit klarer Message 3. **Push zu `main`** → Auto-Deploy startet 4. **Pipeline beobachten** in Gitea Actions 5. **Verifizieren** auf Production ### Wichtige Commands ```bash # Änderungen pushen (triggert Auto-Deploy) git push origin main # Feature entwickeln (kein Auto-Deploy) git checkout -b feature/my-feature git push origin feature/my-feature # Pipeline-Status prüfen # → https://git.michaelschiemer.de/michael/michaelschiemer/actions # Application-Status prüfen ssh deploy@94.16.110.151 "cd ~/deployment/stacks/production && docker compose ps" ``` ### Deployment-Zeit - **Gesamt:** ~8-15 Minuten - **Tests:** ~2-5 Minuten - **Build:** ~3-5 Minuten - **Deploy:** ~2-4 Minuten - **Health-Check:** ~1 Minute --- **Ready to deploy!** 🚀