[{"data":1,"prerenderedAt":3086},["ShallowReactive",2],{"/fr-fr/blog/5-ways-gitlab-pipeline-logic-solves-real-engineering-problems":3,"navigation-fr-fr":2311,"banner-fr-fr":2733,"footer-fr-fr":2742,"blog-post-authors-fr-fr-Omid Khan":2983,"blog-related-posts-fr-fr-5-ways-gitlab-pipeline-logic-solves-real-engineering-problems":2998,"blog-promotions-fr-fr":3023,"next-steps-fr-fr":3077},{"id":4,"title":5,"authors":6,"body":8,"category":2290,"date":2291,"description":2292,"extension":2293,"externalUrl":2294,"featured":2295,"heroImage":2296,"meta":2297,"navigation":103,"path":2298,"seo":2299,"slug":2303,"stem":2304,"tags":2305,"template":2309,"updatedDate":2294,"__hash__":2310},"blogPosts/fr-fr/blog/5-ways-gitlab-pipeline-logic-solves-real-engineering-problems.md","5 modèles de pipeline GitLab pour résoudre vos enjeux d'ingénierie",[7],"Omid Khan",{"type":9,"value":10,"toc":2280},"minimark",[11,23,26,29,34,37,56,59,189,198,217,223,335,338,345,349,352,361,370,634,807,827,830,836,840,843,851,1277,1302,1305,1311,1315,1322,1325,1357,1360,1825,1831,1837,1843,1849,1855,1859,1866,1884,1887,2007,2010,2137,2147,2162,2172,2178,2182,2185,2196,2199,2203,2206,2252,2256,2259,2262,2265,2276],[12,13,14,15,22],"p",{},"La plupart des outils ",[16,17,21],"a",{"href":18,"rel":19,"title":20},"https://about.gitlab.com/fr-fr/topics/ci-cd/",[],"Qu'est-ce que le CI/CD ?","CI/CD"," savent exécuter un build et lancer un déploiement. La différence se fait lorsque vos besoins de livraison deviennent concrets : un monorepo avec une dizaine de services, des microservices répartis sur plusieurs dépôts, des déploiements vers des dizaines d'environnements, ou une équipe plateforme qui cherche à appliquer des normes sans devenir un goulot d'étranglement.",[12,24,25],{},"Le modèle d'exécution de pipelines de GitLab a été conçu pour cette complexité. Les pipelines parent-enfant, l'exécution du graphe orienté acyclique (DAG), la génération dynamique de pipelines, les déclencheurs multi-projets, les pipelines de merge request avec résultats fusionnés et les composants CI/CD répondent chacun à une catégorie distincte de problèmes. Parce qu'ils se combinent entre eux, la compréhension du modèle complet offre bien plus qu'une accélération du pipeline. Dans cet article, vous découvrirez cinq modèles dans lesquels les pipelines se distinguent, chacun associé à un scénario d'ingénierie concret avec la configuration correspondante.",[12,27,28],{},"Les configurations ci-dessous sont fournies à titre illustratif. Les scripts utilisent des commandes echo pour maintenir un rapport signal/bruit faible. Remplacez-les par vos véritables étapes de build, de test et de déploiement pour qu'elles soient prêtes à l'emploi.",[30,31,33],"h2",{"id":32},"_1-monorepos-pipelines-parent-enfant-et-exécution-du-dag","1. Monorepos : pipelines parent-enfant et exécution du DAG",[12,35,36],{},"Le problème : votre monorepo contient un frontend, un backend et un site de documentation. Chaque commit déclenche une reconstruction complète de l'ensemble, même lorsque seul un fichier README a été modifié.",[12,38,39,40,45,46,55],{},"GitLab résout ce problème grâce à deux fonctionnalités complémentaires : les ",[16,41,44],{"href":42,"rel":43},"https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#parent-child-pipelines",[],"pipelines parent-enfant"," (qui permettent à un pipeline de niveau supérieur de créer des sous-pipelines isolés) et l'",[16,47,50,51],{"href":48,"rel":49},"https://docs.gitlab.com/ci/yaml/#needs",[],"exécution du DAG via ",[52,53,54],"code",{},"needs"," (qui rompt le classement rigide étape par étape et permet aux jobs de démarrer dès que leurs dépendances sont terminées).",[12,57,58],{},"Un pipeline parent détecte les modifications et ne déclenche que les pipelines enfants concernés :",[60,61,66],"pre",{"className":62,"code":63,"language":64,"meta":65,"style":65},"language-yaml shiki shiki-themes github-light","# .gitlab-ci.yml\nstages:\n  - trigger\n\ntrigger-services:\n  stage: trigger\n  trigger:\n    include:\n      - local: '.gitlab/ci/api-service.yml'\n      - local: '.gitlab/ci/web-service.yml'\n      - local: '.gitlab/ci/worker-service.yml'\n    strategy: depend\n","yaml","",[52,67,68,77,88,98,105,113,124,132,140,154,166,178],{"__ignoreMap":65},[69,70,73],"span",{"class":71,"line":72},"line",1,[69,74,76],{"class":75},"sAwPA","# .gitlab-ci.yml\n",[69,78,80,84],{"class":71,"line":79},2,[69,81,83],{"class":82},"shJU0","stages",[69,85,87],{"class":86},"sgsFI",":\n",[69,89,91,94],{"class":71,"line":90},3,[69,92,93],{"class":86},"  - ",[69,95,97],{"class":96},"sYBdl","trigger\n",[69,99,101],{"class":71,"line":100},4,[69,102,104],{"emptyLinePlaceholder":103},true,"\n",[69,106,108,111],{"class":71,"line":107},5,[69,109,110],{"class":82},"trigger-services",[69,112,87],{"class":86},[69,114,116,119,122],{"class":71,"line":115},6,[69,117,118],{"class":82},"  stage",[69,120,121],{"class":86},": ",[69,123,97],{"class":96},[69,125,127,130],{"class":71,"line":126},7,[69,128,129],{"class":82},"  trigger",[69,131,87],{"class":86},[69,133,135,138],{"class":71,"line":134},8,[69,136,137],{"class":82},"    include",[69,139,87],{"class":86},[69,141,143,146,149,151],{"class":71,"line":142},9,[69,144,145],{"class":86},"      - ",[69,147,148],{"class":82},"local",[69,150,121],{"class":86},[69,152,153],{"class":96},"'.gitlab/ci/api-service.yml'\n",[69,155,157,159,161,163],{"class":71,"line":156},10,[69,158,145],{"class":86},[69,160,148],{"class":82},[69,162,121],{"class":86},[69,164,165],{"class":96},"'.gitlab/ci/web-service.yml'\n",[69,167,169,171,173,175],{"class":71,"line":168},11,[69,170,145],{"class":86},[69,172,148],{"class":82},[69,174,121],{"class":86},[69,176,177],{"class":96},"'.gitlab/ci/worker-service.yml'\n",[69,179,181,184,186],{"class":71,"line":180},12,[69,182,183],{"class":82},"    strategy",[69,185,121],{"class":86},[69,187,188],{"class":96},"depend\n",[12,190,191,192,197],{},"Chaque pipeline enfant est entièrement indépendant avec ses propres étapes, jobs et artefacts. Le pipeline parent attend la fin de l'ensemble via ",[16,193,196],{"href":194,"rel":195},"https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#wait-for-downstream-pipeline-to-complete",[],"strategy: depend",", ce qui vous donne un signal vert/rouge unique au niveau supérieur, avec une vue détaillée de chaque pipeline de service. Cette séparation organisationnelle est le gain le plus important pour les grandes équipes : chaque service est propriétaire de sa configuration de pipeline, les modifications d'une configuration n'entraînent pas l'échec d'une autre, et la complexité reste gérable à mesure que le dépôt grandit.",[12,199,200,201,209,210,213,214,216],{},"Un point important : lorsque vous ",[16,202,205,206],{"href":203,"rel":204},"https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#combine-multiple-child-pipeline-configuration-files",[],"transmettez plusieurs fichiers à un même ",[52,207,208],{},"trigger: include:",", GitLab les fusionne dans une seule configuration de pipeline enfant. Cela signifie que les jobs définis dans ces fichiers partagent le même contexte de pipeline et peuvent se référencer mutuellement avec ",[52,211,212],{},"needs:",", ce qui rend l'optimisation du DAG possible. Si vous les séparez dans des jobs de déclenchement distincts, chaque fichier constituerait son propre pipeline isolé, et les références ",[52,215,212],{}," entre fichiers ne fonctionneraient pas.",[12,218,219,220,222],{},"Combinez cette approche avec ",[52,221,212],{}," à l'intérieur de chaque pipeline enfant pour exécuter le DAG. Vos tests d'intégration peuvent démarrer dès que le build est terminé, sans attendre les autres jobs de la même étape.",[60,224,226],{"className":62,"code":225,"language":64,"meta":65,"style":65},"# .gitlab/ci/api-service.yml\nstages:\n  - build\n  - test\n\nbuild-api:\n  stage: build\n  script:\n    - echo \"Building API service\"\n\ntest-api:\n  stage: test\n  needs: [build-api]\n  script:\n    - echo \"Running API tests\"\n",[52,227,228,233,239,246,253,257,264,272,279,287,291,298,306,320,327],{"__ignoreMap":65},[69,229,230],{"class":71,"line":72},[69,231,232],{"class":75},"# .gitlab/ci/api-service.yml\n",[69,234,235,237],{"class":71,"line":79},[69,236,83],{"class":82},[69,238,87],{"class":86},[69,240,241,243],{"class":71,"line":90},[69,242,93],{"class":86},[69,244,245],{"class":96},"build\n",[69,247,248,250],{"class":71,"line":100},[69,249,93],{"class":86},[69,251,252],{"class":96},"test\n",[69,254,255],{"class":71,"line":107},[69,256,104],{"emptyLinePlaceholder":103},[69,258,259,262],{"class":71,"line":115},[69,260,261],{"class":82},"build-api",[69,263,87],{"class":86},[69,265,266,268,270],{"class":71,"line":126},[69,267,118],{"class":82},[69,269,121],{"class":86},[69,271,245],{"class":96},[69,273,274,277],{"class":71,"line":134},[69,275,276],{"class":82},"  script",[69,278,87],{"class":86},[69,280,281,284],{"class":71,"line":142},[69,282,283],{"class":86},"    - ",[69,285,286],{"class":96},"echo \"Building API service\"\n",[69,288,289],{"class":71,"line":156},[69,290,104],{"emptyLinePlaceholder":103},[69,292,293,296],{"class":71,"line":168},[69,294,295],{"class":82},"test-api",[69,297,87],{"class":86},[69,299,300,302,304],{"class":71,"line":180},[69,301,118],{"class":82},[69,303,121],{"class":86},[69,305,252],{"class":96},[69,307,309,312,315,317],{"class":71,"line":308},13,[69,310,311],{"class":82},"  needs",[69,313,314],{"class":86},": [",[69,316,261],{"class":96},[69,318,319],{"class":86},"]\n",[69,321,323,325],{"class":71,"line":322},14,[69,324,276],{"class":82},[69,326,87],{"class":86},[69,328,330,332],{"class":71,"line":329},15,[69,331,283],{"class":86},[69,333,334],{"class":96},"echo \"Running API tests\"\n",[12,336,337],{},"Pourquoi c'est important : les équipes qui disposent de monorepos volumineux constatent généralement des réductions significatives du temps d'exécution des pipelines après le passage à l'exécution du DAG, car les jobs n'attendent plus des tâches sans rapport dans la même étape. Les pipelines parent-enfant constituent la couche organisationnelle qui facilite la gestion de la configuration à mesure que le dépôt et l'équipe grandissent.",[12,339,340],{},[341,342],"img",{"alt":343,"src":344,"title":343},"Pipelines downstream locaux","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775738759/Blog/Imported/hackathon-fake-blog-post-s/image3_vwj3rz.png",[30,346,348],{"id":347},"_2-microservices-pipelines-multi-projets-inter-dépôts","2. Microservices : pipelines multi-projets inter-dépôts",[12,350,351],{},"Le problème : votre frontend se trouve dans un dépôt, et votre backend dans un autre. Lorsque l'équipe frontend livre une modification, elle n'a aucune visibilité sur les éventuelles défaillances du backend, et inversement.",[12,353,354,355,360],{},"Les ",[16,356,359],{"href":357,"rel":358},"https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#multi-project-pipelines",[],"pipelines multi-projets"," de GitLab permettent à un projet de déclencher un pipeline dans un projet totalement distinct et d'en attendre le résultat. Le projet déclencheur obtient un pipeline downstream lié directement dans sa propre vue de pipeline.",[12,362,363,364,369],{},"Le pipeline frontend construit un artefact de contrat d'API et le publie, puis déclenche le pipeline backend. Le backend récupère cet artefact directement via l'",[16,365,368],{"href":366,"rel":367},"https://docs.gitlab.com/api/jobs/#download-a-single-artifact-file-from-specific-tag-or-branch",[],"API Jobs"," et le valide avant de poursuivre. Si une modification incompatible est détectée, le pipeline backend échoue, tout comme le pipeline frontend.",[60,371,373],{"className":62,"code":372,"language":64,"meta":65,"style":65},"# frontend repo: .gitlab-ci.yml\nstages:\n  - build\n  - test\n  - trigger-backend\n\nbuild-frontend:\n  stage: build\n  script:\n    - echo \"Building frontend and generating API contract...\"\n    - mkdir -p dist\n    - |\n      echo '{\n        \"api_version\": \"v2\",\n        \"breaking_changes\": false\n      }' > dist/api-contract.json\n    - cat dist/api-contract.json\n  artifacts:\n    paths:\n      - dist/api-contract.json\n    expire_in: 1 hour\n\ntest-frontend:\n  stage: test\n  script:\n    - echo \"All frontend tests passed!\"\n\ntrigger-backend-pipeline:\n  stage: trigger-backend\n  trigger:\n    project: my-org/backend-service\n    branch: main\n    strategy: depend\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"main\"\n",[52,374,375,380,386,392,398,405,409,416,424,430,437,444,452,457,462,467,473,481,489,497,505,516,521,529,538,545,553,558,566,575,582,593,604,613,621],{"__ignoreMap":65},[69,376,377],{"class":71,"line":72},[69,378,379],{"class":75},"# frontend repo: .gitlab-ci.yml\n",[69,381,382,384],{"class":71,"line":79},[69,383,83],{"class":82},[69,385,87],{"class":86},[69,387,388,390],{"class":71,"line":90},[69,389,93],{"class":86},[69,391,245],{"class":96},[69,393,394,396],{"class":71,"line":100},[69,395,93],{"class":86},[69,397,252],{"class":96},[69,399,400,402],{"class":71,"line":107},[69,401,93],{"class":86},[69,403,404],{"class":96},"trigger-backend\n",[69,406,407],{"class":71,"line":115},[69,408,104],{"emptyLinePlaceholder":103},[69,410,411,414],{"class":71,"line":126},[69,412,413],{"class":82},"build-frontend",[69,415,87],{"class":86},[69,417,418,420,422],{"class":71,"line":134},[69,419,118],{"class":82},[69,421,121],{"class":86},[69,423,245],{"class":96},[69,425,426,428],{"class":71,"line":142},[69,427,276],{"class":82},[69,429,87],{"class":86},[69,431,432,434],{"class":71,"line":156},[69,433,283],{"class":86},[69,435,436],{"class":96},"echo \"Building frontend and generating API contract...\"\n",[69,438,439,441],{"class":71,"line":168},[69,440,283],{"class":86},[69,442,443],{"class":96},"mkdir -p dist\n",[69,445,446,448],{"class":71,"line":180},[69,447,283],{"class":86},[69,449,451],{"class":450},"sD7c4","|\n",[69,453,454],{"class":71,"line":308},[69,455,456],{"class":96},"      echo '{\n",[69,458,459],{"class":71,"line":322},[69,460,461],{"class":96},"        \"api_version\": \"v2\",\n",[69,463,464],{"class":71,"line":329},[69,465,466],{"class":96},"        \"breaking_changes\": false\n",[69,468,470],{"class":71,"line":469},16,[69,471,472],{"class":96},"      }' > dist/api-contract.json\n",[69,474,476,478],{"class":71,"line":475},17,[69,477,283],{"class":86},[69,479,480],{"class":96},"cat dist/api-contract.json\n",[69,482,484,487],{"class":71,"line":483},18,[69,485,486],{"class":82},"  artifacts",[69,488,87],{"class":86},[69,490,492,495],{"class":71,"line":491},19,[69,493,494],{"class":82},"    paths",[69,496,87],{"class":86},[69,498,500,502],{"class":71,"line":499},20,[69,501,145],{"class":86},[69,503,504],{"class":96},"dist/api-contract.json\n",[69,506,508,511,513],{"class":71,"line":507},21,[69,509,510],{"class":82},"    expire_in",[69,512,121],{"class":86},[69,514,515],{"class":96},"1 hour\n",[69,517,519],{"class":71,"line":518},22,[69,520,104],{"emptyLinePlaceholder":103},[69,522,524,527],{"class":71,"line":523},23,[69,525,526],{"class":82},"test-frontend",[69,528,87],{"class":86},[69,530,532,534,536],{"class":71,"line":531},24,[69,533,118],{"class":82},[69,535,121],{"class":86},[69,537,252],{"class":96},[69,539,541,543],{"class":71,"line":540},25,[69,542,276],{"class":82},[69,544,87],{"class":86},[69,546,548,550],{"class":71,"line":547},26,[69,549,283],{"class":86},[69,551,552],{"class":96},"echo \"All frontend tests passed!\"\n",[69,554,556],{"class":71,"line":555},27,[69,557,104],{"emptyLinePlaceholder":103},[69,559,561,564],{"class":71,"line":560},28,[69,562,563],{"class":82},"trigger-backend-pipeline",[69,565,87],{"class":86},[69,567,569,571,573],{"class":71,"line":568},29,[69,570,118],{"class":82},[69,572,121],{"class":86},[69,574,404],{"class":96},[69,576,578,580],{"class":71,"line":577},30,[69,579,129],{"class":82},[69,581,87],{"class":86},[69,583,585,588,590],{"class":71,"line":584},31,[69,586,587],{"class":82},"    project",[69,589,121],{"class":86},[69,591,592],{"class":96},"my-org/backend-service\n",[69,594,596,599,601],{"class":71,"line":595},32,[69,597,598],{"class":82},"    branch",[69,600,121],{"class":86},[69,602,603],{"class":96},"main\n",[69,605,607,609,611],{"class":71,"line":606},33,[69,608,183],{"class":82},[69,610,121],{"class":86},[69,612,188],{"class":96},[69,614,616,619],{"class":71,"line":615},34,[69,617,618],{"class":82},"  rules",[69,620,87],{"class":86},[69,622,624,626,629,631],{"class":71,"line":623},35,[69,625,283],{"class":86},[69,627,628],{"class":82},"if",[69,630,121],{"class":86},[69,632,633],{"class":96},"$CI_COMMIT_BRANCH == \"main\"\n",[60,635,637],{"className":62,"code":636,"language":64,"meta":65,"style":65},"# backend repo: .gitlab-ci.yml\nstages:\n  - build\n  - test\n\nbuild-backend:\n  stage: build\n  script:\n    - echo \"All backend tests passed!\"\n\nintegration-test:\n  stage: test\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"pipeline\"\n  script:\n    - echo \"Fetching API contract from frontend...\"\n    - |\n      curl --silent --fail \\\n        --header \"JOB-TOKEN: $CI_JOB_TOKEN\" \\\n        --output api-contract.json \\\n        \"${CI_API_V4_URL}/projects/${FRONTEND_PROJECT_ID}/jobs/artifacts/main/raw/dist/api-contract.json?job=build-frontend\"\n    - cat api-contract.json\n    - |\n      if grep -q '\"breaking_changes\": true' api-contract.json; then\n        echo \"FAIL: Breaking API changes detected - backend integration blocked!\"\n        exit 1\n      fi\n      echo \"PASS: API contract is compatible!\"\n",[52,638,639,644,650,656,662,666,673,681,687,694,698,705,713,719,730,736,743,749,754,759,764,769,776,782,787,792,797,802],{"__ignoreMap":65},[69,640,641],{"class":71,"line":72},[69,642,643],{"class":75},"# backend repo: .gitlab-ci.yml\n",[69,645,646,648],{"class":71,"line":79},[69,647,83],{"class":82},[69,649,87],{"class":86},[69,651,652,654],{"class":71,"line":90},[69,653,93],{"class":86},[69,655,245],{"class":96},[69,657,658,660],{"class":71,"line":100},[69,659,93],{"class":86},[69,661,252],{"class":96},[69,663,664],{"class":71,"line":107},[69,665,104],{"emptyLinePlaceholder":103},[69,667,668,671],{"class":71,"line":115},[69,669,670],{"class":82},"build-backend",[69,672,87],{"class":86},[69,674,675,677,679],{"class":71,"line":126},[69,676,118],{"class":82},[69,678,121],{"class":86},[69,680,245],{"class":96},[69,682,683,685],{"class":71,"line":134},[69,684,276],{"class":82},[69,686,87],{"class":86},[69,688,689,691],{"class":71,"line":142},[69,690,283],{"class":86},[69,692,693],{"class":96},"echo \"All backend tests passed!\"\n",[69,695,696],{"class":71,"line":156},[69,697,104],{"emptyLinePlaceholder":103},[69,699,700,703],{"class":71,"line":168},[69,701,702],{"class":82},"integration-test",[69,704,87],{"class":86},[69,706,707,709,711],{"class":71,"line":180},[69,708,118],{"class":82},[69,710,121],{"class":86},[69,712,252],{"class":96},[69,714,715,717],{"class":71,"line":308},[69,716,618],{"class":82},[69,718,87],{"class":86},[69,720,721,723,725,727],{"class":71,"line":322},[69,722,283],{"class":86},[69,724,628],{"class":82},[69,726,121],{"class":86},[69,728,729],{"class":96},"$CI_PIPELINE_SOURCE == \"pipeline\"\n",[69,731,732,734],{"class":71,"line":329},[69,733,276],{"class":82},[69,735,87],{"class":86},[69,737,738,740],{"class":71,"line":469},[69,739,283],{"class":86},[69,741,742],{"class":96},"echo \"Fetching API contract from frontend...\"\n",[69,744,745,747],{"class":71,"line":475},[69,746,283],{"class":86},[69,748,451],{"class":450},[69,750,751],{"class":71,"line":483},[69,752,753],{"class":96},"      curl --silent --fail \\\n",[69,755,756],{"class":71,"line":491},[69,757,758],{"class":96},"        --header \"JOB-TOKEN: $CI_JOB_TOKEN\" \\\n",[69,760,761],{"class":71,"line":499},[69,762,763],{"class":96},"        --output api-contract.json \\\n",[69,765,766],{"class":71,"line":507},[69,767,768],{"class":96},"        \"${CI_API_V4_URL}/projects/${FRONTEND_PROJECT_ID}/jobs/artifacts/main/raw/dist/api-contract.json?job=build-frontend\"\n",[69,770,771,773],{"class":71,"line":518},[69,772,283],{"class":86},[69,774,775],{"class":96},"cat api-contract.json\n",[69,777,778,780],{"class":71,"line":523},[69,779,283],{"class":86},[69,781,451],{"class":450},[69,783,784],{"class":71,"line":531},[69,785,786],{"class":96},"      if grep -q '\"breaking_changes\": true' api-contract.json; then\n",[69,788,789],{"class":71,"line":540},[69,790,791],{"class":96},"        echo \"FAIL: Breaking API changes detected - backend integration blocked!\"\n",[69,793,794],{"class":71,"line":547},[69,795,796],{"class":96},"        exit 1\n",[69,798,799],{"class":71,"line":555},[69,800,801],{"class":96},"      fi\n",[69,803,804],{"class":71,"line":560},[69,805,806],{"class":96},"      echo \"PASS: API contract is compatible!\"\n",[12,808,809,810,812,813,816,817,820,821,826],{},"Quelques points à noter dans cette configuration. Le job ",[52,811,702],{}," utilise ",[52,814,815],{},"$CI_PIPELINE_SOURCE == \"pipeline\""," pour s'assurer qu'il ne s'exécute que lorsqu'il est déclenché par un pipeline amont, et non lors d'un push direct sur le dépôt backend. L'identifiant du projet frontend est référencé via ",[52,818,819],{},"$FRONTEND_PROJECT_ID",", qui doit être défini comme ",[16,822,825],{"href":823,"rel":824},"https://docs.gitlab.com/ci/variables/",[],"variable CI/CD"," dans les paramètres du projet backend afin d'éviter de le coder en dur.",[12,828,829],{},"Pourquoi c'est important : les échecs inter-services qui ne se manifestaient auparavant qu'en production sont désormais détectés dans le pipeline. La dépendance entre services, auparavant invisible, devient visible, traçable et corrigeable.",[12,831,832],{},[341,833],{"alt":834,"src":835,"title":834},"Pipelines multi-projets","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775738762/Blog/Imported/hackathon-fake-blog-post-s/image4_h6mfsb.png",[30,837,839],{"id":838},"_3-déploiements-multilocataires-et-de-matrice-pipelines-enfants-dynamiques","3. Déploiements multilocataires et de matrice : pipelines enfants dynamiques",[12,841,842],{},"Le problème : vous déployez la même application vers 15 environnements clients, trois régions cloud ou encore des environnements de développement/préproduction/production. Mettre à jour une étape de déploiement sur l'ensemble de ces environnements un par un entraîne une dérive de configuration, tandis que créer un pipeline distinct pour chaque environnement est impossible à maintenir.",[12,844,354,845,850],{},[16,846,849],{"href":847,"rel":848},"https://docs.gitlab.com/ci/pipelines/downstream_pipelines/#dynamic-child-pipelines",[],"pipelines enfants dynamiques"," de GitLab permettent de générer un pipeline au moment de l'exécution. Un job exécute un script qui produit un fichier YAML, qui devient le pipeline de l'étape suivante. La structure même du pipeline devient une donnée.",[60,852,854],{"className":62,"code":853,"language":64,"meta":65,"style":65},"# .gitlab-ci.yml\nstages:\n  - generate\n  - trigger-environments\n\ngenerate-config:\n  stage: generate\n  script:\n    - |\n      # ENVIRONMENTS can be passed as a CI variable or read from a config file.\n      # Default to dev, staging, prod if not set.\n      ENVIRONMENTS=${ENVIRONMENTS:-\"dev staging prod\"}\n      for ENV in $ENVIRONMENTS; do\n        cat > ${ENV}-pipeline.yml \u003C\u003C EOF\n      stages:\n        - deploy\n        - verify\n      deploy-${ENV}:\n        stage: deploy\n        script:\n          - echo \"Deploying to ${ENV} environment\"\n      verify-${ENV}:\n        stage: verify\n        script:\n          - echo \"Running smoke tests on ${ENV}\"\n      EOF\n      done\n  artifacts:\n    paths:\n      - \"*.yml\"\n    exclude:\n      - \".gitlab-ci.yml\"\n\n.trigger-template:\n  stage: trigger-environments\n  trigger:\n    strategy: depend\n\ntrigger-dev:\n  extends: .trigger-template\n  trigger:\n    include:\n      - artifact: dev-pipeline.yml\n        job: generate-config\n\ntrigger-staging:\n  extends: .trigger-template\n  needs: [trigger-dev]\n  trigger:\n    include:\n      - artifact: staging-pipeline.yml\n        job: generate-config\n\ntrigger-prod:\n  extends: .trigger-template\n  needs: [trigger-staging]\n  trigger:\n    include:\n      - artifact: prod-pipeline.yml\n        job: generate-config\n  when: manual\n",[52,855,856,860,866,873,880,884,891,899,905,911,916,921,926,931,936,941,946,951,956,961,966,971,976,981,985,990,995,1000,1006,1012,1019,1026,1033,1037,1044,1052,1059,1068,1073,1081,1092,1099,1106,1119,1130,1135,1143,1152,1163,1170,1177,1189,1198,1203,1211,1220,1231,1238,1245,1257,1266],{"__ignoreMap":65},[69,857,858],{"class":71,"line":72},[69,859,76],{"class":75},[69,861,862,864],{"class":71,"line":79},[69,863,83],{"class":82},[69,865,87],{"class":86},[69,867,868,870],{"class":71,"line":90},[69,869,93],{"class":86},[69,871,872],{"class":96},"generate\n",[69,874,875,877],{"class":71,"line":100},[69,876,93],{"class":86},[69,878,879],{"class":96},"trigger-environments\n",[69,881,882],{"class":71,"line":107},[69,883,104],{"emptyLinePlaceholder":103},[69,885,886,889],{"class":71,"line":115},[69,887,888],{"class":82},"generate-config",[69,890,87],{"class":86},[69,892,893,895,897],{"class":71,"line":126},[69,894,118],{"class":82},[69,896,121],{"class":86},[69,898,872],{"class":96},[69,900,901,903],{"class":71,"line":134},[69,902,276],{"class":82},[69,904,87],{"class":86},[69,906,907,909],{"class":71,"line":142},[69,908,283],{"class":86},[69,910,451],{"class":450},[69,912,913],{"class":71,"line":156},[69,914,915],{"class":96},"      # ENVIRONMENTS can be passed as a CI variable or read from a config file.\n",[69,917,918],{"class":71,"line":168},[69,919,920],{"class":96},"      # Default to dev, staging, prod if not set.\n",[69,922,923],{"class":71,"line":180},[69,924,925],{"class":96},"      ENVIRONMENTS=${ENVIRONMENTS:-\"dev staging prod\"}\n",[69,927,928],{"class":71,"line":308},[69,929,930],{"class":96},"      for ENV in $ENVIRONMENTS; do\n",[69,932,933],{"class":71,"line":322},[69,934,935],{"class":96},"        cat > ${ENV}-pipeline.yml \u003C\u003C EOF\n",[69,937,938],{"class":71,"line":329},[69,939,940],{"class":96},"      stages:\n",[69,942,943],{"class":71,"line":469},[69,944,945],{"class":96},"        - deploy\n",[69,947,948],{"class":71,"line":475},[69,949,950],{"class":96},"        - verify\n",[69,952,953],{"class":71,"line":483},[69,954,955],{"class":96},"      deploy-${ENV}:\n",[69,957,958],{"class":71,"line":491},[69,959,960],{"class":96},"        stage: deploy\n",[69,962,963],{"class":71,"line":499},[69,964,965],{"class":96},"        script:\n",[69,967,968],{"class":71,"line":507},[69,969,970],{"class":96},"          - echo \"Deploying to ${ENV} environment\"\n",[69,972,973],{"class":71,"line":518},[69,974,975],{"class":96},"      verify-${ENV}:\n",[69,977,978],{"class":71,"line":523},[69,979,980],{"class":96},"        stage: verify\n",[69,982,983],{"class":71,"line":531},[69,984,965],{"class":96},[69,986,987],{"class":71,"line":540},[69,988,989],{"class":96},"          - echo \"Running smoke tests on ${ENV}\"\n",[69,991,992],{"class":71,"line":547},[69,993,994],{"class":96},"      EOF\n",[69,996,997],{"class":71,"line":555},[69,998,999],{"class":96},"      done\n",[69,1001,1002,1004],{"class":71,"line":560},[69,1003,486],{"class":82},[69,1005,87],{"class":86},[69,1007,1008,1010],{"class":71,"line":568},[69,1009,494],{"class":82},[69,1011,87],{"class":86},[69,1013,1014,1016],{"class":71,"line":577},[69,1015,145],{"class":86},[69,1017,1018],{"class":96},"\"*.yml\"\n",[69,1020,1021,1024],{"class":71,"line":584},[69,1022,1023],{"class":82},"    exclude",[69,1025,87],{"class":86},[69,1027,1028,1030],{"class":71,"line":595},[69,1029,145],{"class":86},[69,1031,1032],{"class":96},"\".gitlab-ci.yml\"\n",[69,1034,1035],{"class":71,"line":606},[69,1036,104],{"emptyLinePlaceholder":103},[69,1038,1039,1042],{"class":71,"line":615},[69,1040,1041],{"class":82},".trigger-template",[69,1043,87],{"class":86},[69,1045,1046,1048,1050],{"class":71,"line":623},[69,1047,118],{"class":82},[69,1049,121],{"class":86},[69,1051,879],{"class":96},[69,1053,1055,1057],{"class":71,"line":1054},36,[69,1056,129],{"class":82},[69,1058,87],{"class":86},[69,1060,1062,1064,1066],{"class":71,"line":1061},37,[69,1063,183],{"class":82},[69,1065,121],{"class":86},[69,1067,188],{"class":96},[69,1069,1071],{"class":71,"line":1070},38,[69,1072,104],{"emptyLinePlaceholder":103},[69,1074,1076,1079],{"class":71,"line":1075},39,[69,1077,1078],{"class":82},"trigger-dev",[69,1080,87],{"class":86},[69,1082,1084,1087,1089],{"class":71,"line":1083},40,[69,1085,1086],{"class":82},"  extends",[69,1088,121],{"class":86},[69,1090,1091],{"class":96},".trigger-template\n",[69,1093,1095,1097],{"class":71,"line":1094},41,[69,1096,129],{"class":82},[69,1098,87],{"class":86},[69,1100,1102,1104],{"class":71,"line":1101},42,[69,1103,137],{"class":82},[69,1105,87],{"class":86},[69,1107,1109,1111,1114,1116],{"class":71,"line":1108},43,[69,1110,145],{"class":86},[69,1112,1113],{"class":82},"artifact",[69,1115,121],{"class":86},[69,1117,1118],{"class":96},"dev-pipeline.yml\n",[69,1120,1122,1125,1127],{"class":71,"line":1121},44,[69,1123,1124],{"class":82},"        job",[69,1126,121],{"class":86},[69,1128,1129],{"class":96},"generate-config\n",[69,1131,1133],{"class":71,"line":1132},45,[69,1134,104],{"emptyLinePlaceholder":103},[69,1136,1138,1141],{"class":71,"line":1137},46,[69,1139,1140],{"class":82},"trigger-staging",[69,1142,87],{"class":86},[69,1144,1146,1148,1150],{"class":71,"line":1145},47,[69,1147,1086],{"class":82},[69,1149,121],{"class":86},[69,1151,1091],{"class":96},[69,1153,1155,1157,1159,1161],{"class":71,"line":1154},48,[69,1156,311],{"class":82},[69,1158,314],{"class":86},[69,1160,1078],{"class":96},[69,1162,319],{"class":86},[69,1164,1166,1168],{"class":71,"line":1165},49,[69,1167,129],{"class":82},[69,1169,87],{"class":86},[69,1171,1173,1175],{"class":71,"line":1172},50,[69,1174,137],{"class":82},[69,1176,87],{"class":86},[69,1178,1180,1182,1184,1186],{"class":71,"line":1179},51,[69,1181,145],{"class":86},[69,1183,1113],{"class":82},[69,1185,121],{"class":86},[69,1187,1188],{"class":96},"staging-pipeline.yml\n",[69,1190,1192,1194,1196],{"class":71,"line":1191},52,[69,1193,1124],{"class":82},[69,1195,121],{"class":86},[69,1197,1129],{"class":96},[69,1199,1201],{"class":71,"line":1200},53,[69,1202,104],{"emptyLinePlaceholder":103},[69,1204,1206,1209],{"class":71,"line":1205},54,[69,1207,1208],{"class":82},"trigger-prod",[69,1210,87],{"class":86},[69,1212,1214,1216,1218],{"class":71,"line":1213},55,[69,1215,1086],{"class":82},[69,1217,121],{"class":86},[69,1219,1091],{"class":96},[69,1221,1223,1225,1227,1229],{"class":71,"line":1222},56,[69,1224,311],{"class":82},[69,1226,314],{"class":86},[69,1228,1140],{"class":96},[69,1230,319],{"class":86},[69,1232,1234,1236],{"class":71,"line":1233},57,[69,1235,129],{"class":82},[69,1237,87],{"class":86},[69,1239,1241,1243],{"class":71,"line":1240},58,[69,1242,137],{"class":82},[69,1244,87],{"class":86},[69,1246,1248,1250,1252,1254],{"class":71,"line":1247},59,[69,1249,145],{"class":86},[69,1251,1113],{"class":82},[69,1253,121],{"class":86},[69,1255,1256],{"class":96},"prod-pipeline.yml\n",[69,1258,1260,1262,1264],{"class":71,"line":1259},60,[69,1261,1124],{"class":82},[69,1263,121],{"class":86},[69,1265,1129],{"class":96},[69,1267,1269,1272,1274],{"class":71,"line":1268},61,[69,1270,1271],{"class":82},"  when",[69,1273,121],{"class":86},[69,1275,1276],{"class":96},"manual\n",[12,1278,1279,1280,1283,1284,1289,1290,1292,1293,1295,1296,1301],{},"Le script de génération parcourt une variable ",[52,1281,1282],{},"ENVIRONMENTS"," plutôt que de coder en dur chaque environnement séparément. Transmettez une liste différente via une variable CI ou lisez-la depuis un fichier de configuration, et le pipeline s'adapte sans toucher au fichier YAML. Les jobs de déclenchement utilisent ",[16,1285,1288],{"href":1286,"rel":1287},"https://docs.gitlab.com/ci/yaml/#extends",[],"extends:"," pour hériter de la configuration partagée de ",[52,1291,1041],{},", de sorte que ",[52,1294,196],{}," est défini une seule fois au lieu d'être répété sur chaque job de déclenchement. Pour ajouter un nouvel environnement, il suffit de mettre à jour la variable, sans dupliquer la configuration du pipeline. Ajoutez ",[16,1297,1300],{"href":1298,"rel":1299},"https://docs.gitlab.com/ci/yaml/#when",[],"when: manual"," au déclencheur de production pour obtenir une porte de validation intégrée directement dans le graphe du pipeline.",[12,1303,1304],{},"Pourquoi c'est important : les entreprises SaaS et les équipes plateforme utilisent ce modèle pour gérer des dizaines d'environnements sans dupliquer la logique de pipeline. La structure du pipeline elle-même reste simple à mesure que la matrice de déploiement évolue.",[12,1306,1307],{},[341,1308],{"alt":1309,"src":1310,"title":1309},"Pipeline dynamique","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775738765/Blog/Imported/hackathon-fake-blog-post-s/image7_wr0kx2.png",[30,1312,1314],{"id":1313},"_4-livraison-axée-sur-les-merge-requests-pipelines-de-merge-request-résultats-fusionnés-et-routage-par-workflow","4. Livraison axée sur les merge requests : pipelines de merge request, résultats fusionnés et routage par workflow",[12,1316,1317,1318,1321],{},"Le problème : votre pipeline s'exécute à chaque push sur chaque branche. Des tests coûteux s'exécutent sur des branches de fonctionnalité qui ne seront jamais fusionnées. Parallèlement, vous n'avez aucune garantie que ce que vous avez testé correspond réellement à ce qui arrivera sur la branche ",[52,1319,1320],{},"main"," après le merge.",[12,1323,1324],{},"GitLab propose trois fonctionnalités imbriquées qui résolvent ensemble ce problème :",[1326,1327,1328,1337,1345],"ul",{},[1329,1330,354,1331,1336],"li",{},[16,1332,1335],{"href":1333,"rel":1334},"https://docs.gitlab.com/ci/pipelines/merge_request_pipelines/",[],"pipelines de merge request"," ne s'exécutent que lorsqu'une merge request existe, et non à chaque push de branche. Cette approche à elle seule élimine une quantité significative de ressources gaspillées.",[1329,1338,354,1339,1344],{},[16,1340,1343],{"href":1341,"rel":1342},"https://docs.gitlab.com/ci/pipelines/merged_results_pipelines/",[],"pipelines à résultats fusionnés"," vont plus loin. GitLab crée un commit de merge temporaire (votre branche plus la branche cible actuelle) et exécute le pipeline sur ce résultat. Vous testez ce qui existera réellement après le merge, et non simplement votre branche de manière isolée.",[1329,1346,354,1347,1352,1353,1356],{},[16,1348,1351],{"href":1349,"rel":1350},"https://docs.gitlab.com/ci/yaml/workflow/",[],"règles de workflow"," vous permettent de définir exactement quel type de pipeline s'exécute dans quelles conditions et de supprimer tout le reste. La protection ",[52,1354,1355],{},"$CI_OPEN_MERGE_REQUESTS"," ci-dessous empêche le déclenchement simultané de pipelines en double pour une branche et sa merge request ouverte.",[12,1358,1359],{},"Avec ces trois fonctionnalités combinées, voici à quoi ressemble un pipeline à niveaux :",[60,1361,1363],{"className":62,"code":1362,"language":64,"meta":65,"style":65},"# .gitlab-ci.yml\nworkflow:\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS\n      when: never\n    - if: $CI_COMMIT_BRANCH\n    - if: $CI_PIPELINE_SOURCE == \"schedule\"\n\nstages:\n  - fast-checks\n  - expensive-tests\n  - deploy\n\nlint-code:\n  stage: fast-checks\n  script:\n    - echo \"Running linter\"\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"push\"\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH == \"main\"\n\nunit-tests:\n  stage: fast-checks\n  script:\n    - echo \"Running unit tests\"\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"push\"\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH == \"main\"\n\nintegration-tests:\n  stage: expensive-tests\n  script:\n    - echo \"Running integration tests (15 min)\"\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH == \"main\"\n\ne2e-tests:\n  stage: expensive-tests\n  script:\n    - echo \"Running E2E tests (30 min)\"\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"merge_request_event\"\n    - if: $CI_COMMIT_BRANCH == \"main\"\n\nnightly-comprehensive-scan:\n  stage: expensive-tests\n  script:\n    - echo \"Running full nightly suite (2 hours)\"\n  rules:\n    - if: $CI_PIPELINE_SOURCE == \"schedule\"\n\ndeploy-production:\n  stage: deploy\n  script:\n    - echo \"Deploying to production\"\n  rules:\n    - if: $CI_COMMIT_BRANCH == \"main\"\n      when: manual\n",[52,1364,1365,1369,1376,1382,1393,1404,1414,1425,1436,1440,1446,1453,1460,1467,1471,1478,1486,1492,1499,1505,1516,1526,1536,1540,1547,1555,1561,1568,1574,1584,1594,1604,1608,1615,1623,1629,1636,1642,1652,1662,1666,1673,1681,1687,1694,1700,1710,1720,1724,1731,1739,1745,1752,1758,1768,1772,1779,1787,1793,1800,1806,1816],{"__ignoreMap":65},[69,1366,1367],{"class":71,"line":72},[69,1368,76],{"class":75},[69,1370,1371,1374],{"class":71,"line":79},[69,1372,1373],{"class":82},"workflow",[69,1375,87],{"class":86},[69,1377,1378,1380],{"class":71,"line":90},[69,1379,618],{"class":82},[69,1381,87],{"class":86},[69,1383,1384,1386,1388,1390],{"class":71,"line":100},[69,1385,283],{"class":86},[69,1387,628],{"class":82},[69,1389,121],{"class":86},[69,1391,1392],{"class":96},"$CI_PIPELINE_SOURCE == \"merge_request_event\"\n",[69,1394,1395,1397,1399,1401],{"class":71,"line":107},[69,1396,283],{"class":86},[69,1398,628],{"class":82},[69,1400,121],{"class":86},[69,1402,1403],{"class":96},"$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS\n",[69,1405,1406,1409,1411],{"class":71,"line":115},[69,1407,1408],{"class":82},"      when",[69,1410,121],{"class":86},[69,1412,1413],{"class":96},"never\n",[69,1415,1416,1418,1420,1422],{"class":71,"line":126},[69,1417,283],{"class":86},[69,1419,628],{"class":82},[69,1421,121],{"class":86},[69,1423,1424],{"class":96},"$CI_COMMIT_BRANCH\n",[69,1426,1427,1429,1431,1433],{"class":71,"line":134},[69,1428,283],{"class":86},[69,1430,628],{"class":82},[69,1432,121],{"class":86},[69,1434,1435],{"class":96},"$CI_PIPELINE_SOURCE == \"schedule\"\n",[69,1437,1438],{"class":71,"line":142},[69,1439,104],{"emptyLinePlaceholder":103},[69,1441,1442,1444],{"class":71,"line":156},[69,1443,83],{"class":82},[69,1445,87],{"class":86},[69,1447,1448,1450],{"class":71,"line":168},[69,1449,93],{"class":86},[69,1451,1452],{"class":96},"fast-checks\n",[69,1454,1455,1457],{"class":71,"line":180},[69,1456,93],{"class":86},[69,1458,1459],{"class":96},"expensive-tests\n",[69,1461,1462,1464],{"class":71,"line":308},[69,1463,93],{"class":86},[69,1465,1466],{"class":96},"deploy\n",[69,1468,1469],{"class":71,"line":322},[69,1470,104],{"emptyLinePlaceholder":103},[69,1472,1473,1476],{"class":71,"line":329},[69,1474,1475],{"class":82},"lint-code",[69,1477,87],{"class":86},[69,1479,1480,1482,1484],{"class":71,"line":469},[69,1481,118],{"class":82},[69,1483,121],{"class":86},[69,1485,1452],{"class":96},[69,1487,1488,1490],{"class":71,"line":475},[69,1489,276],{"class":82},[69,1491,87],{"class":86},[69,1493,1494,1496],{"class":71,"line":483},[69,1495,283],{"class":86},[69,1497,1498],{"class":96},"echo \"Running linter\"\n",[69,1500,1501,1503],{"class":71,"line":491},[69,1502,618],{"class":82},[69,1504,87],{"class":86},[69,1506,1507,1509,1511,1513],{"class":71,"line":499},[69,1508,283],{"class":86},[69,1510,628],{"class":82},[69,1512,121],{"class":86},[69,1514,1515],{"class":96},"$CI_PIPELINE_SOURCE == \"push\"\n",[69,1517,1518,1520,1522,1524],{"class":71,"line":507},[69,1519,283],{"class":86},[69,1521,628],{"class":82},[69,1523,121],{"class":86},[69,1525,1392],{"class":96},[69,1527,1528,1530,1532,1534],{"class":71,"line":518},[69,1529,283],{"class":86},[69,1531,628],{"class":82},[69,1533,121],{"class":86},[69,1535,633],{"class":96},[69,1537,1538],{"class":71,"line":523},[69,1539,104],{"emptyLinePlaceholder":103},[69,1541,1542,1545],{"class":71,"line":531},[69,1543,1544],{"class":82},"unit-tests",[69,1546,87],{"class":86},[69,1548,1549,1551,1553],{"class":71,"line":540},[69,1550,118],{"class":82},[69,1552,121],{"class":86},[69,1554,1452],{"class":96},[69,1556,1557,1559],{"class":71,"line":547},[69,1558,276],{"class":82},[69,1560,87],{"class":86},[69,1562,1563,1565],{"class":71,"line":555},[69,1564,283],{"class":86},[69,1566,1567],{"class":96},"echo \"Running unit tests\"\n",[69,1569,1570,1572],{"class":71,"line":560},[69,1571,618],{"class":82},[69,1573,87],{"class":86},[69,1575,1576,1578,1580,1582],{"class":71,"line":568},[69,1577,283],{"class":86},[69,1579,628],{"class":82},[69,1581,121],{"class":86},[69,1583,1515],{"class":96},[69,1585,1586,1588,1590,1592],{"class":71,"line":577},[69,1587,283],{"class":86},[69,1589,628],{"class":82},[69,1591,121],{"class":86},[69,1593,1392],{"class":96},[69,1595,1596,1598,1600,1602],{"class":71,"line":584},[69,1597,283],{"class":86},[69,1599,628],{"class":82},[69,1601,121],{"class":86},[69,1603,633],{"class":96},[69,1605,1606],{"class":71,"line":595},[69,1607,104],{"emptyLinePlaceholder":103},[69,1609,1610,1613],{"class":71,"line":606},[69,1611,1612],{"class":82},"integration-tests",[69,1614,87],{"class":86},[69,1616,1617,1619,1621],{"class":71,"line":615},[69,1618,118],{"class":82},[69,1620,121],{"class":86},[69,1622,1459],{"class":96},[69,1624,1625,1627],{"class":71,"line":623},[69,1626,276],{"class":82},[69,1628,87],{"class":86},[69,1630,1631,1633],{"class":71,"line":1054},[69,1632,283],{"class":86},[69,1634,1635],{"class":96},"echo \"Running integration tests (15 min)\"\n",[69,1637,1638,1640],{"class":71,"line":1061},[69,1639,618],{"class":82},[69,1641,87],{"class":86},[69,1643,1644,1646,1648,1650],{"class":71,"line":1070},[69,1645,283],{"class":86},[69,1647,628],{"class":82},[69,1649,121],{"class":86},[69,1651,1392],{"class":96},[69,1653,1654,1656,1658,1660],{"class":71,"line":1075},[69,1655,283],{"class":86},[69,1657,628],{"class":82},[69,1659,121],{"class":86},[69,1661,633],{"class":96},[69,1663,1664],{"class":71,"line":1083},[69,1665,104],{"emptyLinePlaceholder":103},[69,1667,1668,1671],{"class":71,"line":1094},[69,1669,1670],{"class":82},"e2e-tests",[69,1672,87],{"class":86},[69,1674,1675,1677,1679],{"class":71,"line":1101},[69,1676,118],{"class":82},[69,1678,121],{"class":86},[69,1680,1459],{"class":96},[69,1682,1683,1685],{"class":71,"line":1108},[69,1684,276],{"class":82},[69,1686,87],{"class":86},[69,1688,1689,1691],{"class":71,"line":1121},[69,1690,283],{"class":86},[69,1692,1693],{"class":96},"echo \"Running E2E tests (30 min)\"\n",[69,1695,1696,1698],{"class":71,"line":1132},[69,1697,618],{"class":82},[69,1699,87],{"class":86},[69,1701,1702,1704,1706,1708],{"class":71,"line":1137},[69,1703,283],{"class":86},[69,1705,628],{"class":82},[69,1707,121],{"class":86},[69,1709,1392],{"class":96},[69,1711,1712,1714,1716,1718],{"class":71,"line":1145},[69,1713,283],{"class":86},[69,1715,628],{"class":82},[69,1717,121],{"class":86},[69,1719,633],{"class":96},[69,1721,1722],{"class":71,"line":1154},[69,1723,104],{"emptyLinePlaceholder":103},[69,1725,1726,1729],{"class":71,"line":1165},[69,1727,1728],{"class":82},"nightly-comprehensive-scan",[69,1730,87],{"class":86},[69,1732,1733,1735,1737],{"class":71,"line":1172},[69,1734,118],{"class":82},[69,1736,121],{"class":86},[69,1738,1459],{"class":96},[69,1740,1741,1743],{"class":71,"line":1179},[69,1742,276],{"class":82},[69,1744,87],{"class":86},[69,1746,1747,1749],{"class":71,"line":1191},[69,1748,283],{"class":86},[69,1750,1751],{"class":96},"echo \"Running full nightly suite (2 hours)\"\n",[69,1753,1754,1756],{"class":71,"line":1200},[69,1755,618],{"class":82},[69,1757,87],{"class":86},[69,1759,1760,1762,1764,1766],{"class":71,"line":1205},[69,1761,283],{"class":86},[69,1763,628],{"class":82},[69,1765,121],{"class":86},[69,1767,1435],{"class":96},[69,1769,1770],{"class":71,"line":1213},[69,1771,104],{"emptyLinePlaceholder":103},[69,1773,1774,1777],{"class":71,"line":1222},[69,1775,1776],{"class":82},"deploy-production",[69,1778,87],{"class":86},[69,1780,1781,1783,1785],{"class":71,"line":1233},[69,1782,118],{"class":82},[69,1784,121],{"class":86},[69,1786,1466],{"class":96},[69,1788,1789,1791],{"class":71,"line":1240},[69,1790,276],{"class":82},[69,1792,87],{"class":86},[69,1794,1795,1797],{"class":71,"line":1247},[69,1796,283],{"class":86},[69,1798,1799],{"class":96},"echo \"Deploying to production\"\n",[69,1801,1802,1804],{"class":71,"line":1259},[69,1803,618],{"class":82},[69,1805,87],{"class":86},[69,1807,1808,1810,1812,1814],{"class":71,"line":1268},[69,1809,283],{"class":86},[69,1811,628],{"class":82},[69,1813,121],{"class":86},[69,1815,633],{"class":96},[69,1817,1819,1821,1823],{"class":71,"line":1818},62,[69,1820,1408],{"class":82},[69,1822,121],{"class":86},[69,1824,1276],{"class":96},[12,1826,1827,1828,1830],{},"Avec cette configuration, le pipeline se comporte différemment selon le contexte. Un push vers une branche de fonctionnalité sans merge request ouverte n'exécute que l’analyse du code et les tests unitaires. Dès qu'une merge request est ouverte, les règles de workflow passent d'un pipeline de branche à un pipeline de merge request, et la suite complète d'intégration et de tests de bout en bout s'exécute sur le résultat fusionné. Le merge vers la branche ",[52,1829,1320],{}," met en file d'attente un déploiement en production manuel. Une planification nocturne exécute le scan complet une seule fois, et non à chaque commit.",[12,1832,1833,1834,1836],{},"Pourquoi c'est important : les équipes réduisent leurs coûts CI de manière significative avec ce modèle, non pas en exécutant moins de tests, mais en exécutant les bons tests au bon moment. Les pipelines à résultats fusionnés détectent les bogues qui n'apparaissent qu'après un merge, avant même qu'ils n'atteignent la branche ",[52,1835,1320],{},".",[12,1838,1839],{},[341,1840],{"alt":1841,"src":1842,"title":1841},"Pipelines conditionnels (dans une branche sans merge request)","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775738768/Blog/Imported/hackathon-fake-blog-post-s/image6_dnfcny.png",[12,1844,1845],{},[341,1846],{"alt":1847,"src":1848,"title":1847},"Pipelines conditionnels (dans une merge request)","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775738772/Blog/Imported/hackathon-fake-blog-post-s/image1_wyiafu.png",[12,1850,1851],{},[341,1852],{"alt":1853,"src":1854,"title":1853},"Pipelines conditionnels (branche principale)","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775738774/Blog/Imported/hackathon-fake-blog-post-s/image5_r6lkfd.png",[30,1856,1858],{"id":1857},"_5-pipelines-gouvernés-composants-cicd","5. Pipelines gouvernés : composants CI/CD",[12,1860,1861,1862,1865],{},"Le problème : votre équipe plateforme a défini la bonne manière de compiler, tester et déployer. Mais chaque équipe possède son propre fichier ",[52,1863,1864],{},".gitlab-ci.yml"," avec des variations subtiles. Les scans de sécurité sont ignorés. Les normes de déploiement subissent des dérives de configuration. Les audits deviennent trop complexes.",[12,1867,354,1868,1873,1874,1877,1878,1883],{},[16,1869,1872],{"href":1870,"rel":1871},"https://docs.gitlab.com/ci/components/",[],"composants CI/CD"," de GitLab permettent aux équipes plateforme de publier des composants de pipeline versionnés et réutilisables. Les équipes applicatives les utilisent avec une seule ligne ",[52,1875,1876],{},"include:"," et des paramètres facultatifs : pas de copier-coller, pas de dérive. Les composants sont consultables via le ",[16,1879,1882],{"href":1880,"rel":1881},"https://docs.gitlab.com/ci/components/#cicd-catalog",[],"catalogue CI/CD",", ce qui permet aux équipes de trouver et d'adopter des composants approuvés sans avoir à passer par l'équipe plateforme.",[12,1885,1886],{},"Voici la définition d'un composant issu d'une bibliothèque partagée :",[60,1888,1890],{"className":62,"code":1889,"language":64,"meta":65,"style":65},"# templates/deploy.yml\nspec:\n  inputs:\n    stage:\n      default: deploy\n    environment:\n      default: production\n---\ndeploy-job:\n  stage: $[[ inputs.stage ]]\n  script:\n    - echo \"Deploying $APP_NAME to $[[ inputs.environment ]]\"\n    - echo \"Deploy URL: $DEPLOY_URL\"\n  environment:\n    name: $[[ inputs.environment ]]\n",[52,1891,1892,1897,1904,1911,1918,1927,1934,1943,1949,1956,1965,1971,1978,1990,1997],{"__ignoreMap":65},[69,1893,1894],{"class":71,"line":72},[69,1895,1896],{"class":75},"# templates/deploy.yml\n",[69,1898,1899,1902],{"class":71,"line":79},[69,1900,1901],{"class":82},"spec",[69,1903,87],{"class":86},[69,1905,1906,1909],{"class":71,"line":90},[69,1907,1908],{"class":82},"  inputs",[69,1910,87],{"class":86},[69,1912,1913,1916],{"class":71,"line":100},[69,1914,1915],{"class":82},"    stage",[69,1917,87],{"class":86},[69,1919,1920,1923,1925],{"class":71,"line":107},[69,1921,1922],{"class":82},"      default",[69,1924,121],{"class":86},[69,1926,1466],{"class":96},[69,1928,1929,1932],{"class":71,"line":115},[69,1930,1931],{"class":82},"    environment",[69,1933,87],{"class":86},[69,1935,1936,1938,1940],{"class":71,"line":126},[69,1937,1922],{"class":82},[69,1939,121],{"class":86},[69,1941,1942],{"class":96},"production\n",[69,1944,1945],{"class":71,"line":134},[69,1946,1948],{"class":1947},"s7eDp","---\n",[69,1950,1951,1954],{"class":71,"line":142},[69,1952,1953],{"class":82},"deploy-job",[69,1955,87],{"class":86},[69,1957,1958,1960,1962],{"class":71,"line":156},[69,1959,118],{"class":82},[69,1961,121],{"class":86},[69,1963,1964],{"class":96},"$[[ inputs.stage ]]\n",[69,1966,1967,1969],{"class":71,"line":168},[69,1968,276],{"class":82},[69,1970,87],{"class":86},[69,1972,1973,1975],{"class":71,"line":180},[69,1974,283],{"class":86},[69,1976,1977],{"class":96},"echo \"Deploying $APP_NAME to $[[ inputs.environment ]]\"\n",[69,1979,1980,1982,1985,1987],{"class":71,"line":308},[69,1981,283],{"class":86},[69,1983,1984],{"class":82},"echo \"Deploy URL",[69,1986,121],{"class":86},[69,1988,1989],{"class":96},"$DEPLOY_URL\"\n",[69,1991,1992,1995],{"class":71,"line":322},[69,1993,1994],{"class":82},"  environment",[69,1996,87],{"class":86},[69,1998,1999,2002,2004],{"class":71,"line":329},[69,2000,2001],{"class":82},"    name",[69,2003,121],{"class":86},[69,2005,2006],{"class":96},"$[[ inputs.environment ]]\n",[12,2008,2009],{},"Et voici comment une équipe applicative l'utilise :",[60,2011,2013],{"className":62,"code":2012,"language":64,"meta":65,"style":65},"# Application repo: .gitlab-ci.yml\nvariables:\n  APP_NAME: \"my-awesome-app\"\n  DEPLOY_URL: \"https://api.example.com\"\n\ninclude:\n  - component: gitlab.com/my-org/component-library/build@v1.0.6\n  - component: gitlab.com/my-org/component-library/test@v1.0.6\n  - component: gitlab.com/my-org/component-library/deploy@v1.0.6\n    inputs:\n      environment: staging\n\nstages:\n  - build\n  - test\n  - deploy\n",[52,2014,2015,2020,2027,2037,2047,2051,2058,2070,2081,2092,2099,2109,2113,2119,2125,2131],{"__ignoreMap":65},[69,2016,2017],{"class":71,"line":72},[69,2018,2019],{"class":75},"# Application repo: .gitlab-ci.yml\n",[69,2021,2022,2025],{"class":71,"line":79},[69,2023,2024],{"class":82},"variables",[69,2026,87],{"class":86},[69,2028,2029,2032,2034],{"class":71,"line":90},[69,2030,2031],{"class":82},"  APP_NAME",[69,2033,121],{"class":86},[69,2035,2036],{"class":96},"\"my-awesome-app\"\n",[69,2038,2039,2042,2044],{"class":71,"line":100},[69,2040,2041],{"class":82},"  DEPLOY_URL",[69,2043,121],{"class":86},[69,2045,2046],{"class":96},"\"https://api.example.com\"\n",[69,2048,2049],{"class":71,"line":107},[69,2050,104],{"emptyLinePlaceholder":103},[69,2052,2053,2056],{"class":71,"line":115},[69,2054,2055],{"class":82},"include",[69,2057,87],{"class":86},[69,2059,2060,2062,2065,2067],{"class":71,"line":126},[69,2061,93],{"class":86},[69,2063,2064],{"class":82},"component",[69,2066,121],{"class":86},[69,2068,2069],{"class":96},"gitlab.com/my-org/component-library/build@v1.0.6\n",[69,2071,2072,2074,2076,2078],{"class":71,"line":134},[69,2073,93],{"class":86},[69,2075,2064],{"class":82},[69,2077,121],{"class":86},[69,2079,2080],{"class":96},"gitlab.com/my-org/component-library/test@v1.0.6\n",[69,2082,2083,2085,2087,2089],{"class":71,"line":142},[69,2084,93],{"class":86},[69,2086,2064],{"class":82},[69,2088,121],{"class":86},[69,2090,2091],{"class":96},"gitlab.com/my-org/component-library/deploy@v1.0.6\n",[69,2093,2094,2097],{"class":71,"line":156},[69,2095,2096],{"class":82},"    inputs",[69,2098,87],{"class":86},[69,2100,2101,2104,2106],{"class":71,"line":168},[69,2102,2103],{"class":82},"      environment",[69,2105,121],{"class":86},[69,2107,2108],{"class":96},"staging\n",[69,2110,2111],{"class":71,"line":180},[69,2112,104],{"emptyLinePlaceholder":103},[69,2114,2115,2117],{"class":71,"line":308},[69,2116,83],{"class":82},[69,2118,87],{"class":86},[69,2120,2121,2123],{"class":71,"line":322},[69,2122,93],{"class":86},[69,2124,245],{"class":96},[69,2126,2127,2129],{"class":71,"line":329},[69,2128,93],{"class":86},[69,2130,252],{"class":96},[69,2132,2133,2135],{"class":71,"line":469},[69,2134,93],{"class":86},[69,2136,1466],{"class":96},[12,2138,2139,2140,2142,2143,2146],{},"Trois lignes ",[52,2141,1876],{}," remplacent des centaines de lignes de fichier YAML dupliqué. L'équipe plateforme peut déployer un correctif de sécurité dans la version ",[52,2144,2145],{},"v1.0.7"," et les équipes l'adoptent à leur propre rythme, ou l'équipe plateforme peut imposer une version minimale à tous. Dans les deux cas, une seule modification se propage partout au lieu de devoir être appliquée dépôt par dépôt.",[12,2148,2149,2150,2155,2156,2161],{},"Associez cette approche aux ",[16,2151,2154],{"href":2152,"rel":2153},"https://docs.gitlab.com/ci/resource_groups/",[],"groupes de ressources"," pour empêcher les déploiements simultanés vers le même environnement, et aux ",[16,2157,2160],{"href":2158,"rel":2159},"https://docs.gitlab.com/ci/environments/protected_environments/",[],"environnements protégés"," pour appliquer des portes d'approbation, et vous obtenez une plateforme de livraison gouvernée où la conformité est la norme, et non l'exception.",[12,2163,2164,2165,2171],{},"Pourquoi c'est important : c'est le modèle qui permet à ",[16,2166,2170],{"href":2167,"rel":2168,"title":2169},"https://about.gitlab.com/fr-fr/blog/what-is-gitlab-ci-cd/",[],"Qu'est-ce que GitLab CI/CD ?","GitLab CI/CD"," d'évoluer pour être appliqué par des centaines d'équipes. Les équipes d'ingénierie de plateforme appliquent la conformité sans devenir un goulot d'étranglement. Les équipes applicatives obtiennent un chemin rapide vers un pipeline fonctionnel sans avoir à tout recommencer.",[12,2173,2174],{},[341,2175],{"alt":2176,"src":2177,"title":2176},"Pipeline avec composants (jobs importés)","https://res.cloudinary.com/about-gitlab-com/image/upload/v1775738776/Blog/Imported/hackathon-fake-blog-post-s/image2_pizuxd.png",[30,2179,2181],{"id":2180},"vue-densemble","Vue d'ensemble",[12,2183,2184],{},"Aucune de ces fonctionnalités n'existe de manière isolée. L'intérêt du modèle de pipeline de GitLab réside dans le fait que ces éléments fondamentaux se combinent entre eux :",[1326,2186,2187,2190,2193],{},[1329,2188,2189],{},"Un monorepo utilise des pipelines parent-enfant, et chaque pipeline enfant utilise l'exécution du DAG.",[1329,2191,2192],{},"Une plateforme de microservices utilise des pipelines multi-projets, et chaque projet utilise des pipelines de merge request avec résultats fusionnés.",[1329,2194,2195],{},"Une plateforme gouvernée utilise des composants CI/CD pour standardiser les modèles ci-dessus dans toutes les équipes.",[12,2197,2198],{},"La plupart des équipes découvrent l'une de ces fonctionnalités lorsqu'elles rencontrent un point de friction spécifique. Celles qui investissent dans la compréhension du modèle complet obtiennent un système de livraison qui reflète réellement le fonctionnement de leur organisation d'ingénierie, et non un pipeline qui le freine.",[30,2200,2202],{"id":2201},"autres-modèles-à-explorer","Autres modèles à explorer",[12,2204,2205],{},"Les cinq modèles ci-dessus couvrent les points de friction structurels les plus courants, mais le modèle de pipeline de GitLab va plus loin. Voici quelques pistes supplémentaires à mesure que vos besoins évoluent :",[1326,2207,2208,2216,2234],{},[1329,2209,354,2210,2215],{},[16,2211,2214],{"href":2212,"rel":2213},"https://docs.gitlab.com/ci/environments/",[],"versions temporaires d'application avec environnements dynamiques"," vous permettent de créer un aperçu en direct pour chaque branche de fonctionnalité et de le supprimer automatiquement à la fermeture de la merge request. C'est particulièrement utile pour les équipes qui travaillent sur le frontend ou les modifications d'API qui nécessitent une validation des parties prenantes avant le merge.",[1329,2217,354,2218,2223,2224,2227,2228,2233],{},[16,2219,2222],{"href":2220,"rel":2221},"https://docs.gitlab.com/ci/caching/",[],"stratégies de mise en cache et d'artefacts"," sont souvent le moyen le plus rapide de réduire le temps d'exécution des pipelines une fois le travail structurel effectué. Structurer les clés de ",[52,2225,2226],{},"cache:"," autour des fichiers de verrouillage des dépendances et faire preuve de rigueur sur ce qui est transmis entre les jobs avec ",[16,2229,2232],{"href":2230,"rel":2231},"https://docs.gitlab.com/ci/yaml/#artifacts",[],"artefacts:"," peut faire une différence significative sans modifier la forme de votre pipeline.",[1329,2235,354,2236,2241,2242,2247,2248,2251],{},[16,2237,2240],{"href":2238,"rel":2239},"https://docs.gitlab.com/ci/pipelines/schedules/",[],"pipelines planifiés et déclenchés par API"," méritent d'être connus, car tout ne doit pas s'exécuter sur un push de code. Les scans de sécurité nocturnes, les rapports de conformité et l'automatisation des releases sont mieux modélisés sous forme de pipelines planifiés ou ",[16,2243,2246],{"href":2244,"rel":2245},"https://docs.gitlab.com/ci/triggers/",[],"déclenchés par API",", avec ",[52,2249,2250],{},"$CI_PIPELINE_SOURCE"," qui achemine les bons jobs selon le contexte.",[30,2253,2255],{"id":2254},"lancez-vous","Lancez-vous",[12,2257,2258],{},"La livraison logicielle moderne est complexe. Les équipes gèrent des monorepos avec des dizaines de services, coordonnent leurs efforts entre plusieurs dépôts, déploient vers de nombreux environnements simultanément et cherchent à maintenir la cohérence des normes à mesure que les organisations évoluent. Le modèle de pipeline de GitLab a été conçu avec tous ces enjeux à l'esprit.",[12,2260,2261],{},"Il vaut la peine d'investir dans le modèle de pipeline de GitLab, car ses différents éléments s'articulent particulièrement bien entre eux. Les pipelines parent-enfant apportent une certaine structure aux codes sources volumineux. Les pipelines multi-projets donnent davantage de visibilité aux dépendances inter-équipes et permettent de les tester. Les pipelines dynamiques transforment la gestion des environnements en un processus aisément évolutif. La livraison axée sur les merge requests avec résultats fusionnés garantit la confiance à chaque étape du processus de revue. Et les composants CI/CD offrent aux équipes plateforme un moyen de partager les bonnes pratiques dans toute l'organisation sans devenir un goulot d'étranglement.",[12,2263,2264],{},"Chacune de ces fonctionnalités est puissante individuellement, et encore plus lorsqu'elles sont combinées. GitLab vous fournit les composants nécessaires pour concevoir un système de livraison adapté au fonctionnement réel de votre équipe, et qui évolue avec vos besoins.",[2266,2267,2268],"blockquote",{},[12,2269,2270,2275],{},[16,2271,2274],{"href":2272,"rel":2273},"https://about.gitlab.com/fr-fr/free-trial/?utm_medium=blog&utm_source=blog&utm_campaign=eg_emea_x_trial_x_fr_blog_fr",[],"Démarrez un essai gratuit de GitLab Ultimate"," pour exploiter la logique des pipelines dès aujourd'hui.",[2277,2278,2279],"style",{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}",{"title":65,"searchDepth":79,"depth":79,"links":2281},[2282,2283,2284,2285,2286,2287,2288,2289],{"id":32,"depth":79,"text":33},{"id":347,"depth":79,"text":348},{"id":838,"depth":79,"text":839},{"id":1313,"depth":79,"text":1314},{"id":1857,"depth":79,"text":1858},{"id":2180,"depth":79,"text":2181},{"id":2201,"depth":79,"text":2202},{"id":2254,"depth":79,"text":2255},"engineering","2026-05-06","Découvrez comment faire évoluer votre approche CI/CD avec des modèles composables pour les monorepos, les microservices, les environnements et la gouvernance.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772721753/frfsm1qfscwrmsyzj1qn.png",{},"/fr-fr/blog/5-ways-gitlab-pipeline-logic-solves-real-engineering-problems",{"config":2300,"title":2301,"ogTitle":65,"description":2302},{"noIndex":2295},"5 pipelines GitLab pour résoudre vos enjeux d'ingénierie","Découvrez comment faire évoluer votre approche CI/CD avec des modèles composables\npour les monorepos, les microservices, les environnements et la gouvernance.","5-ways-gitlab-pipeline-logic-solves-real-engineering-problems","fr-fr/blog/5-ways-gitlab-pipeline-logic-solves-real-engineering-problems",[21,2306,2307,2308],"DevOps platform","tutorial","features","BlogPost","yRb225LPlXcGvE0zgqfuVV_vsN2TsjJTtH-ya5Ob9_U",{"logo":2312,"freeTrial":2317,"sales":2322,"login":2327,"items":2332,"search":2648,"minimal":2684,"duo":2703,"switchNav":2712,"pricingDeployment":2723},{"config":2313},{"href":2314,"dataGaName":2315,"dataGaLocation":2316},"/fr-fr/","gitlab logo","header",{"text":2318,"config":2319},"Commencer un essai gratuit",{"href":2320,"dataGaName":2321,"dataGaLocation":2316},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr&glm_content=default-saas-trial/","free trial",{"text":2323,"config":2324},"Contacter l’équipe commerciale",{"href":2325,"dataGaName":2326,"dataGaLocation":2316},"/fr-fr/sales/","sales",{"text":2328,"config":2329},"Connexion",{"href":2330,"dataGaName":2331,"dataGaLocation":2316},"https://gitlab.com/users/sign_in/","sign in",[2333,2362,2463,2468,2572,2628],{"text":2334,"config":2335,"menu":2337},"Plateforme",{"dataNavLevelOne":2336},"platform",{"type":2338,"columns":2339},"cards",[2340,2346,2354],{"title":2334,"description":2341,"link":2342},"La plateforme d’orchestration intelligente pour le DevSecOps",{"text":2343,"config":2344},"Explorer notre plateforme",{"href":2345,"dataGaName":2336,"dataGaLocation":2316},"/fr-fr/platform/",{"title":2347,"description":2348,"link":2349},"GitLab Duo Agent Platform","L’IA agentique pour l’ensemble du cycle de développement logiciel",{"text":2350,"config":2351},"Découvrir GitLab Duo",{"href":2352,"dataGaName":2353,"dataGaLocation":2316},"/fr-fr/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":2355,"description":2356,"link":2357},"Pourquoi GitLab ?","Découvrez les principales raisons pour lesquelles les entreprises choisissent GitLab",{"text":2358,"config":2359},"En savoir plus",{"href":2360,"dataGaName":2361,"dataGaLocation":2316},"/fr-fr/why-gitlab/","why gitlab",{"text":2363,"left":103,"config":2364,"menu":2366},"Produit",{"dataNavLevelOne":2365},"solutions",{"type":2367,"link":2368,"columns":2372,"feature":2442},"lists",{"text":2369,"config":2370},"Voir toutes les solutions",{"href":2371,"dataGaName":2365,"dataGaLocation":2316},"/fr-fr/solutions/",[2373,2397,2420],{"title":2374,"description":2375,"link":2376,"items":2381},"Automatisation","CI/CD et automatisation pour accélérer le déploiement",{"config":2377},{"icon":2378,"href":2379,"dataGaName":2380,"dataGaLocation":2316},"AutomatedCodeAlt","/fr-fr/solutions/delivery-automation/","automated software delivery",[2382,2385,2388,2393],{"text":21,"config":2383},{"href":2384,"dataGaLocation":2316,"dataGaName":21},"/fr-fr/solutions/continuous-integration/",{"text":2347,"config":2386},{"href":2352,"dataGaLocation":2316,"dataGaName":2387},"gitlab duo agent platform - product menu",{"text":2389,"config":2390},"Gestion du code source",{"href":2391,"dataGaLocation":2316,"dataGaName":2392},"/fr-fr/solutions/source-code-management/","Source Code Management",{"text":2394,"config":2395},"Livraison de logiciels automatisée",{"href":2379,"dataGaLocation":2316,"dataGaName":2396},"Automated software delivery",{"title":2398,"description":2399,"link":2400,"items":2405},"Sécurité","Livrez du code plus rapidement sans compromettre la sécurité",{"config":2401},{"href":2402,"dataGaName":2403,"dataGaLocation":2316,"icon":2404},"/fr-fr/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[2406,2410,2415],{"text":2407,"config":2408},"Tests de sécurité des applications",{"href":2402,"dataGaName":2409,"dataGaLocation":2316},"Application security testing",{"text":2411,"config":2412},"Sécurité de la chaîne d’approvisionnement logicielle",{"href":2413,"dataGaLocation":2316,"dataGaName":2414},"/fr-fr/solutions/supply-chain/","Software supply chain security",{"text":2416,"config":2417},"Conformité logicielle",{"href":2418,"dataGaName":2419,"dataGaLocation":2316},"/fr-fr/solutions/software-compliance/","software compliance",{"title":2421,"link":2422,"items":2427},"Mesures",{"config":2423},{"icon":2424,"href":2425,"dataGaName":2426,"dataGaLocation":2316},"DigitalTransformation","/fr-fr/solutions/visibility-measurement/","visibility and measurement",[2428,2432,2437],{"text":2429,"config":2430},"Visibilité et mesures",{"href":2425,"dataGaLocation":2316,"dataGaName":2431},"Visibility and Measurement",{"text":2433,"config":2434},"Gestion de la chaîne de valeur",{"href":2435,"dataGaLocation":2316,"dataGaName":2436},"/fr-fr/solutions/value-stream-management/","Value Stream Management",{"text":2438,"config":2439},"Analyses et informations",{"href":2440,"dataGaLocation":2316,"dataGaName":2441},"/fr-fr/solutions/analytics-and-insights/","Analytics and insights",{"title":2443,"type":2367,"items":2444},"GitLab",[2445,2451,2457],{"text":2446,"config":2447},"Pour les entreprises",{"icon":2448,"href":2449,"dataGaLocation":2316,"dataGaName":2450},"Building","/fr-fr/enterprise/","enterprise",{"text":2452,"config":2453},"Pour les PME",{"icon":2454,"href":2455,"dataGaLocation":2316,"dataGaName":2456},"Work","/fr-fr/small-business/","small business",{"text":2458,"config":2459},"Pour le secteur public",{"icon":2460,"href":2461,"dataGaLocation":2316,"dataGaName":2462},"Organization","/fr-fr/solutions/public-sector/","public sector",{"text":2464,"config":2465},"Tarifs",{"href":2466,"dataGaName":2467,"dataGaLocation":2316,"dataNavLevelOne":2467},"/fr-fr/pricing/","pricing",{"text":2469,"config":2470,"menu":2472},"Ressources",{"dataNavLevelOne":2471},"resources",{"type":2367,"link":2473,"columns":2477,"feature":2561},{"text":2474,"config":2475},"Afficher toutes les ressources",{"href":2476,"dataGaName":2471,"dataGaLocation":2316},"/fr-fr/resources/",[2478,2511,2533],{"title":2479,"items":2480},"Premiers pas",[2481,2486,2491,2496,2501,2506],{"text":2482,"config":2483},"Installation",{"href":2484,"dataGaName":2485,"dataGaLocation":2316},"/fr-fr/install/","install",{"text":2487,"config":2488},"Guides de démarrage",{"href":2489,"dataGaName":2490,"dataGaLocation":2316},"/fr-fr/get-started/","quick setup checklists",{"text":2492,"config":2493},"Apprentissage",{"href":2494,"dataGaLocation":2316,"dataGaName":2495},"https://university.gitlab.com/","learn",{"text":2497,"config":2498},"Documentation",{"href":2499,"dataGaName":2500,"dataGaLocation":2316},"https://docs.gitlab.com/","product documentation",{"text":2502,"config":2503},"Vidéos sur les bonnes pratiques",{"href":2504,"dataGaName":2505,"dataGaLocation":2316},"/fr-fr/getting-started-videos/","best practice videos",{"text":2507,"config":2508},"Intégrations",{"href":2509,"dataGaName":2510,"dataGaLocation":2316},"/fr-fr/integrations/","integrations",{"title":2512,"items":2513},"Découvrir",[2514,2519,2524,2528],{"text":2515,"config":2516},"Témoignages clients",{"href":2517,"dataGaName":2518,"dataGaLocation":2316},"/fr-fr/customers/","customer success stories",{"text":2520,"config":2521},"Blog",{"href":2522,"dataGaName":2523,"dataGaLocation":2316},"/fr-fr/blog/","blog",{"text":2525,"config":2526},"The Source",{"href":2527,"dataGaName":2523,"dataGaLocation":2316},"/fr-fr/the-source/",{"text":2529,"config":2530},"Travail à distance",{"href":2531,"dataGaName":2532,"dataGaLocation":2316},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":2534,"items":2535},"Connecter",[2536,2541,2546,2551,2556],{"text":2537,"config":2538},"Services GitLab",{"href":2539,"dataGaName":2540,"dataGaLocation":2316},"/fr-fr/services/","services",{"text":2542,"config":2543},"Communauté",{"href":2544,"dataGaName":2545,"dataGaLocation":2316},"/community/","community",{"text":2547,"config":2548},"Forum",{"href":2549,"dataGaName":2550,"dataGaLocation":2316},"https://forum.gitlab.com/","forum",{"text":2552,"config":2553},"Événements",{"href":2554,"dataGaName":2555,"dataGaLocation":2316},"/events/","events",{"text":2557,"config":2558},"Partenaires",{"href":2559,"dataGaName":2560,"dataGaLocation":2316},"/fr-fr/partners/","partners",{"config":2562,"title":2565,"text":2566,"link":2567},{"background":2563,"textColor":2564},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","Nouveautés de GitLab","Restez informé des dernières fonctionnalités et améliorations.",{"text":2568,"config":2569},"Lire les articles les plus récents",{"href":2570,"dataGaName":2571,"dataGaLocation":2316},"/fr-fr/whats-new/","whats new",{"text":2573,"config":2574,"menu":2576},"Société",{"dataNavLevelOne":2575},"company",{"type":2367,"columns":2577},[2578],{"items":2579},[2580,2585,2591,2593,2598,2603,2608,2613,2618,2623],{"text":2581,"config":2582},"À propos",{"href":2583,"dataGaName":2584,"dataGaLocation":2316},"/fr-fr/company/","about",{"text":2586,"config":2587,"footerGa":2590},"Carrières",{"href":2588,"dataGaName":2589,"dataGaLocation":2316},"/jobs/","jobs",{"dataGaName":2589},{"text":2552,"config":2592},{"href":2554,"dataGaName":2555,"dataGaLocation":2316},{"text":2594,"config":2595},"Leadership",{"href":2596,"dataGaName":2597,"dataGaLocation":2316},"/company/team/e-group/","leadership",{"text":2599,"config":2600},"Manuel",{"href":2601,"dataGaName":2602,"dataGaLocation":2316},"https://handbook.gitlab.com/","handbook",{"text":2604,"config":2605},"Relations avec les investisseurs",{"href":2606,"dataGaName":2607,"dataGaLocation":2316},"https://ir.gitlab.com/","investor relations",{"text":2609,"config":2610},"Trust Center",{"href":2611,"dataGaName":2612,"dataGaLocation":2316},"/fr-fr/security/","trust center",{"text":2614,"config":2615},"Centre pour la transparence de l’IA",{"href":2616,"dataGaName":2617,"dataGaLocation":2316},"/fr-fr/ai-transparency-center/","ai transparency center",{"text":2619,"config":2620},"Newsletter",{"href":2621,"dataGaName":2622,"dataGaLocation":2316},"/company/contact/#contact-forms","newsletter",{"text":2624,"config":2625},"Presse",{"href":2626,"dataGaName":2627,"dataGaLocation":2316},"/press/","press",{"text":2629,"config":2630,"menu":2631},"Nous contacter",{"dataNavLevelOne":2575},{"type":2367,"columns":2632},[2633],{"items":2634},[2635,2638,2643],{"text":2323,"config":2636},{"href":2325,"dataGaName":2637,"dataGaLocation":2316},"talk to sales",{"text":2639,"config":2640},"Portail d'assistance",{"href":2641,"dataGaName":2642,"dataGaLocation":2316},"https://support.gitlab.com","support portal",{"text":2644,"config":2645},"Portail clients GitLab",{"href":2646,"dataGaName":2647,"dataGaLocation":2316},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":2649,"login":2650,"suggestions":2657},"Fermer",{"text":2651,"link":2652},"Pour rechercher des dépôts et des projets, connectez-vous à",{"text":2653,"config":2654},"GitLab.com",{"href":2330,"dataGaName":2655,"dataGaLocation":2656},"search login","search",{"text":2658,"default":2659},"Suggestions",[2660,2663,2668,2670,2675,2680],{"text":2347,"config":2661},{"href":2352,"dataGaName":2662,"dataGaLocation":2656},"GitLab Duo Agent Platform",{"text":2664,"config":2665},"Suggestions de code (IA)",{"href":2666,"dataGaName":2667,"dataGaLocation":2656},"/fr-fr/solutions/code-suggestions/","Code Suggestions (AI)",{"text":21,"config":2669},{"href":2384,"dataGaName":21,"dataGaLocation":2656},{"text":2671,"config":2672},"GitLab sur AWS",{"href":2673,"dataGaName":2674,"dataGaLocation":2656},"/fr-fr/partners/technology-partners/aws/","GitLab on AWS",{"text":2676,"config":2677},"GitLab sur Google Cloud",{"href":2678,"dataGaName":2679,"dataGaLocation":2656},"/fr-fr/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":2681,"config":2682},"Pourquoi utiliser GitLab ?",{"href":2360,"dataGaName":2683,"dataGaLocation":2656},"Why GitLab?",{"freeTrial":2685,"mobileIcon":2690,"desktopIcon":2695,"secondaryButton":2698},{"text":2686,"config":2687},"Commencer votre essai gratuit",{"href":2688,"dataGaName":2321,"dataGaLocation":2689},"https://gitlab.com/-/trials/new/","nav",{"altText":2691,"config":2692},"Icône GitLab",{"src":2693,"dataGaName":2694,"dataGaLocation":2689},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":2691,"config":2696},{"src":2697,"dataGaName":2694,"dataGaLocation":2689},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":2699,"config":2700},"Commencer",{"href":2701,"dataGaName":2702,"dataGaLocation":2689},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/fr-fr/get-started/","get started",{"freeTrial":2704,"mobileIcon":2708,"desktopIcon":2710},{"text":2705,"config":2706},"En savoir plus sur GitLab Duo",{"href":2352,"dataGaName":2707,"dataGaLocation":2689},"gitlab duo",{"altText":2691,"config":2709},{"src":2693,"dataGaName":2694,"dataGaLocation":2689},{"altText":2691,"config":2711},{"src":2697,"dataGaName":2694,"dataGaLocation":2689},{"button":2713,"mobileIcon":2718,"desktopIcon":2720},{"text":2714,"config":2715},"/switch",{"href":2716,"dataGaName":2717,"dataGaLocation":2689},"#contact","switch",{"altText":2691,"config":2719},{"src":2693,"dataGaName":2694,"dataGaLocation":2689},{"altText":2691,"config":2721},{"src":2722,"dataGaName":2694,"dataGaLocation":2689},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":2724,"mobileIcon":2729,"desktopIcon":2731},{"text":2725,"config":2726},"Retour aux tarifs",{"href":2466,"dataGaName":2727,"dataGaLocation":2689,"icon":2728},"back to pricing","GoBack",{"altText":2691,"config":2730},{"src":2693,"dataGaName":2694,"dataGaLocation":2689},{"altText":2691,"config":2732},{"src":2697,"dataGaName":2694,"dataGaLocation":2689},{"title":2734,"button":2735,"config":2740},"Découvrez comment l'IA agentique transforme la livraison logicielle",{"text":2736,"config":2737},"Rejoindre GitLab Transcend en direct le 10 juin",{"href":2738,"dataGaName":2739,"dataGaLocation":2316},"/fr-fr/events/transcend/virtual/","transcend event",{"layout":2741,"disabled":2295},"release",{"data":2743},{"text":2744,"source":2745,"edit":2751,"contribute":2756,"config":2761,"items":2766,"minimal":2974},"Git est une marque déposée de Software Freedom Conservancy et notre utilisation de « GitLab » est sous licence.",{"text":2746,"config":2747},"Afficher le code source de la page",{"href":2748,"dataGaName":2749,"dataGaLocation":2750},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":2752,"config":2753},"Modifier cette page",{"href":2754,"dataGaName":2755,"dataGaLocation":2750},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":2757,"config":2758},"Veuillez contribuer",{"href":2759,"dataGaName":2760,"dataGaLocation":2750},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":2762,"facebook":2763,"youtube":2764,"linkedin":2765},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[2767,2814,2867,2911,2941],{"title":2464,"links":2768,"subMenu":2783},[2769,2773,2778],{"text":2770,"config":2771},"Voir les forfaits",{"href":2466,"dataGaName":2772,"dataGaLocation":2750},"view plans",{"text":2774,"config":2775},"GitLab Premium",{"href":2776,"dataGaName":2777,"dataGaLocation":2750},"/fr-fr/pricing/premium/","why premium",{"text":2779,"config":2780},"GitLab Ultimate",{"href":2781,"dataGaName":2782,"dataGaLocation":2750},"/fr-fr/pricing/ultimate/","why ultimate",[2784],{"title":2629,"links":2785},[2786,2789,2792,2794,2799,2804,2809],{"text":2787,"config":2788},"Contacter l'équipe commerciale",{"href":2325,"dataGaName":2326,"dataGaLocation":2750},{"text":2790,"config":2791},"Assistance GitLab",{"href":2641,"dataGaName":2642,"dataGaLocation":2750},{"text":2644,"config":2793},{"href":2646,"dataGaName":2647,"dataGaLocation":2750},{"text":2795,"config":2796},"Statut",{"href":2797,"dataGaName":2798,"dataGaLocation":2750},"https://status.gitlab.com/","status",{"text":2800,"config":2801},"Conditions d'utilisation",{"href":2802,"dataGaName":2803,"dataGaLocation":2750},"/terms/","terms of use",{"text":2805,"config":2806},"Politique de confidentialité",{"href":2807,"dataGaName":2808,"dataGaLocation":2750},"/fr-fr/privacy/","privacy statement",{"text":2810,"config":2811},"Gérer vos cookies",{"dataGaName":2812,"dataGaLocation":2750,"id":2813,"isOneTrustButton":103},"cookie preferences","ot-sdk-btn",{"title":2363,"links":2815,"subMenu":2824},[2816,2820],{"text":2817,"config":2818},"Plateforme DevSecOps",{"href":2345,"dataGaName":2819,"dataGaLocation":2750},"devsecops platform",{"text":2821,"config":2822},"Développement assisté par l'IA",{"href":2352,"dataGaName":2823,"dataGaLocation":2750},"ai-assisted development",[2825],{"title":2826,"links":2827},"Thèmes",[2828,2832,2837,2842,2847,2852,2857,2862],{"text":21,"config":2829},{"href":2830,"dataGaName":2831,"dataGaLocation":2750},"/fr-fr/topics/ci-cd/","cicd",{"text":2833,"config":2834},"GitOps",{"href":2835,"dataGaName":2836,"dataGaLocation":2750},"/fr-fr/topics/gitops/","gitops",{"text":2838,"config":2839},"DevOps",{"href":2840,"dataGaName":2841,"dataGaLocation":2750},"/fr-fr/topics/devops/","devops",{"text":2843,"config":2844},"Contrôle de version",{"href":2845,"dataGaName":2846,"dataGaLocation":2750},"/fr-fr/topics/version-control/","version control",{"text":2848,"config":2849},"DevSecOps",{"href":2850,"dataGaName":2851,"dataGaLocation":2750},"/fr-fr/topics/devsecops/","devsecops",{"text":2853,"config":2854},"Cloud-native",{"href":2855,"dataGaName":2856,"dataGaLocation":2750},"/fr-fr/topics/cloud-native/","cloud native",{"text":2858,"config":2859},"IA pour la programmation",{"href":2860,"dataGaName":2861,"dataGaLocation":2750},"/fr-fr/topics/devops/ai-for-coding/","ai for coding",{"text":2863,"config":2864},"IA agentique",{"href":2865,"dataGaName":2866,"dataGaLocation":2750},"/fr-fr/topics/agentic-ai/","agentic ai",{"title":2868,"links":2869},"Solutions",[2870,2873,2875,2880,2883,2886,2889,2892,2895,2898,2901,2906],{"text":2407,"config":2871},{"href":2402,"dataGaName":2872,"dataGaLocation":2750},"Application Security Testing",{"text":2394,"config":2874},{"href":2379,"dataGaName":2380,"dataGaLocation":2750},{"text":2876,"config":2877},"Développement Agile",{"href":2878,"dataGaName":2879,"dataGaLocation":2750},"/fr-fr/solutions/agile-delivery/","agile delivery",{"text":2389,"config":2881},{"href":2391,"dataGaName":2882,"dataGaLocation":2750},"source code management",{"text":21,"config":2884},{"href":2384,"dataGaName":2885,"dataGaLocation":2750},"continuous integration & delivery",{"text":2433,"config":2887},{"href":2435,"dataGaName":2888,"dataGaLocation":2750},"value stream management",{"text":2833,"config":2890},{"href":2891,"dataGaName":2836,"dataGaLocation":2750},"/fr-fr/solutions/gitops/",{"text":2893,"config":2894},"Entreprises",{"href":2449,"dataGaName":2450,"dataGaLocation":2750},{"text":2896,"config":2897},"PME",{"href":2455,"dataGaName":2456,"dataGaLocation":2750},{"text":2899,"config":2900},"Secteur public",{"href":2461,"dataGaName":2462,"dataGaLocation":2750},{"text":2902,"config":2903},"Éducation",{"href":2904,"dataGaName":2905,"dataGaLocation":2750},"/fr-fr/solutions/education/","education",{"text":2907,"config":2908},"Services financiers",{"href":2909,"dataGaName":2910,"dataGaLocation":2750},"/fr-fr/solutions/finance/","financial services",{"title":2469,"links":2912},[2913,2915,2917,2919,2922,2924,2927,2929,2931,2933,2935,2937,2939],{"text":2482,"config":2914},{"href":2484,"dataGaName":2485,"dataGaLocation":2750},{"text":2487,"config":2916},{"href":2489,"dataGaName":2490,"dataGaLocation":2750},{"text":2492,"config":2918},{"href":2494,"dataGaName":2495,"dataGaLocation":2750},{"text":2497,"config":2920},{"href":2499,"dataGaName":2921,"dataGaLocation":2750},"docs",{"text":2520,"config":2923},{"href":2522,"dataGaName":2523,"dataGaLocation":2750},{"text":2925,"config":2926},"Quoi de neuf",{"href":2570,"dataGaName":2571,"dataGaLocation":2750},{"text":2515,"config":2928},{"href":2517,"dataGaName":2518,"dataGaLocation":2750},{"text":2529,"config":2930},{"href":2531,"dataGaName":2532,"dataGaLocation":2750},{"text":2537,"config":2932},{"href":2539,"dataGaName":2540,"dataGaLocation":2750},{"text":2542,"config":2934},{"href":2544,"dataGaName":2545,"dataGaLocation":2750},{"text":2547,"config":2936},{"href":2549,"dataGaName":2550,"dataGaLocation":2750},{"text":2552,"config":2938},{"href":2554,"dataGaName":2555,"dataGaLocation":2750},{"text":2557,"config":2940},{"href":2559,"dataGaName":2560,"dataGaLocation":2750},{"title":2573,"links":2942},[2943,2945,2947,2949,2951,2953,2958,2963,2965,2967,2969],{"text":2581,"config":2944},{"href":2583,"dataGaName":2575,"dataGaLocation":2750},{"text":2586,"config":2946},{"href":2588,"dataGaName":2589,"dataGaLocation":2750},{"text":2594,"config":2948},{"href":2596,"dataGaName":2597,"dataGaLocation":2750},{"text":2599,"config":2950},{"href":2601,"dataGaName":2602,"dataGaLocation":2750},{"text":2604,"config":2952},{"href":2606,"dataGaName":2607,"dataGaLocation":2750},{"text":2954,"config":2955},"Développement durable",{"href":2956,"dataGaName":2957,"dataGaLocation":2750},"/sustainability/","Sustainability",{"text":2959,"config":2960},"Diversité, inclusion et appartenance (DIB)",{"href":2961,"dataGaName":2962,"dataGaLocation":2750},"/fr-fr/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":2609,"config":2964},{"href":2611,"dataGaName":2612,"dataGaLocation":2750},{"text":2619,"config":2966},{"href":2621,"dataGaName":2622,"dataGaLocation":2750},{"text":2624,"config":2968},{"href":2626,"dataGaName":2627,"dataGaLocation":2750},{"text":2970,"config":2971},"Déclaration de transparence sur l'esclavage moderne",{"href":2972,"dataGaName":2973,"dataGaLocation":2750},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":2975},[2976,2978,2981],{"text":2800,"config":2977},{"href":2802,"dataGaName":2803,"dataGaLocation":2750},{"text":2979,"config":2980},"Gestion des cookies",{"dataGaName":2812,"dataGaLocation":2750,"id":2813,"isOneTrustButton":103},{"text":2805,"config":2982},{"href":2807,"dataGaName":2808,"dataGaLocation":2750},[2984],{"id":2985,"title":7,"body":2294,"config":2986,"content":2989,"description":2294,"extension":2992,"meta":2993,"navigation":103,"path":2994,"seo":2995,"stem":2996,"__hash__":2997},"blogAuthors/en-us/blog/authors/omid-khan.yml",{"template":2987,"gitlabHandle":2988},"BlogAuthor","OmidKhan",{"name":7,"config":2990,"role":65},{"headshot":2991},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1769090536/q4p3qwthtken8fpokgzu.jpg","yml",{},"/en-us/blog/authors/omid-khan",{},"en-us/blog/authors/omid-khan","4ZHOi5nEiZLdJm1phW-47SM0x-BGo8jNbg_Zt0oSzEQ",[2999,3007,3015],{"title":3000,"description":3001,"heroImage":3002,"category":2290,"date":3003,"authors":3004,"slug":3006,"externalUrl":2294},"Comment mettre en place l'observabilité CI/CD à grande échelle","Ce guide pratique consacré à l'analyse des pipelines GitLab aide les utilisateurs de GitLab Self-Managed à obtenir des indicateurs opérationnels exploitables grâce à Prometheus et Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-05-18",[3005],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"title":3008,"description":3009,"heroImage":3010,"category":2290,"date":3011,"authors":3012,"slug":3014,"externalUrl":2294},"Comment utiliser le registre de conteneurs GitLab avec les images durcies Docker","Simplifiez la gestion des images de conteneurs grâce à ce guide pas à pas.","https://res.cloudinary.com/about-gitlab-com/image/upload/f_auto,q_auto,c_lfill/v1772111172/mwhgbjawn62kymfwrhle.png","2026-04-01",[3013],"Tim Rizzi","using-gitlab-container-virtual-registry-with-docker-hardened-images",{"title":3016,"description":3017,"heroImage":3018,"category":2290,"date":3019,"authors":3020,"slug":3022,"externalUrl":2294},"GitLab Duo Agentic Chat : renforcez votre code avec les règles personnalisées","Découvrez comment l'IA peut comprendre votre code source, suivre vos conventions et générer du code prêt pour la production avec un minimum de cycles de revue.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099203/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2820%29_2bJGC5ZP3WheoqzlLT05C5_1750099203484.png","2026-02-10",[3021],"Michael Friedrich","custom-rules-duo-agentic-chat-deep-dive",{"promotions":3024},[3025,3039,3051,3063],{"id":3026,"categories":3027,"header":3029,"text":3030,"button":3031,"image":3036},"ai-modernization",[3028],"ai","L'IA tient-elle ses promesses à grande échelle ?","Le questionnaire ne prendra pas plus de 5 minutes.",{"text":3032,"config":3033},"Obtenez votre score de maturité IA",{"href":3034,"dataGaName":3035,"dataGaLocation":2523},"/fr-fr/assessments/ai-modernization-assessment/","modernization assessment",{"config":3037},{"src":3038},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":3040,"categories":3041,"header":3043,"text":3030,"button":3044,"image":3048},"devops-modernization",[3042,2851],"product","Vous contentez-vous de gérer des outils ou de livrer des innovations ?",{"text":3045,"config":3046},"Obtenez votre score de maturité DevOps",{"href":3047,"dataGaName":3035,"dataGaLocation":2523},"/fr-fr/assessments/devops-modernization-assessment/",{"config":3049},{"src":3050},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":3052,"categories":3053,"header":3055,"text":3030,"button":3056,"image":3060},"security-modernization",[3054],"security","Faut-il sacrifier la rapidité pour garantir la sécurité ?",{"text":3057,"config":3058},"Obtenez votre score de maturité en matière de sécurité",{"href":3059,"dataGaName":3035,"dataGaLocation":2523},"/fr-fr/assessments/security-modernization-assessment/",{"config":3061},{"src":3062},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":3064,"paths":3065,"header":3068,"text":3069,"button":3070,"image":3075},"github-azure-migration",[3066,3067],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Votre équipe est-elle prête pour la migration de GitHub vers Azure ?","GitHub a déjà commencé sa migration vers Azure. Découvrez ce que cela signifie pour vous.",{"text":3071,"config":3072},"Découvrez les différences entre GitLab et GitHub",{"href":3073,"dataGaName":3074,"dataGaLocation":2523},"/fr-fr/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":3076},{"src":3050},{"header":3078,"blurb":3079,"button":3080,"secondaryButton":3084},"Commencez à développer plus rapidement dès aujourd'hui","Découvrez ce que votre équipe peut accomplir avec la plateforme d'orchestration intelligente pour le DevSecOps.\n",{"text":2318,"config":3081},{"href":3082,"dataGaName":2321,"dataGaLocation":3083},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/fr-fr/","feature",{"text":2787,"config":3085},{"href":2325,"dataGaName":2326,"dataGaLocation":3083},1781392824038]