CI/CD
Intégration continue, portes qualité et hooks git. Pour la publication des builds, voir release-process.md.
La CI tourne sur GitHub Actions. L'ancienne CI GitLab (.gitlab-ci.yml) est legacy (dernière modification en 2023) et de fait inutilisée.
Workflows (.github/workflows/)
ci.yml — CI (sur chaque pull request)
Un unique job quality :
- Checkout (
fetch-depth: 0), Node 20 + cache yarn. yarn install --frozen-lockfile --prefer-offline.- Calcul des fichiers modifiés vs la branche de base.
- Lint uniquement des fichiers
.ts/.tsx/.js/.jsxmodifiés. - Contrôle d'architecture :
npx depcruise src --config .dependency-cruiser.js→depcruise-report.json. - Tests + couverture :
yarn jest --coverage --coverageReporters=json-summary --coverageReporters=text. - Commentaire de couverture sur la PR (
MishaKav/jest-coverage-comment). - DangerJS :
yarn danger ci.
Warning
Il n'y a aucune étape de typecheck en CI alors même que yarn typecheck existe — lancez-le localement avant de pousser.
security-audit.yml — Audit de sécurité (hebdomadaire)
- Déclencheurs : cron
0 9 * * 1(lundis 09:00 UTC) +workflow_dispatchmanuel. Tourne sur la branchedev. yarn audit --level high --json, une étape python dédoublonne les advisories critical/high, puis poste un embed sur un webhook Discord (DISCORD_MOBILE_SECURITY_WEBHOOK_URL) — rouge si critical, orange si high, vert si propre.
deploy.yml — Deploy (sur push vers dev / staging / main)
Résout la lane d'environnement depuis la branche puis build + upload les deux plateformes. La soumission aux stores n'est jamais automatique. Voir release-process.md.
| Branche | Android | iOS |
|---|---|---|
dev |
Internal App Sharing | TestFlight |
staging |
Internal App Sharing | TestFlight |
main |
Internal App Sharing + Play Store prod (draft) |
TestFlight + version App Store (non soumise) |
- job
android(ubuntu) + jobios(macOS) : décodent le.env.<env>/ keystore / credentials depuis les secrets, puisbundle exec fastlane <lane>. - Le push ne lance qu'Android pour l'instant ; le job iOS (macOS) ne tourne que sur
workflow_dispatchmanuel — tant que la clé API App Store Connect n'est pas configurée, afin d'éviter un job macOS voué à l'échec et coûteux en minutes à chaque push. À réactiver au push une fois la clé ASC en place. - Android met en cache
~/.gradleet sautegradle clean(runners éphémères) pour garder un build rapide. - Le
org.gradle.jvmargscommitté (-Xmx8g/-XX:MaxMetaspaceSize=8g) dépasse les ~7 Go de RAM d'un runnerubuntu-latestet fait OOM-kill le job pendant la minification R8 (se manifeste parThe operation was canceled~25 min après le début, sans erreur gradle). Le workflow le plafonne à-Xmx4g -XX:MaxMetaspaceSize=1gavant de builder — CI uniquement, config locale intacte. - Les jobs tournent sur Ruby 3.3 (épinglé) — fastlane 2.220 échoue sur Ruby 3.4 (la gem par défaut
abbreva été retirée). - Run manuel :
workflow_dispatchavec une entréeplatform(both/android/ios) déploie une seule plateforme — ex.gh workflow run deploy.yml --ref dev -f platform=android(ne publie qu'Android, pratique tant que la clé ASC iOS n'est pas configurée). - Requiert les secrets de déploiement listés dans release-process.md.
release-please.yml — release-please (sur push vers staging)
Lance googleapis/release-please-action@v4 (release-type: node) pour ouvrir/maintenir la PR de release (bump de version + CHANGELOG). Voir release-process.md.
DangerJS (Dangerfile.ts)
Lancé comme dernière étape de ci.yml. Il impose :
| Contrôle | Niveau | Règle |
|---|---|---|
| Description de PR | avertissement | vide ou < 20 caractères |
| Titre de PR | avertissement | doit matcher la regex Conventional Commits |
| Assignee / draft | avertissement | assignee manquant, ou PR en draft |
| Taille de PR | échec | additions+deletions > 1500 (lockfiles et fichiers de test exclus) ; avertissement > 750 ; avertissement > 30 fichiers |
| Tests | avertissement | nouveau src/**/*.ts(x) sans nouveau fichier .test. ; ratio de test faible (< 0.2) |
| Chemins sensibles | avertissement | changements sur ios/fastlane/, .github/, babel.config.js, jest.config.js, tsconfig.json |
| Secrets | échec | OpenAI sk-…, Stripe pk_live_…, AWS AKIA…, clés PEM, token=/password= |
| Architecture | échec sur error | parse depcruise-report.json ; échoue sur les erreurs dep-cruiser, avertit sur les warnings |
Gardez les PR sous 1500 lignes de code non-test modifiées ou la CI échoue. Les fichiers de test (*.test.*) et les lockfiles sont exclus du décompte, donc la limite suit la charge de revue sur le code source — une grosse PR de couverture pleine de tests co-localisés ne la déclenche pas.
Hooks git (Husky, .husky/)
| Hook | Lance |
|---|---|
pre-commit |
npx lint-staged → ESLint + prettier --write sur les *.ts/*.tsx stagés |
commit-msg |
yarn commitlint --edit $1 → Conventional Commits imposés |
Pas de hook pre-push.
Conventions imposées
- Conventional Commits (
commitlint.config.jsétend@commitlint/config-conventional) :feat:,fix:,chore:,docs:,style:,refactor:,test:,perf:,ci:,build:,revert:. - Prettier (
.prettierrc.js) : single quotes, trailing commasall, semicolons,printWidth: 100,tabWidth: 2. - ESLint (
.eslintrc) :@react-native+@typescript-eslint/recommended;curlyoff,@typescript-eslint/no-empty-functionwarn.
Portes qualité en un coup d'œil
| Étape | Portes |
|---|---|
| Commit local | lint-staged (eslint + prettier), commitlint |
| Pull request | lint (fichiers modifiés), depcruise, jest + couverture, DangerJS |
| Hebdomadaire | yarn audit → Discord |
Push vers dev/staging/main |
deploy.yml → build & upload Android + iOS (matrice ci-dessus) |
Push vers staging |
release-please ouvre/met à jour la PR de release |
Fichiers clés
.github/workflows/{ci,deploy,security-audit,release-please}.ymlDangerfile.ts.husky/{pre-commit,commit-msg},commitlint.config.js.eslintrc,.prettierrc.js,.dependency-cruiser.js