Aller au contenu

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 :

  1. Checkout (fetch-depth: 0), Node 20 + cache yarn.
  2. yarn install --frozen-lockfile --prefer-offline.
  3. Calcul des fichiers modifiés vs la branche de base.
  4. Lint uniquement des fichiers .ts/.tsx/.js/.jsx modifiés.
  5. Contrôle d'architecture : npx depcruise src --config .dependency-cruiser.jsdepcruise-report.json.
  6. Tests + couverture : yarn jest --coverage --coverageReporters=json-summary --coverageReporters=text.
  7. Commentaire de couverture sur la PR (MishaKav/jest-coverage-comment).
  8. 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_dispatch manuel. Tourne sur la branche dev.
  • 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) + job ios (macOS) : décodent le .env.<env> / keystore / credentials depuis les secrets, puis bundle exec fastlane <lane>.
  • Le push ne lance qu'Android pour l'instant ; le job iOS (macOS) ne tourne que sur workflow_dispatch manuel — 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 ~/.gradle et saute gradle clean (runners éphémères) pour garder un build rapide.
  • Le org.gradle.jvmargs committé (-Xmx8g/-XX:MaxMetaspaceSize=8g) dépasse les ~7 Go de RAM d'un runner ubuntu-latest et fait OOM-kill le job pendant la minification R8 (se manifeste par The operation was canceled ~25 min après le début, sans erreur gradle). Le workflow le plafonne à -Xmx4g -XX:MaxMetaspaceSize=1g avant 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 abbrev a été retirée).
  • Run manuel : workflow_dispatch avec une entrée platform (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 $1Conventional 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 commas all, semicolons, printWidth: 100, tabWidth: 2.
  • ESLint (.eslintrc) : @react-native + @typescript-eslint/recommended ; curly off, @typescript-eslint/no-empty-function warn.

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}.yml
  • Dangerfile.ts
  • .husky/{pre-commit,commit-msg}, commitlint.config.js
  • .eslintrc, .prettierrc.js, .dependency-cruiser.js