# ADR-023 : Pipeline CI avec image PHP préparée et tâches parallèles

**Statut :** Accepté
**Date :** 2026-10-27
**Contexte :** `.gitlab-ci.yml`, runner autohébergé sur server1 (le serveur de production, tag `welely-server`)

---

## Contexte

Une pipeline demandait environ 10 minutes de travail avant le déploiement sur staging, dont une grande part perdue en préparation :

- chaque tâche PHP (style, analyse statique, audit, tests) partait de `php:8.3-cli`, réinstallait les paquets système et **compilait les extensions PHP** : environ 1 minute par tâche, dont 55 s de compilation. Le contrôle de style durait 98 s pour 16 s de contrôle réel ;
- le runner n'exécute que quelques tâches à la fois : jusqu'à 4 min 30 d'attente avant de démarrer ;
- le runner étant le serveur de production, les compilations simultanées se ralentissaient entre elles (style : 98 s sur master, 264 s sur une MR) et prenaient du processeur au site ;
- les étapes s'enchaînaient : le frontend attendait les tests sans en dépendre.

## Décision

1. **Image de CI préparée** (`docker/ci/php.Dockerfile`) : PHP 8.3, extensions, Composer, git et client MySQL. La tâche `ci-image` (étape `prepare`) la construit avec Kaniko, sans démon Docker ni conteneur privilégié, quand le Dockerfile change, et la pousse dans le registre GitLab du projet. Les tâches PHP l'utilisent (`CI_PHP_IMAGE`, tag versionné à changer avec le Dockerfile).
2. **Style et analyse statique dans une seule tâche** (`lint-php`) : une préparation au lieu de deux. Les deux contrôles tournent toujours, la tâche échoue si l'un échoue.
3. **Audit sur `composer.lock`** (`composer audit --locked`) : plus d'installation.
4. **Dépendances déclarées** (`needs`) : tests JS et frontend démarrent tout de suite ; staging attend le style, l'analyse, les tests et le frontend (pas l'audit, non bloquant) ; la production attend staging et le frontend.
5. **Caches par contenu** : `vendor/` selon `composer.lock`, cache npm selon `package-lock.json` (au lieu de `node_modules/` par branche, que `npm ci` supprimait de toute façon).

## Alternatives Considérées

### Augmenter le nombre de tâches simultanées du runner
Réduit l'attente. Rejeté : le runner est le serveur de production ; plus de tâches simultanées, c'est plus de processeur pris au site.

### Image publique déjà équipée (Docker Hub)
Rien à construire. Rejeté : dépendance à un tiers pour une image qui exécute notre code avec les secrets de CI (risque de chaîne d'approvisionnement).

### Ne lancer le lint que sur les MR, pas sur master
Moins de travail après le merge. Rejeté : master doit rester vérifié avant tout déploiement.

## Conséquences

- Nouveau dossier `docker/ci/`, nouvelle étape `prepare` qui ne tourne que si le Dockerfile change.
- Modifier le Dockerfile impose de changer le tag `CI_PHP_IMAGE` : sinon les pipelines déjà en cours gardent l'ancienne image.
- La tâche `ci-image` compare le Dockerfile à master (`compare_to`) : elle ne tourne que dans la pipeline de la branche qui le modifie, avant le merge. Sans cette comparaison, chaque nouvelle branche reconstruisait l'image (5 à 7 min).
- Les tâches PHP dépendent du registre GitLab du projet (activé).

## Quand Réviser

- Si la montée de version de PHP ou d'une extension est nécessaire : nouveau tag d'image.
- Si un runner dédié (hors serveur de production) est mis en place : augmenter alors le parallélisme.
