Matrix GitHub Actions : guide pratique des tests parallèles multi-plateformes et multi-versions

L’année dernière, un projet open source m’a contacté : leur fichier de configuration CI avait gonflé à plus de 800 lignes. Je l’ai ouvert — des définitions de job répétées partout : Node 16 sur Ubuntu, Node 16 sur Windows, Node 16 sur macOS… puis Node 18, puis Node 20. Modifier une commande de test ? Douze endroits à toucher. Ajouter une version ? Quinze minutes de copier-coller.
À ce moment-là, j’ai réalisé que beaucoup de monde maintient encore à la main des tests multi-versions et multi-plateformes.
Le Matrix de GitHub Actions, en résumé, déploie automatiquement ces configurations répétitives. Vous définissez quelques systèmes d’exploitation et quelques versions de runtime, et il exécute toutes les combinaisons. Ça a l’air simple, mais en pratique les pièges sont nombreux — explosion du nombre de combinaisons et facture qui explose, un échec qui fait tout tomber, exclusion d’une combinaison spécifique mal comprise… Je suis passé par là.
Cet article part de la syntaxe Matrix la plus basique pour vous faire maîtriser exclude/include, le choix de fail-fast, la limitation de concurrence avec max-parallel, et la génération dynamique de Matrix. À la fin, 5 modèles de workflow prêts à copier dans votre projet, du projet perso à l’entreprise.
2. Concepts clés du Matrix : déployer plusieurs tâches en un clic
La logique du Matrix est simple : vous définissez des dimensions, GitHub Actions calcule le produit cartésien.
Par exemple, votre projet doit être testé sur Ubuntu, Windows et macOS, avec Node.js 18, 20 et 22. En écriture classique, 9 jobs à la main, chacun répétant environnement, installation et tests. Avec Matrix :
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20, 22]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm test
Ces 10 lignes deviennent 3 x 3 = 9 tâches parallèles. Chaque tâche reçoit des valeurs différentes pour matrix.os et matrix.node.
Le projet à 800 lignes de config ? Refactoré avec Matrix, environ 120 lignes — plus de 60 % de code en moins. Ajouter une version : un chiffre dans le tableau, plus de copier-coller de jobs.
Ce que Matrix vous apporte :
- Générer d’un coup les combinaisons multi-plateformes et multi-versions
- Déployer toute la config sans duplication manuelle
- Exclure les combinaisons connues comme problématiques via exclude
- Ajouter des cas avec configuration spéciale via include
- Contrôler la concurrence pour équilibrer vitesse et coût
Ce qu’il ne résout pas :
- Des tests mal écrits — Matrix ne les sauvera pas
- Trop de combinaisons et facture qui explose — à vous de maîtriser les dimensions
- Installation lente des dépendances — à combiner avec la mise en cache
Franchement, Matrix n’est pas difficile à comprendre ; le dur, c’est l’appliquer aux vrais projets. On commence par la syntaxe de base.
3. Syntaxe de base : principe os x version
Les combinaisons Matrix, c’est le produit cartésien : chaque dimension se combine avec les autres.
Une dimension, N valeurs -> N tâches
Deux dimensions, M x N valeurs -> M x N tâches
Trois dimensions, A x B x C valeurs -> A x B x C tâches
Exemple concret : projet Python à tester sur Linux et Windows, Python 3.9 à 3.12, avec PostgreSQL et MySQL :
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.9', '3.10', '3.11', '3.12']
database: [postgresql, mysql]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Setup ${{ matrix.database }}
run: |
# Démarrer le service de base de données correspondant
if [ "${{ matrix.database }}" = "postgresql" ]; then
docker run -d -p 5432:5432 postgres
else
docker run -d -p 3306:3306 mysql
fi
shell: bash
- run: pip install -r requirements.txt
- run: pytest
Cette config génère 2 x 4 x 2 = 16 tâches, chacune dans un environnement isolé.
Accéder aux variables Matrix :
${{ matrix.os }}— système d’exploitation de la tâche courante${{ matrix.python-version }}— version Python${{ matrix.database }}— type de base de données
Ces variables servent dans runs-on, steps, env, etc.
Piège fréquent : beaucoup pensent que Matrix gère automatiquement les dépendances. Chaque tâche est un environnement neuf — l’installation se répète. Si l’install prend 2 minutes, 16 tâches = 32 minutes d’attente (en séquentiel).
Deux pistes :
- Cache — mettre en cache pip ou npm pour éviter les retéléchargements
- Moins de combinaisons — exclude pour retirer les tests superflus
J’ai détaillé la stratégie de cache dans [Stratégie de cache GitHub Actions : accélérer le pipeline CI/CD par 5]. Ici, on se concentre sur exclude/include.
4. exclude/include : contrôler finement les combinaisons
Par défaut, Matrix fait le produit cartésien complet. En pratique, certaines combinaisons sont inutiles ou demandent un traitement spécial.
4.1 exclude : écarter les combinaisons invalides
Sur un projet Python : Windows + Python 3.9 échouait toujours — une dépendance incompatible sur Windows en 3.9. Le projet cible surtout Linux ; Windows est secondaire, pas la peine de corriger ce bug précis.
exclude entre en jeu :
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.9', '3.10', '3.11', '3.12']
exclude:
- os: windows-latest
python-version: '3.9'
- os: macos-latest
python-version: '3.9'
On retire Python 3.9 sur Windows et macOS. 12 tâches au départ, 10 après exclusion.
Cas typiques pour exclude :
- Problème de compatibilité connu — une version ne tourne pas sur un OS
- Limite de ressources — peu de runners self-hosted, réduire les combinaisons
- Cas marginaux — combinaisons rarement utilisées, pas worth le temps CI
4.2 include : ajouter une configuration spéciale
include fait l’inverse — combinaisons supplémentaires ou variables en plus.
Exemple : activer le rapport de couverture uniquement sur Python 3.12 :
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
include:
- python-version: '3.12'
coverage: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pip install -r requirements.txt
- name: Run tests
run: |
if [ "${{ matrix.coverage }}" = "true" ]; then
pytest --cov=src --cov-report=xml
else
pytest
fi
shell: bash
include ici :
- Ajoute une combinaison — test Python 3.12
- Ajoute une variable —
coverage: true
Cas typiques pour include :
- Version expérimentale — ex. Python 3.13 preview sur un seul OS
- Config spéciale — variables ou paramètres supplémentaires
- Couverture des cas rares — combinaisons peu fréquentes ajoutées à la main
4.3 exclude et include ensemble
Souvent les deux : exclure tout Python 3.9, mais garder un test minimal Ubuntu + Python 3.9 :
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.9', '3.10', '3.11', '3.12']
exclude:
- python-version: '3.9'
include:
- os: ubuntu-latest
python-version: '3.9'
minimal: true
Ordre d’exécution : toutes les combinaisons -> exclude -> include. Résultat : 4 versions sur Ubuntu, 3 sur Windows (sans 3.9).
5. Stratégie fail-fast : échec rapide vs débogage complet
Par défaut, si une tâche Matrix échoue, les autres en cours sont annulées. C’est fail-fast, activé par défaut.
strategy:
fail-fast: true # valeur par défaut, peut être omis
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20, 22]
5.1 Quand utiliser fail-fast: true (défaut)
Tests PR — vous voulez savoir vite si ça casse. Un échec, les autres suivront souvent (même bug de code), inutile de continuer.
Budget serré — quota GitHub Actions limité, runners self-hosted limités. fail-fast économise.
Mon habitude : fail-fast: true en PR, fail-fast: false sur les tests complets de main.
5.2 Quand utiliser fail-fast: false
Phase de débogage — vous voulez voir quelles combinaisons échouent et pourquoi. Avec fail-fast: true, seule la première échec visible.
Tests de compatibilité — chaque combinaison compte, même si une version pose problème.
Rapport complet — un bilan de toutes les combinaisons après le CI.
strategy:
fail-fast: false # laisser toutes les tâches se terminer
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [18, 20, 22]
5.3 Cas réel
L’année dernière, CI qui échouait sur Ubuntu + Node 18 alors que le reste passait. Avec fail-fast par défaut, à chaque run on ne voyait que cet échec puis annulation. Passage à fail-fast: false : Windows + Node 18 OK, seul Ubuntu posait problème — casse de casse dans les chemins de fichiers.
Conseil : débogage avec fail-fast: false ; en production stable, fail-fast: true pour économiser temps et argent.
6. max-parallel : concurrence et optimisation des coûts
Les tâches Matrix tournent en parallèle par défaut. Runners GitHub hébergés : limite 20 en public ; privé gratuit : 2.
Parfois il faut limiter manuellement — max-parallel.
6.1 Quand limiter la concurrence
Runners self-hosted limités — serveur 4 cœurs / 8 Go, 8 tâches simultanées le tuent.
Rate limiting API tierce — tests qui appellent une API avec quota QPS.
Pool de connexions DB — 10 connexions max, trop de tâches = épuisement.
strategy:
max-parallel: 4 # maximum 4 tâches en parallèle
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20, 22]
6 tâches générées, 4 max en parallèle. Une finit, une autre démarre.
6.2 Exemple de calcul de coût
Projet : 3 OS x 4 versions Node = 12 tâches, ~10 minutes chacune.
Sans limite (runners suffisants) :
- 12 tâches en parallèle
- Durée totale ~10 minutes
- Temps de calcul = 12 x 10 = 120 minutes
Avec max-parallel: 4 :
- 12 tâches en 3 vagues
- Durée totale ~30 minutes
- Temps de calcul = 120 minutes (inchangé)
max-parallel ne réduit pas le temps de calcul total, seulement la durée du pipeline. Pourquoi l’utiliser ?
Coût de pic et limites de ressources.
GitHub facture les minutes ; en self-hosted ou cloud au pic, la concurrence compte. 12 tâches = 12 connexions DB ; par vagues de 4, il en faut 4.
Mon expérience :
- Dépôt public, runners GitHub : pas besoin de max-parallel
- Privé, quota gratuit :
max-parallel: 2 - Self-hosted : selon la machine, 4 cœurs → 2–4 en parallèle
7. Matrix dynamique : fromJSON en profondeur
Jusqu’ici, Matrix statique dans le YAML. Parfois il faut générer les combinaisons selon les changements de code.
Monorepo avec plusieurs services : ne tester que ceux touchés par le commit.
7.1 Workflow en deux étapes
Pas de syntaxe « matrix dynamique » native — un job produit la config, un autre l’utilise via fromJSON().
jobs:
# Étape 1 : détecter les services modifiés et générer la config matrix
detect:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2 # récupérer le commit précédent
- name: Detect changed services
id: set-matrix
run: |
# Fichiers modifiés dans ce commit
CHANGED_FILES=$(git diff --name-only HEAD^ HEAD)
# Déterminer quels services ont changé
SERVICES="[]"
if echo "$CHANGED_FILES" | grep -q "services/auth/"; then
SERVICES=$(echo $SERVICES | jq '. + ["auth"]')
fi
if echo "$CHANGED_FILES" | grep -q "services/api/"; then
SERVICES=$(echo $SERVICES | jq '. + ["api"]')
fi
if echo "$CHANGED_FILES" | grep -q "services/web/"; then
SERVICES=$(echo $SERVICES | jq '. + ["web"]')
fi
# Si aucun service modifié, tester tous par défaut
if [ "$SERVICES" = "[]" ]; then
SERVICES='["auth", "api", "web"]'
fi
echo "matrix={\"service\":$(echo $SERVICES)}" >> $GITHUB_OUTPUT
# Étape 2 : utiliser le matrix généré dynamiquement
test:
needs: detect
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJSON(needs.detect.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- name: Test ${{ matrix.service }}
run: |
cd services/${{ matrix.service }}
npm install
npm test
Fonctionnement :
- Job
detect: répertoires modifiés - Génération JSON du matrix
- Job
test:fromJSON()et tâches correspondantes
7.2 Cas d’usage du matrix dynamique
Monorepo — seulement les services modifiés
Déploiement à la demande — Dockerfile changé → build des images concernées
Optimisation — matrix complet seulement si package.json change
Pièges que j’ai vus :
fromJSON()uniquement sur la valeur destrategy.matrix- JSON valide, ex.
{"service": ["auth", "api"]} - Matrix vide = erreur workflow — prévoir une valeur par défaut
8. Bibliothèque de modèles : 5 workflows de production
Cinq modèles copiables, du projet perso à l’entreprise.
8.1 Modèle 1 : tests Node.js multi-versions (base)
Scénario : lib ou app Node.js, plusieurs versions Node
name: Node.js CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [18, 20, 22, 23]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run build --if-present
- run: npm test
- name: Upload coverage
if: matrix.node-version == 22
uses: codecov/codecov-action@v4
Points clés :
npm ciplutôt quenpm installpour verrouiller les versions- Couverture uploadée seulement sur Node 22
cache: 'npm'pour accélérer l’install
8.2 Modèle 2 : Python multi-plateformes et multi-versions (intermédiaire)
Scénario : projet Python, tests cross-OS et cross-version
name: Python CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.10', '3.11', '3.12']
exclude:
- os: windows-latest
python-version: '3.10' # problème de compatibilité connu
steps:
- uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: pytest -v
- name: Lint check
run: |
pip install ruff
ruff check .
Points clés :
excludepour combinaisons connues comme problématiquescache: 'pip'- Lint avec ruff
8.3 Modèle 3 : exclude/include fin (avancé)
Scénario : contrôle fin, exclusions et tests spéciaux
name: Advanced Matrix
on:
push:
branches: [main]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12']
exclude:
# Exclure Windows + Python 3.10 (problème connu)
- os: windows-latest
python-version: '3.10'
include:
# Test expérimental : Ubuntu + Python 3.13 preview
- os: ubuntu-latest
python-version: '3.13-dev'
experimental: true
# Rapport de couverture pour Python 3.12
- python-version: '3.12'
coverage: true
continue-on-error: ${{ matrix.experimental == true }}
steps:
- uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- run: pip install -r requirements.txt
- name: Run tests
run: |
if [ "${{ matrix.coverage }}" = "true" ]; then
pytest --cov=src --cov-report=xml
else
pytest
fi
shell: bash
Points clés :
continue-on-errorpour tests expérimentauxincludepour nouvelles combinaisons et variablesshell: bashpour cohérence Windows/Linux
8.4 Modèle 4 : matrix dynamique + cache (avancé)
Scénario : monorepo, combinaisons selon les fichiers modifiés
name: Dynamic Matrix CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
detect:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Detect changed packages
id: set-matrix
run: |
CHANGED_FILES=$(git diff --name-only HEAD^ HEAD)
PACKAGES="[]"
for dir in packages/*/; do
pkg=$(basename $dir)
if echo "$CHANGED_FILES" | grep -q "^packages/$pkg/"; then
PACKAGES=$(echo $PACKAGES | jq ". + [\"$pkg\"]")
fi
done
# Sans changement, tester tous les packages
if [ "$PACKAGES" = "[]" ]; then
PACKAGES='["core", "utils", "cli"]'
fi
echo "matrix={\"package\":$(echo $PACKAGES)}" >> $GITHUB_OUTPUT
test:
needs: detect
runs-on: ubuntu-latest
strategy:
matrix: ${{ fromJSON(needs.detect.outputs.matrix) }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build --if-present
- name: Test ${{ matrix.package }}
run: |
cd packages/${{ matrix.package }}
npm test
Points clés :
fetch-depth: 2pour comparer au commit précédentjqpour manipuler le JSON- Valeur par défaut si aucun changement
8.5 Modèle 5 : self-hosted + max-parallel (entreprise)
Scénario : runners self-hosted, concurrence et ressources strictes
name: Enterprise CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: [self-hosted, linux, x64]
strategy:
fail-fast: true
max-parallel: 4
matrix:
java-version: [11, 17, 21]
database: [postgresql, mysql]
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
mysql:
image: mysql:8
env:
MYSQL_ROOT_PASSWORD: root
ports:
- 3306:3306
options: >-
--health-cmd "mysqladmin ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4
- name: Setup Java ${{ matrix.java-version }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java-version }}
distribution: 'temurin'
cache: 'maven'
- name: Run tests with ${{ matrix.database }}
env:
DB_TYPE: ${{ matrix.database }}
DB_HOST: localhost
DB_PORT: ${{ matrix.database == 'postgresql' && 5432 || 3306 }}
run: mvn test -Dspring.profiles.active=${{ matrix.database }}
- name: Archive test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-${{ matrix.java-version }}-${{ matrix.database }}
path: target/surefire-reports
Points clés :
runs-on: [self-hosted, linux, x64]max-parallel: 4pour protéger le serveurservicespour les bases de testif: always()pour archiver même en échec
9. Pièges courants et bonnes pratiques
Quelques pièges après des années de Matrix.
9.1 Piège 1 : explosion des combinaisons
Le pire vu : 4 OS x 5 runtimes x 3 bases x 2 caches = 120 tâches. 45 minutes par CI, facture qui explose.
Solutions :
- Matrix complet sur main seulement ; PR avec combinaisons clés
excludepour les cas marginaux- Chaque dimension est-elle vraiment nécessaire — 4 OS ?
# PR : combinaisons clés uniquement
on:
pull_request:
branches: [main]
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest] # PR : Ubuntu seulement
node: [20] # PR : Node 20 seulement
9.2 Piège 2 : fail-fast bloque le débogage
fail-fast: true par défaut : un échec, tout s’arrête — pas de rapport complet.
Solution : fail-fast: false en débogage, puis remettre true.
Ou via variable :
strategy:
fail-fast: ${{ github.event_name == 'pull_request' }}
9.3 Piège 3 : pas de cache
Matrix répète le même job : réinstaller à chaque fois coûte cher. 12 combinaisons x 2 min d’install = 24 minutes rien que pour l’install.
Solution : cache GitHub Actions ou action dédiée.
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm' # activer le cache npm
9.4 Synthèse des bonnes pratiques
Pratique 1 : Matrix réduit en PR + Matrix complet sur main
jobs:
test:
strategy:
matrix:
# PR : combinaisons clés uniquement
${{ github.event_name == 'pull_request' && fromJSON('{"os":["ubuntu-latest"],"node":[20]}') || fromJSON('{"os":["ubuntu-latest","windows-latest","macos-latest"],"node":[18,20,22]}') }}
Pratique 2 : exclude pour les combinaisons connues
Problème sur une combinaison : exclude d’abord, note pour corriger plus tard.
Pratique 3 : cache pour réduire le temps d’install
L’install des dépendances domine souvent — le cache passe de minutes à secondes.
Pratique 4 : nommer les combinaisons
Par défaut test (ubuntu-latest, 20) — personnalisez avec name :
jobs:
test:
name: Test (${{ matrix.os }}, Node ${{ matrix.node }})
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20, 22]
Plus lisible dans l’interface GitHub Actions.
10. Conclusion
Le Matrix GitHub Actions est l’outil idéal pour les tests multi-plateformes et multi-versions. En bref : définir les dimensions, contrôler les combinaisons, gérer la concurrence, générer dynamiquement.
Trop de projets maintiennent encore des configs CI dupliquées — une commande à changer à dix endroits. Matrix compresse des centaines de lignes en quelques dizaines.
Rappel :
- Syntaxe : produit cartésien avec
matrix.osetmatrix.node - Contrôle :
excludeetinclude - Stratégie :
fail-fastfalse en débogage, true en prod - Concurrence :
max-parallelpour self-hosted et coûts - Dynamique :
fromJSON()pour tester à la demande
Les 5 modèles sont copiables tels quels, du Node.js simple au self-hosted entreprise.
Si vous débutez, partez du modèle 1, ajoutez exclude/include, puis le dynamique. Pas tout d’un coup.
Questions en commentaire, ou doc officielle GitHub Actions. Partagez vos astuces Matrix si vous en avez.
Configurer le Matrix GitHub Actions pour tests multi-plateformes
Configurer une stratégie Matrix pour des tests automatisés cross-OS et cross-version
⏱️ Estimated time: 30 min
- 1
Step 1: Définir les dimensions Matrix
Ajoutez strategy.matrix au job du workflow :
```yaml
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20, 22]
```
Cela génère 2 x 3 = 6 tâches parallèles. - 2
Step 2: Utiliser les variables Matrix
Référencez les variables dans runs-on et steps :
```yaml
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
```
Chaque tâche reçoit automatiquement os et node correspondants. - 3
Step 3: Exclure des combinaisons (optionnel)
Utilisez exclude pour les combinaisons problématiques :
```yaml
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: [18, 20, 22]
exclude:
- os: windows-latest
node: 18
```
Exclut Windows + Node 18, il reste 5 tâches. - 4
Step 4: Configurer la stratégie d'échec
Choisissez fail-fast selon le contexte :
- Tests PR : fail-fast: true (échec rapide, économie)
- Débogage : fail-fast: false (voir tous les échecs)
- Branche main : fail-fast: false (rapport complet)
```yaml
strategy:
fail-fast: false
matrix:
# ...
``` - 5
Step 5: Limiter la concurrence (optionnel)
Avec runners self-hosted ou ressources limitées :
```yaml
strategy:
max-parallel: 4
matrix:
# ...
```
Au maximum 4 tâches simultanées, évite la surcharge du runner.
FAQ
Y a-t-il une limite au nombre de combinaisons Matrix ?
Quelle est la valeur par défaut de fail-fast ?
Quel est l'ordre d'exécution de exclude et include ?
Où peut-on utiliser fromJSON() pour un matrix dynamique ?
max-parallel réduit-il le temps de calcul total ?
Les tâches Matrix partagent-elles le cache ?
Comment nommer personnaliser les tâches Matrix ?
• name: Test (${{ matrix.os }}, Node ${{ matrix.node }})
L'interface affichera par ex. "Test (ubuntu-latest, Node 20)" pour identifier chaque tâche.
13 min de lecture · Publié le: 28 avr. 2026 · Mis à jour le: 27 juil. 2026
Guide complet GitHub Actions
Si vous arrivez depuis la recherche, le plus rapide est de passer à l’article précédent ou suivant de cette série.
Précédent
Matrix GitHub Actions : tests parallèles multi-versions en pratique
Tutoriel pratique du Matrix GitHub Actions : syntaxe de base, filtres exclude/include, optimisation fail-fast et contrôle des ressources max-parallel, avec un modèle complet de pipeline de tests parallèles multi-versions.
Partie 4 sur 10
Suivant
Stratégies de déploiement GitHub Actions : du VPS aux plateformes cloud
Trois stratégies de déploiement avec GitHub Actions : SSH vers VPS, hébergement managé (Vercel/Cloudflare/Netlify) et architecture hybride, avec workflows complets et guide de dépannage
Partie 6 sur 10



Commentaires
Connectez-vous avec GitHub pour laisser un commentaire