Aller au contenu
CI/CD & Automatisation medium

Lab 15 — Matrices multi-versions

9 min de lecture

logo gitlab

Un test qui passe sur une seule version Python n’est pas une garantie de compatibilité réelle. Dans ce lab, vous mettez en place une matrice pour exécuter plusieurs combinaisons en parallèle, tout en gardant un flux de build propre avec needs.

  • Créer une matrice avec parallel: matrix
  • Paramétrer l’image via une variable (python:$PYTHON_VERSION)
  • Segmenter les tests en suites complémentaires
  • Garder un enchaînement propre vers le build avec needs

Quand une équipe migre de Python 3.11 vers 3.12, les incompatibilités apparaissent souvent tard, parfois en production. La matrice CI permet de détecter ces écarts plus tôt, sans doubler manuellement les jobs.

Vous utiliserez ce pattern pour :

  • valider une compatibilité multi-versions ;
  • réduire le temps d’exécution via parallélisme ;
  • préparer des stratégies de test plus fines par type de suite.
  1. Basculez sur la branche du lab

    Fenêtre de terminal
    cd pipeline-craft
    git checkout starter/lab-15
  2. Ouvrez ci/test.yml

    Vous devez y voir un job de test mono-version.

  3. Lancez un run baseline

    Fenêtre de terminal
    git push origin starter/lab-15

Le pipeline valide un seul environnement Python. Il ne détecte donc pas les divergences d’interpréteur, et la phase de test reste plus longue qu’elle ne devrait.

  1. Modifiez le job pytest en job matriciel

    Indice : renommez le job pour refléter son rôle matriciel.

  2. Paramétrez l’image avec la variable

    Indice : l’image Python doit dépendre de la dimension PYTHON_VERSION.

  3. Gardez un script qui route selon TEST_SUITE

    L’objectif est d’éviter la duplication de jobs tout en conservant des suites ciblées.

👉 Vérifier votre solution (Étape 1)
pytest-matrix:
extends: .python-base
stage: test
parallel:
matrix:
- PYTHON_VERSION: ["3.11-slim", "3.12-slim"]
TEST_SUITE: ["core", "api"]
image: python:$PYTHON_VERSION
needs: []
before_script:
- pip install -r requirements-dev.txt
script:
- |
if [ "$TEST_SUITE" = "core" ]; then
pytest -v tests/test_health.py tests/test_version.py --junitxml=report.xml --cov=app --cov-report=term-missing
else
pytest -v tests/test_items.py --junitxml=report.xml --cov=app --cov-report=term-missing
fi
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
artifacts:
when: always
paths:
- report.xml
reports:
junit: report.xml
expire_in: 7 days

La matrice produit 4 combinaisons : 2 versions Python x 2 suites de tests.

Étape 2 — Aligner le build sur la fin des tests

Section intitulée « Étape 2 — Aligner le build sur la fin des tests »
  1. Mettez à jour le job de build

    Indice : le build doit dépendre explicitement du job matriciel.

  2. Vérifiez que le build attend bien le succès global de la matrice

    Aucun build ne doit démarrer si une combinaison échoue.

👉 Vérifier votre solution (Étape 2)
docker-build:
stage: build
needs:
- pytest-matrix
image: docker:27
services:
- docker:27-dind
variables:
<<: *docker_vars
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker build -t $CI_REGISTRY_IMAGE:latest .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
  1. Validez la config

    Fenêtre de terminal
    glab ci lint .gitlab-ci.yml
  2. Committez les changements

    Fenêtre de terminal
    git add ci/test.yml ci/build.yml
    git commit -m "ci: add matrix testing across python versions"
    git push origin starter/lab-15
  3. Vérifiez l’UI pipeline

    Vous devez voir 4 jobs de test issus de la matrice.

👉 Vérifier votre solution (Étape 3)
  • 4 jobs de test sont créés automatiquement (2 x 2) ;
  • chaque job affiche ses variables de matrice (PYTHON_VERSION, TEST_SUITE) ;
  • docker-build démarre seulement après succès de toutes les combinaisons.
📄 Voir le fichier .gitlab-ci.yml complet
stages:
- lint
- test
- build
- deploy
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_TAG
default:
interruptible: true
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.pip-cache"
include:
- local: ci/lint.yml
- local: ci/test.yml
- local: ci/build.yml
- local: ci/deploy.yml
📄 Voir le fichier ci/test.yml complet
pytest-matrix:
extends: .python-base
stage: test
parallel:
matrix:
- PYTHON_VERSION: ["3.11-slim", "3.12-slim"]
TEST_SUITE: ["core", "api"]
image: python:$PYTHON_VERSION
needs: []
before_script:
- pip install -r requirements-dev.txt
script:
- |
if [ "$TEST_SUITE" = "core" ]; then
pytest -v tests/test_health.py tests/test_version.py --junitxml=report.xml --cov=app --cov-report=term-missing
else
pytest -v tests/test_items.py --junitxml=report.xml --cov=app --cov-report=term-missing
fi
coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
artifacts:
when: always
paths:
- report.xml
reports:
junit: report.xml
expire_in: 7 days
📄 Voir le fichier ci/build.yml complet
.docker-vars: &docker_vars
DOCKER_TLS_CERTDIR: "/certs"
docker-build:
stage: build
needs:
- pytest-matrix
image: docker:27
services:
- docker:27-dind
variables:
<<: *docker_vars
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker build -t $CI_REGISTRY_IMAGE:latest .
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
- docker push $CI_REGISTRY_IMAGE:latest
  • 4 jobs de test sont visibles (2 versions x 2 suites)
  • Les jobs de test s’exécutent en parallèle
  • Le build dépend du succès de la matrice
  • Le temps global est comparable à un run mono-suite

La matrice peut exploser rapidement en nombre de combinaisons. Ajoutez une dimension seulement si elle apporte une information de qualité utile.

Pensez aussi à nommer clairement vos variables de matrice pour garder des logs lisibles.

  • parallel: matrix permet de scaler les tests sans dupliquer les jobs
  • Un build fiable dépend du succès global des combinaisons
  • Le parallélisme réduit la latence de feedback
  • La matrice est un outil de confiance, pas un objectif en soi

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn