Exercice 05 : Réutiliser des configurations avec extends et ancres
🎯 Objectifs
À la fin de cet exercice, vous serez capable de :
- ✅ Définir un job caché
.job-base(préfixe.) comme template - ✅ Hériter de ce template avec
extends: .job-base - ✅ Utiliser les ancres YAML (
&anchor,*anchor,<<: *anchor) pour partager de la configuration - ✅ Expliquer quand préférer
extends:aux ancres YAML
Durée estimée : 20 minutes
Difficulté : ⭐⭐⭐☆☆ (Intermédiaire)
Prérequis :
- Module GitLab CI Intermédiaire - Exercice 04 complété
- Notions YAML de base
📖 Contexte
Quand plusieurs jobs partagent les mêmes image:, cache:, rules: ou before_script:, la duplication est source d'erreurs. GitLab CI offre deux mécanismes de réutilisation : extends: (spécifique GitLab CI, avec fusion intelligente) et les ancres YAML (standard YAML, fusion directe). Les deux ont des cas d'usage différents.
📋 Énoncé
Créez un pipeline Node.js avec 4 jobs (build, test-unit, test-e2e, lint) qui partagent tous la même image, le même cache et les mêmes règles d'exécution. Factorisez cette configuration avec extends: puis comparez avec les ancres YAML.
🧭 Déroulement de l'exercice
Tâche 1 : Identifier la duplication
Sans aucune factorisation, créez les 4 jobs avec chacun image: node:20-alpine, cache: sur node_modules/ et rules: excluant les MR. Constatez la duplication.
Indice : Sur 4 jobs, vous allez répéter ~10 lignes identiques 4 fois, soit 40 lignes de duplication pure. Si vous changez l'image, vous devez modifier 4 endroits.
Vérification : Le pipeline fonctionne mais le fichier contient beaucoup de répétitions.
Tâche 2 : Créer un job caché .node-base
Créez un job .node-base (le préfixe . empêche GitLab de l'exécuter) qui contient l'image, le cache et les rules communs.
Indice :
`yaml.node-base:
image: node:20-alpine
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- when: on_success
`Les jobs dont le nom commence par
.sont des "jobs cachés". GitLab les ignore lors de l'exécution mais ils peuvent être référencés parextends:.
Vérification : Le job .node-base n'apparaît pas dans le pipeline quand vous poussez.
Tâche 3 : Hériter avec extends
Modifiez les 4 jobs pour qu'ils héritent de .node-base via extends: .node-base. Chaque job ne garde que son stage: et son script: spécifique.
Indice :
`yamlbuild:
extends: .node-base
stage: build
script:
- npm ci
`
extends:fusionne les configurations avec fusion intelligente : les tableaux commescript:sont remplacés (pas concaténés), les clés scalaires du job enfant écrasent celles du parent.
Vérification : Les 4 jobs héritent de l'image et du cache de .node-base. Le pipeline fonctionne identiquement.
Tâche 4 : Utiliser des ancres YAML pour les variables
Créez une ancre YAML &default-vars pour un ensemble de variables communes, et utilisez <<: *default-vars dans les jobs qui en ont besoin.
Indice :
`yaml.default-vars: &default-vars
NODE_ENV: test
CI: "true"
LOG_LEVEL: info
>
test-unit:
variables:
<<: *default-vars
JEST_TIMEOUT: "10000"
`
<<:est l'opérateur de fusion YAML (merge key).*default-varsest la référence à l'ancre&default-vars. Les clés supplémentaires après<<:s'ajoutent aux clés fusionnées.
Vérification : test-unit dispose des variables NODE_ENV, CI, LOG_LEVEL et JEST_TIMEOUT.
Tâche 5 : Comprendre les différences extends vs ancres
Testez ce comportement : avec extends:, un job enfant peut surcharger partiellement un tableau (ex: ajouter une rule: supplémentaire via la clé). Avec les ancres YAML, la fusion des tableaux n'est pas possible - seul <<: fusionne les objets.
Indice :
extends:dans GitLab CI utilise une fusion profonde. Si.node-basearules: [A, B]et que le job enfant déclarerules: [C], le résultat final estrules: [C](remplacement, pas concaténation). Les ancres YAML<<:fusionnent uniquement les clés d'objets (maps), pas les listes.
Vérification : Documentez dans un commentaire YAML la différence observée.
🗂️ Mini-Projet : Pipeline DRY avec extends et ancres
Checkpoints de validation :
.node-basen'apparaît pas dans les pipelines exécutés- Les 4 jobs héritent de l'image et du cache via
extends: - Les variables communes sont factorisées avec une ancre YAML
- Le fichier
.gitlab-ci.ymlest réduit d'au moins 30 lignes - Le comportement du pipeline est identique avant et après factorisation