đ Merge Trains GitLab : fusionner sans jamais casser main

đ Introduction
Deux merge requests peuvent chacune passer leur pipeline avec un joli badge vert. Fusionnez-les lâune aprĂšs lâautre et pourtant, main casse. Ce nâest pas un bug : chaque pipeline a testĂ© sa branche isolĂ©ment (ou combinĂ©e avec main au moment T), pas le rĂ©sultat des deux changements rĂ©unis. Sur un projet avec plusieurs MR fusionnĂ©es par jour, ce scĂ©nario nâest pas une exception, câest une statistique.
Les merge trains de GitLab rĂ©pondent prĂ©cisĂ©ment Ă ce problĂšme. LâidĂ©e : au lieu de fusionner chaque MR dĂšs que son pipeline est vert, on les met en file dâattente, et on teste chacune contre le cumul de toutes celles qui la prĂ©cĂšdent. Si ça passe, ça fusionne, dans lâordre. Si ça casse, seule la MR fautive sort du train, sans bloquer les autres.
Cet article part du principe que vous connaissez dĂ©jĂ les fondamentaux de GitLab CI (stages, jobs, rules). On se concentre ici sur la mĂ©canique des merge trains, leur activation, et comment adapter un .gitlab-ci.yml en consĂ©quence â avec deux schĂ©mas pour visualiser le flux normal et la gestion dâun Ă©chec.
đ Quâest-ce quâun merge train, concrĂštement ?
Un merge train est une file dâattente ordonnĂ©e de merge requests en cours de fusion vers la mĂȘme branche cible. Chaque MR qui y entre dĂ©clenche une pipeline testant non pas ses propres changements isolĂ©s, mais un commit spĂ©culatif : la branche cible, plus les changements de toutes les MR placĂ©es avant elle dans le train, plus les siens. La documentation GitLab rĂ©sume le problĂšme que ça rĂ©sout ainsi : deux merge requests peuvent chacune passer leur propre pipeline, mais leurs changements combinĂ©s peuvent tout de mĂȘme entrer en conflit.
Ce mĂ©canisme sâappuie sur les pipelines de rĂ©sultats fusionnĂ©s (« merged results pipelines »), qui existent indĂ©pendamment des merge trains : elles testent dĂ©jĂ un commit temporaire combinant branche source et branche cible. Le merge train Ă©tend cette idĂ©e en chaĂźnant plusieurs MR Ă la suite, chacune testĂ©e contre le cumul de celles qui la prĂ©cĂšdent.
đ§± Le flux normal : validation cumulative
Prenons trois MR entrées dans le train dans cet ordre : !42, !45, !49. Voici ce qui se passe :
!42est testĂ©e surmain + !42. Pipeline verte â elle fusionne en premier.!45est testĂ©e surmain + !42 + !45, mĂȘme si!42nâa pas encore fini de fusionner. GitLab lance les pipelines en parallĂšle pour ne pas ralentir le train.!49est testĂ©e surmain + !42 + !45 + !49.
La rĂšgle de fusion est stricte : une MR ne fusionne rĂ©ellement dans main que si son propre pipeline a rĂ©ussi ET que toutes les MR placĂ©es avant elle ont dĂ©jĂ fusionnĂ©. Une pipeline verte ne suffit pas si le wagon prĂ©cĂ©dent est encore en cours â GitLab attend son tour. Câest ce qui garantit un historique semi-linĂ©aire : main avance toujours par ajouts validĂ©s dans lâordre, jamais par un mĂ©lange non testĂ©.
Par dĂ©faut, GitLab exĂ©cute jusquâĂ 20 pipelines de merge train en parallĂšle sur un mĂȘme projet ; cette limite est configurable par projet depuis GitLab 19.0.
đ Que se passe-t-il en cas dâĂ©chec ?
Câest lĂ que le merge train montre son intĂ©rĂȘt par rapport Ă une fusion manuelle sĂ©quentielle : un Ă©chec nâimmobilise pas tout le monde.
Si la pipeline de !45 échoue :
- GitLab retire
!45du train â elle repart en attente dâune correction, hors du flux. - GitLab relance immĂ©diatement les pipelines de toutes les MR placĂ©es aprĂšs elle dans le train, cette fois sans les changements de
!45.!49est donc retestée surmain + !42 + !49. - Les pipelines devenues redondantes (celles qui incluaient encore
!45) sont annulées automatiquement.
Le train continue son chemin. !45 peut ĂȘtre corrigĂ©e et remise dans la file Ă son tour, sans avoir bloquĂ© !49 une seule minute de plus que le temps de recalcul de sa pipeline.
đ Activer les merge trains sur son projet
Deux prérequis avant de commencer :
- Le projet doit ĂȘtre hĂ©bergĂ© nativement sur GitLab (pas un miroir dâun dĂ©pĂŽt externe comme GitHub ou Bitbucket).
- Vous devez ĂȘtre sur un plan Premium ou Ultimate â merge trains nâexiste pas sur le plan Free.
Lâactivation se fait dans Settings > Merge requests > Merge options :
- Cochez dâabord « Enable merged results pipelines » â câest un prĂ©requis technique, les merge trains sâappuient dessus.
- Cochez ensuite « Enable merge trains ».
- Enregistrez.
Une fois actif, un nouvel onglet « Merge trains » apparaßt sous Code > Merge requests (disponible depuis GitLab 17.3), listant les MR actuellement en file et leur position.
đ§° Adapter son .gitlab-ci.yml
Contrairement Ă ce quâon pourrait imaginer, activer les merge trains ne demande aucun mot-clĂ© YAML particulier : GitLab orchestre le tout au niveau des paramĂštres du projet et du merge request. Le seul prĂ©requis cĂŽtĂ© configuration est que le pipeline soit dĂ©jĂ taillĂ© pour tourner en pipeline de merge request, avec un workflow ou des rules basĂ©s sur $CI_PIPELINE_SOURCE :
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHLĂ oĂč ça devient intĂ©ressant, câest pour distinguer le contexte exact dâune pipeline de merge request. La variable prĂ©dĂ©finie $CI_MERGE_REQUEST_EVENT_TYPE prend lâune de ces trois valeurs :
detachedâ pipeline classique de MR, teste uniquement la branche source.merged_resultâ teste le commit spĂ©culatif branche source + branche cible.merge_trainâ teste le commit spĂ©culatif cumulant en plus les MR prĂ©cĂ©dentes dans le train.
Câest utile pour rĂ©server les jobs les plus coĂ»teux (suite e2e complĂšte, tests de charge) au passage rĂ©el dans le train, plutĂŽt que de les lancer Ă chaque pipeline de MR classique :
tests-e2e-completes:
stage: test
script:
- ./scripts/run-e2e.sh
rules:
- if: $CI_MERGE_REQUEST_EVENT_TYPE == 'merge_train'â ïž Quelques prĂ©cautions
- Conflit avec la cible = pas de pipeline. Une pipeline de rĂ©sultats fusionnĂ©s (et donc de merge train) ne peut pas se lancer si la branche cible a divergĂ© au point de crĂ©er un conflit textuel. Il faut dâabord rebaser ou merger
maindans la MR. - Le train consomme des ressources. Chaque MR en file déclenche une pipeline complÚte, potentiellement recalculée à chaque échec en amont. Sur un projet avec beaucoup de MR concurrentes et des pipelines longues, surveillez la charge sur vos runners.
- Ce nâest pas un raccourci pour des tests bĂąclĂ©s. Le merge train protĂšge
maindes conflits sĂ©mantiques entre changements combinĂ©s ; il ne remplace pas une bonne couverture de tests dans chaque pipeline individuelle. - 20 pipelines parallĂšles par dĂ©faut. Sur un train trĂšs actif, cette limite (configurable depuis GitLab 19.0, avec un mode dâapplication stricte depuis 19.3) peut mettre en pause lâajout de nouvelles MR le temps que des places se libĂšrent.
đ Conclusion
Le merge train rĂ©sout un problĂšme que les pipelines de MR classiques, aussi bien conçues soient-elles, ne peuvent pas voir : la collision entre changements qui, pris sĂ©parĂ©ment, sont chacun irrĂ©prochables. En mettant les fusions en file et en testant le cumul avant de merger dans lâordre, GitLab garantit que main nâavance que par Ă©tapes dĂ©jĂ validĂ©es ensemble â et quâun Ă©chec isolĂ© ne bloque jamais tout le monde derriĂšre.
Si votre projet fusionne plusieurs MR par jour sur une Ă©quipe de plus de deux ou trois dĂ©veloppeurs, et que vous ĂȘtes sur un plan Premium ou Ultimate, câest une des fonctionnalitĂ©s GitLab CI/CD dont le rapport effort dâactivation / valeur est le plus favorable : deux cases Ă cocher, zĂ©ro ligne de YAML obligatoire.
đ Liens utiles
/faq
Questions fréquentes
Les merge trains sont-ils disponibles sur tous les plans GitLab ?
+
Non. Les merge trains sont une fonctionnalité Premium et Ultimate, disponible sur GitLab.com, en self-managed et en Dedicated. Le plan Free n'y a pas accÚs.
Quelle est la différence entre CI_MERGE_REQUEST_EVENT_TYPE detached, merged_result et merge_train ?
+
Ce sont les trois types de pipeline de merge request. « detached » teste uniquement la branche source. « merged_result » teste un commit spĂ©culatif combinant la branche source et la cible. « merge_train » fait la mĂȘme chose, mais en cumulant en plus les changements des merge requests placĂ©es avant dans le train.
Que se passe-t-il si le pipeline d'une MR échoue dans un merge train ?
+
GitLab retire cette merge request du train et relance immédiatement les pipelines de toutes les merge requests placées aprÚs elle, cette fois sans ses changements. Le train continue sans attendre de correction.
Faut-il activer autre chose avant les merge trains ?
+
Oui : les « merged results pipelines » (Pipelines for merged results) sont un prĂ©requis. Elles doivent ĂȘtre activĂ©es dans Settings > Merge requests > Merge options avant de pouvoir cocher « Enable merge trains ».