QCM de reprise du cours-02
La séance commence par 20 minutes de QCM sur papier. Les questions portent sur les notions du cours-02 : Docker, GitHub Flow, Git Flow, Pull Requests, release branches, hotfixes et logique globale des workflows étudiés.
Une fois le QCM terminé, nous repartons du point où le cours-02 s'arrêtait : que se passe-t-il quand un projet doit maintenir plusieurs versions actives et quand la coordination Git devient plus coûteuse ?
GitLab Flow
GitHub Flow fonctionne très bien tant qu'on intègre en continu sur une seule ligne courante. Mais certains produits doivent aussi continuer à corriger une version plus ancienne déjà déployée chez des clients. C'est là qu'un flow de type GitLab Flow devient intéressant.
Deux lignes actives, deux contraintes différentes
Dans le dépôt de démonstration, main représente la
ligne courante du produit, alors que
production/v1 représente une version plus ancienne
encore supportée. Une nouvelle fonctionnalité part de
main. Un correctif urgent pour les utilisateurs de
la v1 part de production/v1.
Lien rapide avec les environnements
Ce type de flow fait rapidement apparaître des contextes de diffusion différents : environnement de développement pour la ligne courante, environnement de validation intermédiaire, puis production pour une version donnée. Nous resterons aujourd'hui sur trois repères utiles : DEV, STAGING et PROD.
Le coût caché : coordonner les correctifs
Dès qu'un bug existe à la fois sur la version maintenue et sur la
ligne courante, il faut le reporter aussi sur
main après correction sur
production/v1. Cela peut se faire par
cherry-pick ou par correction équivalente, mais dans
tous les cas cela augmente le coût de coordination.
Si vous devez ajouter une nouvelle fonctionnalité, quelle branche cible devez-vous choisir ?
Vous devez partir de main, car une fonctionnalité
nouvelle concerne la ligne courante du produit.
Une branche de maintenance comme production/v1 sert
d'abord à corriger une version plus ancienne déjà utilisée, pas
à enrichir la version courante.
Ce gitGraph donne la lecture minimale à retenir pour
la séance.
Chargement du gitGraph…
Mini-démo guidée — dépôt GitLab Flow
Dépôt support : GVI2026/tp-gitlab-flow
L'objectif n'est pas de refaire un TP complet, mais de rendre visible un besoin que GitHub Flow ou Git Flow couvrent moins bien : maintenir une ancienne version tout en développant la suivante.
-
Vérifier l'existence des deux branches permanentes :
git branch -a -
Montrer une nouvelle fonctionnalité sur la ligne courante avec
l'endpoint
GET /tasks/stats, à implémenter depuisfeature/add-task-stats. -
Basculer ensuite sur la ligne de maintenance et ouvrir un hotfix
depuis
production/v1pour corriger la validation du champtitle.git checkout production/v1 git checkout -b hotfix/fix-title-validation - Finir par verbaliser le vrai message du flow : une correction critique ne reste pas enfermée sur une seule branche si le bug existe aussi sur la ligne courante.
Qu'est-ce qui deviendrait difficile à gérer manuellement dès que les deux branches sont actives en même temps ?
S'assurer qu'un bug corrigé sur production/v1
est bien aussi reporté sur main. Sans
automatisation ni processus explicite, ce cherry-pick peut
être oublié et le bug réapparaître dans la prochaine version.
Plus généralement, valider que les deux lignes restent stables et cohérentes l'une avec l'autre devient un travail de coordination à part entière — c'est exactement là que l'automatisation des vérifications commence à avoir de la valeur.
Trunk-Based Development — teaser stratégique
Le Trunk-Based Development n'est pas le sujet pratique d'aujourd'hui. Nous le regardons comme une direction possible pour des équipes qui intègrent très fréquemment et qui disposent déjà d'une CI/CD solide.
Principe :
une branche principale unique, souvent main ou
trunk, sur laquelle les intégrations sont très
fréquentes.
Feature flags : ils permettent de masquer une fonctionnalité incomplète sans la garder éternellement sur une branche longue.
Merge queues : elles sérialisent les intégrations pour réduire le risque de casser la branche principale au moment du merge.
Point clé : sans pipeline fiable, rapide et lisible, ce mode de travail devient très difficile à tenir.
Pourquoi le Trunk-Based Development est-il présenté comme la suite du module, et non comme un flow à pratiquer tout de suite ?
Parce qu'il suppose déjà une maturité CI/CD importante : tests rapides, build fiable, feedback court et forte discipline d'intégration.
Les prochains cours sur la CI/CD sont justement ce qui permettra de comprendre comment atteindre cette maturité.
Monorepo vs polyrepo — comparaison brève
L'organisation du code en un ou plusieurs dépôts influence directement la complexité des pipelines, la gestion des droits et la cohérence des versions entre composants.
Monorepo
Tout le code vit dans un seul dépôt. On y gagne souvent en cohérence, mais on complexifie plus vite la gestion des droits, la lecture des pipelines et la question des versions compatibles entre plusieurs composants.
Polyrepo
Chaque service ou composant a son dépôt. On gagne en isolation, mais la synchronisation entre versions et la gestion des compatibilités demandent un outillage et une discipline plus visibles.
Tableau comparatif final des flows
Aucun flow n'est universel. Un projet peut très bien évoluer d'un mode très simple vers un flow plus structuré à mesure que la taille de l'équipe, le nombre de versions supportées et l'exigence qualité augmentent.
Sans flow réel : acceptable au tout début d'un prototype individuel, mais fragile.
GitHub Flow : bon point d'entrée dès qu'on veut intégrer souvent sur une ligne courante claire.
GitLab Flow : pertinent dès qu'il faut gérer plusieurs versions actives d'un même produit.
Trunk-Based Development : logique quand la maturité CI/CD permet des intégrations très fréquentes sur un tronc unique.
Cette trajectoire synthétise la progression réaliste d'un projet.
Chargement du schéma…
Git Flow n'apparaît pas dans ce diagramme — où se placerait-il selon vous, et pourquoi ?
Git Flow se placerait entre GitHub Flow et GitLab Flow. Comme GitHub Flow, il part d'une ligne courante unique ; comme GitLab Flow, il gère des branches de maintenance (hotfix, release). Mais son modèle de branches longues et son processus de release formalisé le rendent plus lourd que GitHub Flow sans aller jusqu'à la gestion de versions indépendantes de GitLab Flow.
Il occupe donc une niche particulière : les projets avec des cycles de release planifiés et une équipe suffisamment grande pour justifier ce niveau de formalisme — mais sans nécessairement maintenir plusieurs versions en parallèle pour des clients différents.
Dépôt CI pédagogique — temps 1 : prise en main guidée
Dépôt support : GVI2026/tp-ci-api
Le but n'est pas encore de corriger la pipeline, mais de stabiliser l'environnement de travail et de rendre le dépôt familier avant d'analyser la CI en détail.
- Cloner le dépôt puis l'ouvrir dans VS Code. Si le DevContainer est proposé, l'accepter pour homogénéiser l'environnement.
-
Lancer l'application :
Vérifier ensuite que Swagger répond surnpm run start:devhttp://localhost:3000/api. -
Repérer trois fichiers utiles pour la suite :
.github/workflows/ci.yml,package.jsonet le dossiersrc/. - Faire une première lecture du workflow pour identifier ce qui sera discuté ensuite : triggers, jobs, steps, ordre des vérifications.
Dans .github/workflows/ci.yml, combien de jobs
repérez-vous, et lequel s'exécute en premier ?
Le workflow contient quatre jobs : format-lint,
tests, build et
security. Le premier à s'exécuter est
format-lint, car les autres en dépendent via
needs:.
Repérer cet ordre avant le cours permet de suivre directement l'explication du principe fail-fast sans avoir à chercher dans le fichier en même temps.
DevOps et CI/CD
Les flows que vous venez de voir posent tous la même question en filigrane : comment garder confiance dans les changements quand plusieurs branches, plusieurs versions et plusieurs personnes sont actives en même temps ? DevOps et la CI/CD sont précisément la réponse industrielle à cette question.
DevOps : briser les silos
Pendant longtemps, développement et exploitation fonctionnaient en silos séparés avec des objectifs mesurés différemment. Les développeurs étaient évalués sur la quantité de fonctionnalités livrées ; les équipes d'exploitation sur la stabilité du système. Résultat : chaque mise en production devenait un moment de friction, de ralentissement et de méfiance mutuelle.
DevOps est d'abord une réponse culturelle et organisationnelle : aligner les équipes sur un objectif commun — livrer de la valeur rapidement et de façon fiable. L'outillage (CI/CD, monitoring, infrastructure as code) vient ensuite rendre cette collaboration concrète et répétable.
Le cycle DevOps est continu : on planifie, on code, on vérifie, on package, on déploie, on configure, on surveille… et on replanifie à partir de ce qu'on observe en production.
Chargement du cycle DevOps…
Que se passe-t-il quand un bug critique est découvert en production si Dev et Ops ont des objectifs mesurés séparément ?
L'équipe Dev peut considérer que le bug est "en prod donc c'est un problème Ops". L'équipe Ops peut refuser de déployer un correctif précipité qui risquerait de déstabiliser le système. Personne n'est incité à résoudre rapidement, car la responsabilité partagée n'est pas mesurée.
DevOps supprime cette friction en rendant les deux équipes co-responsables du même résultat : un service stable et évolutif.
Mesurer pour progresser : les métriques DORA
Sans mesure, l'amélioration reste une intuition. Le programme DORA (DevOps Research and Assessment), mené par Google Cloud depuis plus de dix ans sur 40 000+ professionnels, a identifié cinq métriques qui prédisent la performance organisationnelle réelle.
Ces métriques se regroupent en deux axes :
Débit — jusqu'où va la chaîne de livraison ?
Deployment Frequency : à quelle cadence l'équipe déploie en production. Un déploiement par mois est très différent de plusieurs par jour.
Change Lead Time : temps entre le moment où un développeur commite du code et le moment où ce code est en production. Cet indicateur révèle tous les goulots d'étranglement du processus.
Failed Deployment Recovery Time : temps nécessaire pour revenir à un état stable après un déploiement qui a provoqué un incident.
Stabilité — est-ce que ça tient ?
Change Fail Rate : proportion des déploiements qui nécessitent une intervention immédiate — rollback ou hotfix. Un taux élevé signale que la pipeline ne filtre pas assez.
Deployment Rework Rate : proportion des déploiements non planifiés résultant d'un incident en production.
Insight clé de la recherche DORA : rapidité et stabilité ne sont pas en opposition. Les équipes les plus performantes déploient plus souvent et ont moins d'incidents. L'amélioration de l'une tire l'autre vers le haut.
Pensez-vous qu'il est possible de déployer très souvent et d'avoir peu d'incidents en production ?
Oui — et c'est précisément ce que valide la recherche DORA. Déployer souvent force à réduire la taille de chaque changement. Des petits changements sont plus faciles à comprendre, à tester et à réverter si quelque chose cloche.
C'est le principe des petits lots (small batches) : moins on accumule de changements avant un déploiement, moins la probabilité d'un incident complexe à diagnostiquer est élevée.
CI, Continuous Delivery et Continuous Deployment (CD)
Ces trois pratiques forment un spectre progressif : chaque niveau automatise davantage, et chaque niveau suppose que le précédent fonctionne de façon fiable.
Intégration Continue (CI) : chaque commit déclenche automatiquement une vérification — formatage, lint, tests, build. L'objectif est de détecter immédiatement si le changement casse quelque chose dans le projet. Sans CI solide, les deux pratiques suivantes n'ont pas de fondation.
Continuous Delivery : la CI est complétée par une automatisation du packaging et de la préparation à la mise en production. L'artefact est toujours prêt à être déployé. Le déploiement lui-même reste déclenché manuellement — souvent pour des raisons métier ou réglementaires.
Continuous Deployment : le déploiement en production est lui aussi automatisé. Dès qu'un commit passe toutes les vérifications, il part en production sans intervention humaine. Cela suppose une confiance très élevée dans la pipeline et dans les tests.
Chargement du spectre CI/CD…
Quelle est la différence concrète entre Continuous Delivery et Continuous Deployment ?
Dans les deux cas, l'artefact est automatiquement construit, testé et prêt à partir. La différence est dans la dernière étape : en Continuous Delivery, un humain appuie sur le bouton "déployer". En Continuous Deployment, la pipeline le fait toute seule.
Continuous Delivery est souvent préféré dans des contextes réglementés, ou quand une validation métier est requise avant chaque mise en production.
Anatomie d'une pipeline GitHub Actions
Vous pushez un commit. Voici ce qui se passe concrètement côté GitHub Actions.
Un événement
(push, pull_request, ou encore un
planning schedule) déclenche l'exécution d'un
workflow —
un fichier YAML dans .github/workflows/. Ce
workflow décrit un ensemble de
jobs.
Chaque job s'exécute sur sa propre machine virtuelle fraîche,
appelée runner.
À l'intérieur d'un job, les
steps
s'enchaînent séquentiellement. Un step est soit un script
shell (run: npm test), soit une
action
réutilisable (uses: actions/checkout@v4).
Les jobs peuvent avoir des dépendances entre eux via
needs:. L'ensemble des jobs et de leurs dépendances
forme un DAG
(Directed Acyclic Graph) — un graphe orienté sans cycle. Ce
graphe rend visibles à la fois les dépendances obligatoires et
les opportunités de parallélisation.
Chargement de l'anatomie pipeline…
Le principe fail-fast
Placer les vérifications les plus rapides et les moins coûteuses en premier dans la chaîne n'est pas arbitraire : c'est le principe fail-fast. Un job qui échoue arrête immédiatement tous les jobs qui en dépendent. Inutile de compiler si le formatage du code est déjà incorrect. Inutile de scanner les dépendances si les tests unitaires échouent.
Voici la pipeline du dépôt pédagogique. Lisez-la de gauche à droite : chaque flèche en pointillés indique qu'un échec ici stoppera tous les jobs à droite. Les nœuds dans l'ordre représentent le coût croissant du diagnostic — du plus cheap (lint) au plus lourd (scan de sécurité).
Chargement du graphe CI…
Shift-left : détecter tôt, corriger moins cher
Dans un modèle traditionnel, les vérifications arrivent tard : les tests manuels et les audits de sécurité interviennent juste avant la mise en production. À ce stade, corriger un bug est entre 10 et 100 fois plus coûteux qu'en phase de développement, parce que l'auteur du code a changé de contexte, que d'autres fonctionnalités ont été empilées dessus, et que l'impact d'un correctif est plus difficile à isoler.
Le shift-left consiste à avancer toutes les vérifications possibles vers la gauche du cycle de vie du code — le plus tôt possible. Idéalement, une erreur de formatage est détectée avant même le commit, un test cassé est détecté dès le push, et une vulnérabilité critique est détectée avant la mise en production.
La pipeline du dépôt pédagogique applique explicitement ce principe :
1. format-lint — vérification syntaxique et analyse statique. Coût de correction : quelques secondes, aucun contexte perdu.
2. tests — validation du comportement du code. Coût de correction : modéré, mais encore dans le contexte frais du développeur.
3. build — vérification que le code compile réellement. Coût de correction : erreurs de types parfois subtiles à tracer.
4. security — scan des dépendances. Coût de correction : potentiellement élevé si une dépendance critique doit être remplacée, mais au moins détecté avant la prod.
Le feedback loop : la valeur d'une pipeline ne se mesure pas seulement à ce qu'elle détecte, mais à la vitesse à laquelle elle renvoie l'information au développeur. Un retour en 2 minutes permet de corriger immédiatement. Un retour en 45 minutes implique un changement de contexte mental qui multiplie le temps de correction réel.
À quelle étape de la pipeline est-il le moins coûteux de détecter une erreur ?
Le plus tôt possible — idéalement dans le job
format-lint. Une erreur attrapée là prend
quelques secondes à corriger : on édite le fichier, on
relance. Aucun contexte n'est perdu.
À l'inverse, une erreur qui n'est détectée qu'en production oblige à analyser des logs en direct, à réverter un déploiement, parfois à réveiller des personnes. Le coût humain et technique est sans commune mesure.
Environnements : DEV, STAGING, PROD
Une pipeline mène le code d'un environnement à l'autre. Trois repères suffisent pour aujourd'hui :
DEV : environnement local de développement. C'est ici que vous écrivez et testez manuellement. La pipeline part de ce que vous poussez depuis cet environnement.
STAGING : environnement de validation proche de la production. Sert à vérifier le comportement réel de l'application dans des conditions proches des vraies avant une mise en service.
PROD : l'environnement utilisé par les vrais utilisateurs. Une erreur ici a un impact immédiat et visible.
Quel vocabulaire devez-vous maîtriser avant d'entrer dans le TP ?
Event / Trigger : événement qui déclenche la pipeline (push, pull_request, schedule…).
Workflow :
orchestration complète décrite dans un fichier YAML sous .github/workflows/.
Job : unité d'exécution logique tournant sur son propre runner.
Step : action unitaire à l'intérieur d'un job — script shell ou action réutilisable.
Runner : machine virtuelle fraîche qui exécute un job.
DAG : graphe de dépendances entre jobs, qui rend visibles l'ordre d'exécution et les parallélisations possibles.
Fail-fast : principe qui consiste à placer les vérifications les moins coûteuses en premier pour stopper la chaîne dès qu'une erreur est détectée.
Shift-left : stratégie qui avance toutes les vérifications possibles vers le début du cycle de vie du code, réduisant le coût de correction.
Dépôt CI pédagogique — temps 2 : exercices et correction
Le but est maintenant de diagnostiquer puis corriger une CI cassée. Vous travaillez en binôme. Le dépôt a été conçu pour que les pannes soient réalistes, lisibles et rapides à interpréter.
Pipeline de référence à garder en tête
install → format-lint → tests → build → security
L'ordre n'est pas arbitraire. Il sert à détecter vite les erreurs les moins coûteuses à diagnostiquer avant de mobiliser des étapes plus longues.
Commandes utiles pendant le TP
npm run format:check
npm run lint
npm run test:ci
npm run build
act
act -j format-lint
act -j tests
Exercice 1 — corriger une étape qualité simple
Branche : exercise/01-format-lint. L'objectif est de
lire le bon log, puis de corriger un problème de formatage ou de
lint sans modifier inutilement le reste du projet.
Exercice 2 — réparer un test unitaire
Branche : exercise/02-test-failure. L'échec est
volontairement simple à comprendre : vous devez repérer le test,
relire l'intention puis corriger soit le test, soit le code testé.
Exercice 3 — remettre la pipeline dans un ordre fail-fast
Branche : exercise/03-pipeline-order. Le travail
consiste à réorganiser les dépendances de jobs dans
.github/workflows/ci.yml pour retrouver une chaîne
logique et lisible.
Exercice 4 — lire les logs et trouver la bonne cause
Branche : exercise/04-log-reading. Ici, l'enjeu n'est
pas seulement de corriger : il faut surtout savoir lire le bon job,
la bonne step et le bon message d'erreur.
Exercice 5 — stabiliser la chaîne complète
Branche : exercise/05-stabilize. Cette branche sert à
vérifier que vous savez appliquer un ordre de diagnostic cohérent
jusqu'au retour complet au vert.
Bonus — paralléliser une partie simple du DAG
Branche : bonus/parallelization. Ce bonus s'adresse
aux binômes les plus rapides. Le but est de séparer proprement des
vérifications indépendantes sans rendre la lecture du graphe
inutilement compliquée.
Quel ordre de diagnostic devez-vous appliquer quand tout semble cassé ?
Commencez par les étapes qualité les plus précoces, puis les tests, puis le build, puis le reste. L'idée n'est pas d'ouvrir tous les fronts à la fois, mais d'éliminer les causes visibles dans l'ordre où la pipeline les rencontre.
Correction collective et débrief
- Quels échecs étaient visibles en premier ?
- Dans quel job fallait-il lire les logs ?
- Pourquoi l'ordre des jobs n'est-il pas arbitraire ?
- Qu'est-ce qu'une parallélisation utile, et qu'est-ce qui ne l'est pas ?
Conclusion et ouverture
En trois séances, vous êtes passés d'un usage local de Git à des workflows d'équipe structurés, puis à la question que tous ces flows soulèvent : comment garder confiance dans les changements quand les branches, les versions et les intégrations se multiplient ?
La CI répond à la première partie de cette question : détecter vite, corriger tôt, intégrer en confiance. L'autre partie — livrer en production de façon fiable et automatisée — sera l'objet du prochain cours, consacré au Continuous Delivery et au déploiement continu.
Idée directrice à emporter : une pipeline CI qui ne renvoie pas de retour en quelques minutes ne change pas les comportements. La vitesse du feedback est aussi importante que sa fiabilité.