Workflow de release
Stratégie de branches
| Branche | Rôle | Protections |
|---|---|---|
feature/* | Développement | Aucune — push libre |
develop | Intégration | CI doit passer (lint + test) |
main | Production stable | PR obligatoire depuis develop + CI doit passer |
Deux règles strictes sur main
- Push direct interdit — GitHub refuse tout push direct, PR obligatoire
- Source imposée — la PR doit venir de
develop. Une PRfeature/xxx → mainest rejetée automatiquement par le checkSource branch must be develop
Pipeline CI complet
Détail de chaque job
lint — Analyse statique
Vérifie que le code respecte les règles de style et détecte les erreurs évidentes avant même d'exécuter le code.
| Repo | Outil | Ce qui est vérifié |
|---|---|---|
healthai-web | ESLint | TypeScript, React hooks, imports |
healthai-api | ESLint | TypeScript, NestJS patterns |
healthai-etl | Ruff | Style PEP8, imports inutilisés, bugs courants |
healthai-ai | Ruff (× 3 services) | Idem, tournent en parallèle sur vision / workout / api |
healthai-ai — matrix job
Le lint tourne en parallèle sur les 3 services du repo (healthai-vision, healthai-workout, healthai-api) via une stratégie de matrix GitHub Actions.
test — Tests automatisés
Exécute la suite de tests du projet. Certains repos démarrent une base de données réelle en service Docker pour les tests d'intégration.
| Repo | Framework | Infra de test |
|---|---|---|
healthai-web | Vitest | Aucune (unit tests) |
healthai-api | Jest | PostgreSQL 15 (service Docker) |
healthai-etl | pytest | PostgreSQL 15 (service Docker) |
healthai-ai | pytest | Aucune (healthai-vision uniquement) |
ci-ok — Gate de qualité
Job synthèse qui échoue si lint ou test a échoué, et réussit uniquement si les deux sont verts. C'est ce check unique qui est requis par la protection de branche sur main et develop.
ci-ok:
needs: [lint, test]
if: always()
# échoue si l'un des jobs précédents est failure ou cancelledSans ce job agrégateur, la protection de branche devrait lister chaque job individuellement — ce qui pose problème pour les matrix jobs comme le lint de healthai-ai.
build-push — Build Docker
Déclenché uniquement sur les tags v* (ex: v1.2.3). Construit les images Docker et les pousse sur GHCR avec plusieurs tags :
v1.2.3 → :1.2.3 (version exacte, immuable)
:1.2 (dernière patch du mineur)
:1 (dernière release du majeur)
:latest (dernière release stable)healthai-ai — build matrix
Le repo healthai-ai construit 3 images en parallèle sur le même tag : healthai-vision, healthai-workout, healthai-ai-api
release — GitHub Release
Déclenché après build-push. Génère automatiquement le CHANGELOG via git-cliff en lisant les commits depuis le tag précédent, puis crée la GitHub Release.
Exemple de CHANGELOG généré :
## [1.2.0] - 2026-05-19
### Features
- (auth) ajouter le support des refresh tokens Zitadel
- nouvelle page analytics utilisateurs
### Bug Fixes
- (api) corriger la pagination des logs de santé
### Refactor
- extraire la logique de validation dans un service dédiéProtections de branche actives
| Protection | Mécanisme | Portée |
|---|---|---|
| Format des commits | GitHub Ruleset (commit_message_pattern) | Toutes les branches — bloque le push |
| Lint des commits PR | GitHub Actions (commitlint.yml) | PRs vers main et develop |
| CI requise | GitHub Ruleset (required_status_checks → CI) | main et develop |
| PR obligatoire | GitHub Ruleset (pull_request) | main uniquement |
Source = develop | GitHub Actions (check-source-branch.yml) | PRs vers main uniquement |
Créer une release
# 1. Merger develop → main via PR (la CI doit passer)
# 2. Se positionner sur main à jour
git checkout main && git pull
# 3. Taguer (semver strict)
git tag v1.2.3
git push origin v1.2.3
# → déclenche build Docker + GitHub Release automatiquementVersioning sémantique
| Type de changement | Exemple |
|---|---|
| Correctif non-breaking | v1.2.3 → v1.2.4 |
| Nouvelle feature non-breaking | v1.2.3 → v1.3.0 |
Changement breaking (feat!) | v1.2.3 → v2.0.0 |
Ne pas re-tagger
Éviter de re-créer un tag déjà pushé — l'image :1.2.3 ne sera pas reconstruite si elle existe déjà dans le registry.
Annuler un tag (si erreur avant push)
git tag -d v1.2.3
git push origin --delete v1.2.3 # si déjà pushé