- ADR 0014 : un pipeline CI unique, « CI ok » seul check à exiger, déploiement du commit testé. - ADR 0015 : e2e et charge contre la stack Compose déployée, hypothèses et seuils de k6. - ADR 0016 : supervision en profil Compose, active en prod, rôle en lecture seule. - Nouvelle vue 60-observabilite.md ; 00-vue-ensemble, 10-infra, 20-backend et 50-cicd mis à jour (monitoring passé à Fait, nouveau graphe de CI, gates, ports). - README racine et guide de tests du frontend : où sont l'e2e, la charge et la supervision.
5.0 KiB
0014 - Un pipeline CI unique appelle les workflows de composant et conditionne le déploiement
- Statut : accepté
- Date : 2026-09-23
- Complète : 0009, qui reste en vigueur
Contexte
Au 22/09, huit workflows se déclenchaient chacun de leur côté, et l'audit y a relevé :
- Double exécution. Chaque workflow partait sur
push(toutes branches) et surpull_request. Un commit poussé sur une branche de PR jouait donc toute la CI deux fois, à la même minute (constaté dans l'historique des runs detest/integration-api-db-ml). - Sonar refaisait tout.
sonarqube.ymlreconstruisait le frontend et retestait frontend, backend et ML pour produire ses rapports de couverture, en double exact defrontend.yml,backend.ymletml.yml. Son test backend tournait sansuv sync. Il n'avait nipermissionsniconcurrency. - Déploiement non conditionné.
deploy.ymlpartait à chaque push surdevoumain, que la CI du commit soit verte ou non, et déployait la pointe de branche du moment plutôt que le commit poussé. - Erreurs silencieuses et hygiène.
npm test --watch=false --code-coverage: npm garde ces options pour lui,ng testne les reçoit jamais, et la CI ne tenait que par les réglages d'angular.json.uv sync --frozenne vérifie pas queuv.locksuitpyproject.toml.- Plusieurs actions tierces étaient épinglées par tag, contrairement à la règle Sonar
githubactions:S7637. - Aucun job n'avait de
timeout-minutes(360 minutes par défaut).
Décision
ci.yml est le seul workflow déclenché par pull_request et par les push sur dev et
main. Les workflows de composant (backend, frontend, ml, airflow, infra, e2e)
passent en workflow_call et n'ont plus de déclencheur propre.
changes. Un job initial calcule, pardorny/paths-filterépinglé sur un SHA, les composants touchés par la PR, et chaque composant n'est appelé que si son filtre vaut vrai. Sur un push versdevoumain, tous les filtres valent vrai : l'analyse Sonar reste complète sur les branches longues, et paths-filter ne compare pas à la base de fusion avecmain, qui a 80 commits de retard.sonar. Il ne reconstruit ni ne reteste plus rien : il télécharge, dans le même run, les couvertures versées par les jobsverificationdes composants.CI ok. Le job agrège le résultat de tous les autres. Il tourne toujours (if: always()) et échoue dès qu'un job est enfailureoucancelled. C'est le seul check à exiger dans les règles de branche : un composant sauté par son filtre ne publie aucun check interne, qui resterait « en attente » s'il était exigé.deploy. Il appelledeploy.yml, sur les seuls push, et seulement siCI oka réussi.deploy.ymlaligne le dossier de l'environnement surGITHUB_SHA, le commit testé.
deploy.yml n'a toujours aucun déclencheur pull_request : il n'accepte que
workflow_call et workflow_dispatch, dans l'esprit de l'ADR 0009.
Alternatives écartées
| Écartée | Raison |
|---|---|
Garder huit workflows et restreindre seulement push à dev et main |
Supprime la double exécution, pas le doublon Sonar : il faudrait toujours rejouer les tests pour que Sonar ait ses couvertures, les artefacts ne passant pas d'un workflow à l'autre. Et rien n'empêche un déploiement rouge. |
Déclencher le déploiement par workflow_run |
workflow_run joue toujours le fichier de la branche par défaut, main, en retard de 80 commits : la recette ne se serait plus déployée avant la prochaine remontée vers main, sans erreur visible. |
alls-green ou une action tierce d'agrégation |
Dix lignes de shell sur toJSON(needs.*.result) font le même travail, sans dépendance de plus à épingler. |
Cache de couches Docker (bake-action, type=gha) pour l'e2e |
Quatre pièges (noms d'image, cibles Compose, buildx, load) pour deux à quatre minutes gagnées. Reporté après le rendu. |
Conséquences
-
Une PR ne joue que ce qu'elle touche. Une PR de documentation ne joue que
changesetCI ok. -
Les checks s'appellent désormais « Backend / Lint, typage et tests », etc. Au 23/09, ni
devnimainn'ont de règle de protection : à la première, exiger « CI ok » et rien d'autre. -
Modifier
ci.ymlrejoue toute la CI sur la PR (filtreci). -
Le job
deployreste en file tant que le runnereni-g3n'est pas enregistré sur la VM, comme avant. Le groupe de concurrence par SHA des push l'empêche de bloquer les runs suivants. -
La sécurité du runner auto-hébergé ne repose pas sur l'absence de
pull_requestdansdeploy.yml. Une PR de fork peut ajouter son propre workflow. Ce qui protège le runner :- l'approbation obligatoire des workflows de tous les contributeurs externes ;
- les règles de branche des environnements
rec(dev) etprod(mainet un relecteur).
Ces deux réglages restent à poser par l'administratrice du dépôt.