# ADR-024 : Stratégie CI/CD avec Path Filters pour Monorepo **Statut** : Accepté (non implémenté) **Date** : 2026-02-01 ## Contexte RoadWave est organisé en monorepo contenant backend Go, mobile Flutter, documentation et features BDD ([ADR-016](016-organisation-monorepo.md)). Sans optimisation, chaque commit déclencherait **tous** les builds (backend + mobile + docs), même si seul un composant a changé. **Problématique** : - ❌ Temps de CI/CD inutilement longs (rebuild complet ~15 min) - ❌ Gaspillage de ressources GitHub Actions - ❌ Ralentissement du feedback développeur - ❌ Coûts CI/CD élevés pour changements isolés **Exemple** : Modification d'un fichier markdown dans `/docs` déclenche les tests backend (5 min) + tests mobile (8 min) + build (2 min) alors que seule la validation docs (~30s) est nécessaire. ## Décision **Workflows GitHub Actions séparés** avec **path filters** pour rebuild sélectif basé sur les fichiers modifiés. ## Alternatives considérées | Option | Optimisation | Complexité | Maintenance | Coût CI | |--------|--------------|------------|-------------|---------| | **Workflows séparés + path filters** | Excellente (~70%) | Faible | Simple | Minimal | | Workflow monolithique | Nulle | Très faible | Simple | Élevé | | Turborepo/Nx orchestration | Bonne (~50%) | Élevée | Complexe | Moyen | | Multirepo (repos séparés) | Excellente | Élevée | Complexe | Variable | ## Architecture ### Structure Workflows ``` .github/workflows/ ├── backend.yml # Backend Go (tests, lint, build) ├── mobile.yml # Mobile Flutter (tests, lint, build) └── shared.yml # Docs + code partagé (validation, génération) ``` ### Configuration Path Filters #### Workflow Backend (`backend.yml`) ```yaml name: Backend CI on: push: branches: [main, develop] paths: - 'backend/**' # Code Go modifié - 'features/api/**' # Tests API modifiés - 'features/e2e/**' # Tests E2E (impliquent backend) - '.github/workflows/backend.yml' pull_request: branches: [main, develop] paths: - 'backend/**' - 'features/api/**' - 'features/e2e/**' jobs: test-unit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.21' - run: cd backend && go test ./... test-integration: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.21' - run: cd backend && make test-integration test-bdd: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.21' - run: | go install github.com/cucumber/godog/cmd/godog@latest godog run features/api/ features/e2e/ lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: golangci/golangci-lint-action@v4 build: runs-on: ubuntu-latest needs: [test-unit, test-integration, test-bdd, lint] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 with: go-version: '1.21' - run: cd backend && make build ``` **Déclenché par** : - Modifications dans `/backend` (code Go, migrations, config) - Nouvelles features API dans `/features/api` - Tests end-to-end dans `/features/e2e` (backend impliqué) --- #### Workflow Mobile (`mobile.yml`) ```yaml name: Mobile CI on: push: branches: [main, develop] paths: - 'mobile/**' # Code Flutter modifié - 'features/ui/**' # Tests UI modifiés - 'features/e2e/**' # Tests E2E (impliquent mobile) - '.github/workflows/mobile.yml' pull_request: branches: [main, develop] paths: - 'mobile/**' - 'features/ui/**' - 'features/e2e/**' jobs: test-unit: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: flutter-version: '3.16.0' - run: cd mobile && flutter test test-integration: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: flutter-version: '3.16.0' - run: cd mobile && flutter test integration_test/ lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: flutter-version: '3.16.0' - run: cd mobile && flutter analyze build-android: runs-on: ubuntu-latest needs: [test-unit, test-integration, lint] steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: flutter-version: '3.16.0' - run: cd mobile && flutter build apk --release build-ios: runs-on: macos-latest needs: [test-unit, test-integration, lint] steps: - uses: actions/checkout@v4 - uses: subosito/flutter-action@v2 with: flutter-version: '3.16.0' - run: cd mobile && flutter build ios --release --no-codesign ``` **Déclenché par** : - Modifications dans `/mobile` (code Flutter/Dart, assets, config) - Nouvelles features UI dans `/features/ui` - Tests end-to-end dans `/features/e2e` (mobile impliqué) --- #### Workflow Shared (`shared.yml`) ```yaml name: Shared CI on: push: branches: [main, develop] paths: - 'docs/**' # Documentation modifiée - 'shared/**' # Code partagé modifié - '.github/workflows/shared.yml' pull_request: branches: [main, develop] paths: - 'docs/**' - 'shared/**' jobs: docs-validation: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: '3.11' - run: | pip install mkdocs mkdocs-material mkdocs build --strict docs-links: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: lycheeverse/lychee-action@v1 with: args: 'docs/**/*.md' shared-tests: runs-on: ubuntu-latest if: contains(github.event.head_commit.modified, 'shared/') steps: - uses: actions/checkout@v4 # Tests pour code partagé si nécessaire ``` **Déclenché par** : - Modifications dans `/docs` (ADR, règles métier, documentation technique) - Modifications dans `/shared` (contrats API, types partagés) --- ### Matrice de Déclenchement | Modification | Backend | Mobile | Shared | Temps total | |-------------|---------|--------|--------|-------------| | `backend/internal/auth/service.go` | ✅ | ❌ | ❌ | ~5 min | | `mobile/lib/screens/home.dart` | ❌ | ✅ | ❌ | ~8 min | | `features/api/authentication/*.feature` | ✅ | ❌ | ❌ | ~5 min | | `features/ui/audio-guides/*.feature` | ❌ | ✅ | ❌ | ~8 min | | `features/e2e/abonnements/*.feature` | ✅ | ✅ | ❌ | ~13 min (parallèle) | | `docs/adr/018-email.md` | ❌ | ❌ | ✅ | ~30s | | **Commit mixte (backend + mobile + docs)** | ✅ | ✅ | ✅ | ~13 min (parallèle) | **Économie de temps** : - Commit backend-only : ~5 min (vs 15 min sans path filters) = **67% plus rapide** - Commit docs-only : ~30s (vs 15 min) = **97% plus rapide** ### Cas Particulier : Features E2E Les tests end-to-end dans `/features/e2e/` **déclenchent les deux workflows** (backend ET mobile) car ils testent l'intégration complète : **Exemples de features E2E** : - `features/e2e/abonnements/` : Formulaire mobile → API Zitadel → API RoadWave → Mangopay → Confirmation UI - `features/e2e/error-handling/` : Perte réseau → Fallback mode offline → Reprise auto après reconnexion **Justification** : Les features E2E valident le contrat backend-mobile, donc les deux doivent être testés. --- ## Justification ### Avantages ✅ **Rebuild sélectif** : changement backend → seulement backend rebuild (~5 min au lieu de 15 min) ✅ **Économie de temps CI** : ~70% de réduction sur commits isolés (backend-only ou mobile-only) ✅ **Économie de coûts** : GitHub Actions facturé à la minute → réduction proportionnelle des coûts ✅ **Parallélisation** : workflows indépendants exécutés en parallèle par GitHub Actions ✅ **Features E2E** : déclenchent backend ET mobile → cohérence end-to-end garantie ✅ **Feedback rapide** : développeur backend voit uniquement résultats backend (moins de bruit) ✅ **Scalabilité** : ajout de nouveaux composants (admin panel, worker, etc.) = nouveau workflow isolé ### Inconvénients ❌ **Duplication config** : certains éléments (checkout, cache) dupliqués entre workflows ❌ **Maintenance** : 3 workflows à maintenir au lieu de 1 ❌ **Complexité initiale** : setup plus complexe que workflow monolithique **Mitigation** : - Utiliser des **composite actions** pour partager la config commune - Documentation claire dans ce ADR - Coût initial faible (~2h setup) vs gains à long terme importants --- ## Implémentation ### Prérequis - ✅ Code backend implémenté avec tests unitaires + intégration - ✅ Code mobile implémenté avec tests Flutter - ✅ Step definitions BDD implémentées pour `api/`, `ui/`, `e2e/` - ✅ Catégorisation features BDD en `/features/{api,ui,e2e}` ([ADR-007](007-tests-bdd.md)) ### Plan d'Implémentation **Phase 1** : Setup workflows de base (~1h) - Créer `backend.yml` avec jobs test + lint + build - Créer `mobile.yml` avec jobs test + lint + build - Créer `shared.yml` avec validation docs **Phase 2** : Configuration path filters (~30 min) - Ajouter `paths:` à chaque workflow - Tester avec commits isolés (backend-only, mobile-only, docs-only) **Phase 3** : Optimisations (~30 min) - Ajouter caching (Go modules, Flutter dependencies, node_modules) - Créer composite actions pour config partagée - Ajouter badges status dans README **Effort total estimé** : ~2h ### Validation ```bash # Test 1 : Commit backend-only git add backend/ git commit -m "test: backend change" git push # → Vérifier que SEULEMENT backend.yml s'exécute # Test 2 : Commit mobile-only git add mobile/ git commit -m "test: mobile change" git push # → Vérifier que SEULEMENT mobile.yml s'exécute # Test 3 : Commit E2E git add features/e2e/ git commit -m "test: e2e change" git push # → Vérifier que backend.yml ET mobile.yml s'exécutent # Test 4 : Commit docs-only git add docs/ git commit -m "docs: update ADR" git push # → Vérifier que SEULEMENT shared.yml s'exécute ``` --- ## Conséquences ### Positives - **Productivité développeur** : feedback 3x plus rapide sur commits isolés - **Coûts réduits** : ~70% d'économie sur minutes GitHub Actions - **Meilleure expérience PR** : reviews plus rapides, moins d'attente CI - **Scalabilité** : facile d'ajouter nouveaux composants (worker, admin, etc.) ### Négatives - **Maintenance** : 3 workflows à maintenir vs 1 - **Setup initial** : ~2h vs ~30 min pour workflow simple - **Complexité** : nécessite compréhension path filters GitHub Actions ### Risques ⚠️ **Faux négatifs** : path filter mal configuré → test non exécuté → bug en production **Mitigation** : - Features E2E déclenchent toujours backend + mobile (safety net) - Tests de validation dans le plan d'implémentation - Review obligatoire des modifications de workflows --- ## Références - [ADR-007 - Tests BDD et Catégorisation Features](007-tests-bdd.md) - [ADR-016 - Organisation Monorepo](016-organisation-monorepo.md) - [GitHub Actions - Path Filters](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore) - [Monorepo CI/CD Best Practices](https://monorepo.tools/#ci-cd) --- ## Statut d'Implémentation **Actuel** : **Documenté mais non implémenté** **Quand** : Lors du Sprint d'implémentation backend/mobile (code production) **Pourquoi reporté** : Le projet est actuellement en phase de documentation uniquement. Aucun code backend/mobile n'est implémenté, donc pas de tests à exécuter. L'implémentation CI/CD sera faite lors du développement. **Prochaines étapes** : 1. Implémenter code backend avec tests 2. Implémenter code mobile avec tests 3. Implémenter step definitions BDD 4. Créer workflows CI/CD selon ce ADR 5. Valider avec commits de test