Architectures de pipelines
Monorepo, multi-dépôts, matrices : structurer à l'échelle.
Une startup de trois personnes avec un seul service n'a pas besoin de la même architecture qu'une banque de deux cents équipes et de centaines de microservices. La première se pilote avec une pipeline unique qui construit, teste et déploie la seconde doit découper ses dépôts, détecter les changements et coordonner des dizaines de chaînes. Il n'existe pas de « meilleure » pipeline — seulement celle qui correspond à votre contexte.
En bref
Parler d'architecture de pipeline, c'est parler de la façon dont on organise l'ensemble des pipelines, pas du contenu de l'une d'elles : combien y en a-t-il, comment se déclenchent-elles, et comment les artefacts circulent-ils entre elles ?
Trois facteurs qui décident
| Facteur | Questions à se poser |
|---|---|
| Structure d'équipe | combien de développeurs, combien d'équipes ? travaillent-elles sur le même code ? |
| Stratégie de branches | plusieurs branches longues, ou tout le monde sur main ? |
| Modèle de déploiement | une fois par mois ou cinquante fois par jour ? plusieurs versions en production ? |
L'architecture n'est pas un choix esthétique : elle découle de ces trois réponses.
Stratégies de branches
La façon dont vous organisez vos branches Git détermine directement la structure de vos pipelines. Deux philosophies s'opposent.
À gauche, des branches qui vivent des semaines à droite, des branches qui vivent une matinée.
Pipeline par branche
Plusieurs branches « longues » vivent en parallèle pendant des semaines.
Les développeurs travaillent sur des branches feature/*, fusionnées dans
develop une release/X.Y est ouverte pour préparer une version,
puis fusionnée dans main après validation. Chaque branche longue a sa
propre pipeline.
| Branche | Ce que fait la pipeline |
|---|---|
feature/* | tests unitaires, style, analyse statique |
develop | tests, puis déploiement en environnement de développement |
release/* | tests complets, déploiement en staging, tests d'acceptation |
main | déploiement en production, souvent après approbation |
Une branche, un rôle, un comportement de pipeline.
Les avantages tiennent en trois mots : séparation claire — un environnement par branche, facile à expliquer —, contrôle fin sur ce qui part en production et quand, et versions parallèles maintenables (1.0, 1.1, 2.0). En face : la complexité de plusieurs pipelines qui peuvent diverger, des fusions douloureuses — plus une branche vit longtemps, plus les conflits s'accumulent — et un délai de plusieurs semaines entre l'écriture du code et sa mise en production.
Contexte idéal
Équipes à cycles de publication planifiés — mensuels, trimestriels — et produits dont plusieurs versions cohabitent chez les clients : logiciels installés, applications mobiles.
Trunk-based : tout sur une seule branche
Tout le monde travaille sur la branche principale. Les branches de fonctionnalité existent mais durent quelques heures, rarement plus d'une journée : on ouvre une demande de fusion, elle est revue rapidement, et dès la fusion la pipeline se déclenche. Si tout passe, le code peut partir en production automatiquement.
{Le drapeau de fonctionnalité : du code en production, mais éteint.}
if feature_flags.is_enabled("nouvelle_interface_paiement"):
afficher_nouvelle_interface()
else:
afficher_ancienne_interface()C'est la clé du modèle : comment déployer du code qui n'est pas terminé ? En le déployant désactivé. Quand la fonctionnalité est prête, on l'active pour quelques utilisateurs, puis pour tous.
Les avantages : une intégration réellement continue — le code est
intégré plusieurs fois par jour —, pas d'enfer des fusions puisque les
branches sont courtes, et un retour rapide sur la compatibilité avec le
travail des autres. Le prix : une discipline stricte — chaque commit
sur main doit être de qualité production —, des drapeaux de
fonctionnalité obligatoires, donc une infrastructure de plus à gérer, et une
couverture de tests excellente sans laquelle c'est le chaos.
Contexte idéal
Équipes matures pratiquant le déploiement continu, produits en ligne où une seule version est en production.
Laquelle choisir
| Aspect | Pipeline par branche | Trunk-based |
|---|---|---|
| Fréquence de fusion | jours ou semaines | heures |
| Nombre de pipelines | une par type de branche | une seule |
| Drapeaux de fonctionnalité | optionnels | obligatoires |
| Risque de conflit Git | élevé : branches longues | faible : branches courtes |
| Délai jusqu'à la production | jours ou semaines | minutes ou heures |
| Complexité de la pipeline | moyenne à élevée | simple |
| Besoin en tests | important | critique |
La ligne décisive est la première : la fréquence de fusion détermine tout le reste.
Le raccourci de décision : une livraison par mois ou moins, GitFlow reste acceptable plusieurs par semaine, le trunk-based mérite considération plusieurs versions en production, GitFlow est souvent nécessaire un service en ligne à version unique, le trunk-based est plus adapté.
Monorepo ou polyrepo
Autre question structurante : combien de dépôts Git avez-vous ?
Monorepo : tout dans un seul dépôt
Tous les services, bibliothèques et outils partagent le même dépôt. Google, Meta et Microsoft emploient cette approche pour une grande partie de leur code.
monorepo/
├── services/
│ ├── api/ service backend
│ ├── frontend/ application web
│ └── worker/ traitement asynchrone
├── libs/
│ ├── auth/ bibliothèque d'authentification
│ └── utils/ utilitaires partagés
└── infra/
├── terraform/ infrastructure décrite en code
└── k8s/ manifestes KubernetesLe défi : ne pas tout reconstruire à chaque commit. Si quelqu'un modifie le fichier d'aide du frontend, il est inutile de reconstruire l'API — la pipeline doit détecter ce qui a réellement changé.
Commit modifiant : services/api/src/users.py
Analyse des dépendances :
services/api -> reconstruire (fichier modifié)
libs/auth -> vérifier (l'API l'utilise peut-être)
services/frontend -> ignorer (non impacté)
services/worker -> ignorer (non impacté)Avantages : refactorisation atomique — une seule demande de fusion modifie l'API, le frontend et les bibliothèques en restant cohérente —, partage de code naturel sans publication de paquets, et cohérence des versions. Inconvénients : une pipeline complexe, qui exige un outillage de détection des changements, un temps de clonage qui grandit avec le dépôt, et des permissions difficiles à restreindre partie par partie.
| Outil | Écosystème | Point fort |
|---|---|---|
| Nx | JavaScript, TypeScript | excellent sur les projets frontend |
| Turborepo | JavaScript, TypeScript | simple, rapide, cache distribué |
| Bazel | polyglotte | très puissant, apprentissage exigeant |
| Pants | Python, Go, Java | bonne alternative à Bazel |
Quatre outils de construction incrémentale — le monorepo sans outillage ne tient pas à l'échelle.
Polyrepo : un dépôt par service
github.com/acme/api dépôt et pipeline propres
github.com/acme/frontend idem
github.com/acme/worker idem
github.com/acme/libs-auth publié comme paquet (npm, PyPI…)
github.com/acme/infra Terraform séparéAvantages : une pipeline simple par dépôt, des équipes autonomes — l'équipe API déploie sans attendre le frontend — et des permissions claires. Inconvénients : la coordination des versions (l'API v2.3 est-elle compatible avec le frontend v1.8 ?), la duplication des configurations de pipeline d'un dépôt à l'autre, et une refactorisation pénible — modifier une interface partagée impose plusieurs demandes de fusion dans plusieurs dépôts.
L'enfer des dépendances
En polyrepo, les bibliothèques partagées sont publiées comme des paquets. Trois
questions apparaissent aussitôt : quand libs-auth publie une version,
qui la met à jour dans chaque service ? Comment s'assurer que tous les services
restent compatibles ? Que faire d'un service bloqué sur une vieille version ?
En pratique : une stratégie hybride
Peu d'organisations sont entièrement monorepo ou entièrement polyrepo. La plupart tranchent type de code par type de code.
| Type de code | Stratégie | Pourquoi |
|---|---|---|
| Services métier | monorepo | refactorisation atomique, cohérence |
| Infrastructure | dépôt séparé | cycle de vie et permissions distincts |
| Bibliothèques très partagées | dépôts séparés, versionnés | réutilisation au-delà de l'organisation |
Le découpage suit les cycles de vie, pas l'organigramme.
Promotion plutôt que reconstruction
L'artefact déployé en production est-il bien celui qui a été testé ? Le chapitre a posé le principe — construire une fois, déployer partout il vaut aussi à l'échelle de l'architecture : c'est la même image qui traverse dev, staging et production, seule la configuration change.
{L'approbation manuelle porte sur un artefact déjà construit et déjà testé.}
build:
script:
- docker build -t app:CI_COMMIT_SHA .
- docker push registry/app:CI_COMMIT_SHA
staging:
script:
- helm upgrade app ./chart --set image.tag=CI_COMMIT_SHA
--set env=staging -f values-staging.yaml
production:
script:
- helm upgrade app ./chart --set image.tag=CI_COMMIT_SHA
--set env=production -f values-production.yaml
when: manual # approbation requiseTrois prérequis, du côté de l'application : séparer la construction de la configuration — aucune URL ni identifiant en dur —, accepter sa configuration à l'exécution, et disposer d'un registre d'artefacts fiable où stocker les images entre les étapes.
Pipeline applicative et pipeline d'infrastructure
L'infrastructure aussi peut — et devrait — être pilotée par une pipeline. Mais les deux n'ont ni la même fréquence ni le même rayon d'impact, et c'est cette asymétrie qui justifie de les traiter séparément.
| Pipeline applicative | Pipeline d'infrastructure | |
|---|---|---|
| Ce qu'elle déploie | le code : API, frontend, workers, tâches planifiées | les ressources : réseaux, bases de données, clusters, DNS |
| Déclencheur | un commit sur le code applicatif | une modification de l'infrastructure décrite en code |
| Fréquence | élevée, plusieurs fois par jour | faible, quelques fois par semaine |
| Impact | limité, un service à la fois | large, potentiellement tous les services |
Deux rythmes, deux rayons d'impact — donc deux régimes de garde-fous.
| Approche | Avantages | Inconvénients |
|---|---|---|
| Pipelines séparées | cycles indépendants, permissions distinctes, rayon d'impact limité | coordination parfois manuelle |
| Pipeline unique | déploiement atomique de l'infrastructure et de l'application | complexité, risque élevé en cas d'échec |
Recommandation : séparer, mais coordonner.
Mélanger les deux produit des pipelines lourdes, où un changement de couleur de bouton déclenche une vérification Terraform. Trois façons de coordonner sans fusionner : des déclencheurs — la pipeline d'infrastructure lance l'applicative après succès —, le GitOps — un opérateur comme ArgoCD ou Flux détecte les changements et déploie — ou des dépendances explicites, l'applicative vérifiant que l'infrastructure est à jour avant de déployer.
Trois formes avancées
La pipeline en diamant
Exécuter un maximum de jobs en parallèle, puis reconverger avant l'étape suivante. Le graphe en prend la forme : un point de départ, une divergence, une convergence, puis à nouveau.
Un diamant : trois vérifications en parallèle, une convergence avant la construction.
Le temps total baisse, le retour arrive plus tôt — un échec de style se voit sans attendre la fin des tests — et les runners travaillent en parallèle. Revers : tous les jobs parallèles doivent réussir pour passer à la suite un seul échec bloque la convergence.
La matrice
Votre bibliothèque doit fonctionner avec Python 3.9 à 3.12, sur Ubuntu, macOS et Windows : douze combinaisons. La matrice les engendre automatiquement.
{Quatre versions fois trois systèmes : douze jobs parallèles, quatre lignes de configuration.}
test:
strategy:
matrix:
python: [3.9, 3.10, 3.11, 3.12]
os: [ubuntu-24.04, macos-latest, windows-latest]Cas d'usage : bibliothèques ouvertes à compatibilité large, applications de bureau multi-systèmes, validation de compatibilité avant une montée de version.
La pipeline conditionnelle
| Condition | Comportement |
|---|---|
branche main | déployer en staging, puis en production après approbation |
branche feature/* | déployer dans un environnement éphémère, détruit sous 24 h |
fichiers modifiés dans docs/ | ignorer les tests, reconstruire seulement la documentation |
tag créé (v*) | publier une version et les paquets associés |
Économie de ressources, retour adapté au contexte — sans multiplier les pipelines.
Choisir : quatre questions
Combien d'équipes travaillent sur le code ?
Le nombre d'équipes qui partagent le code décide surtout entre monorepo et polyrepo. Tant qu'une seule équipe touche à l'ensemble, un monorepo reste simple à outiller.
| Situation | Recommandation |
|---|---|
| une équipe, moins de 10 personnes | monorepo simple, trunk-based envisageable |
| deux à cinq équipes | monorepo outillé (Nx, Turborepo) ou polyrepo léger |
| dix équipes et plus | polyrepo probable, ou monorepo avec une équipe dédiée à l'outillage |
Au-delà de quelques équipes, il faut investir dans l'outillage ou découper.
À quelle fréquence déployez-vous ?
Plus vous livrez souvent, moins les branches longues sont tenables : le coût des fusions finit par dépasser le contrôle qu'elles apportent.
| Fréquence | Recommandation |
|---|---|
| mensuelle ou moins | GitFlow acceptable, promotion d'artefact recommandée |
| hebdomadaire | trunk-based à considérer, promotion obligatoire |
| quotidienne ou plus | trunk-based, drapeaux de fonctionnalité, déploiement continu |
À partir du rythme hebdomadaire, la promotion cesse d'être un confort.
Avez-vous plusieurs versions en production ?
C'est souvent la question la plus contraignante, car elle ne dépend pas de vos préférences mais de votre produit.
| Situation | Recommandation |
|---|---|
| non : service en ligne, version unique | trunk-based, pipeline unique |
| oui : logiciel installé, application mobile | branches de publication, pipelines par branche |
Un produit installé chez le client impose de maintenir plusieurs versions en parallèle.
Quelle est votre maturité en tests ?
Elle agit comme un garde-fou sur tout ce qui précède : le trunk-based et le déploiement continu ne fonctionnent que si les tests attrapent réellement les régressions. Sinon, chaque fusion devient un pari.
| Niveau | Recommandation |
|---|---|
| peu ou pas de tests automatisés | pipelines simples, investir d'abord dans les tests |
| couverture correcte (plus de 60 %) | trunk-based envisageable, avec prudence |
| excellente couverture et tests d'intégration | déploiement continu possible |
Accélérer les déploiements sans tests solides transforme la pipeline en distributeur d'incidents.
L'anti-patron : copier sans comprendre
« Netflix fait du trunk-based, on devrait faire pareil »
Netflix a des centaines d'ingénieurs dédiés à l'outillage, des années d'itération sur ses pratiques, une infrastructure de tests et de drapeaux de fonctionnalité mature, et un contexte de service en ligne à version unique. Copier l'architecture sans reproduire ces quatre conditions, c'est hériter de la complexité sans le socle qui la rend soutenable : pipelines fragiles, déploiements ratés, et une équipe qui répare l'outillage au lieu de livrer.
La bonne approche
- Commencer simple — une pipeline linéaire qui construit, teste, déploie.
- Identifier les douleurs — qu'est-ce qui vous ralentit réellement ?
- Évoluer progressivement — ajouter de la complexité quand le besoin est démontré.
- Mesurer — durée de pipeline, fréquence de déploiement, taux d'échec.
À retenir de cette séance
L'architecture de pipeline reflète votre contexte — structure d'équipe, stratégie de branches, modèle de déploiement — et il n'existe pas de solution universelle. Trunk-based ou GitFlow : branches courtes, moins de conflits et un retour rapide, mais discipline et drapeaux de fonctionnalité branches longues, plus de contrôle, mais fusions douloureuses. Monorepo ou polyrepo : le premier facilite refactorisation et cohérence mais demande de l'outillage le second donne de l'autonomie mais complique la coordination. Promotion plutôt que reconstruction. Application et infrastructure séparées, mais coordonnées. Et surtout : commencer simple, complexifier quand c'est nécessaire.
Réponse unique
Quel est le principal coût du développement sur tronc commun ?
Indice · Comment intégrer souvent du travail pas encore terminé ?
[ METTRE EN PRATIQUE ]
Choisir une architecture argumentée
3 étapes · 30 min · 130 XP
[ CETTE LEÇON DANS LES PARCOURS ]
- Ingénieur DevOpsétape 19 / 23suivant — Anti-patrons CI/CD →