Bonnes pratiques
Mettre en cache les dépendances
Chaque fois qu'un workflow tourne, GitHub Actions télécharge tes dépendances depuis internet. Avec le cache, ces téléchargements sont évités si les fichiers de lock n'ont pas changé. Résultat : des workflows deux à cinq fois plus rapides.
L'action actions/cache sauvegarde un dossier entre les exécutions.
La clé de cache inclut un hash du fichier de lock — elle se régénère automatiquement quand les dépendances changent.
- name: Cache node_modules
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Installer les dépendances
run: npm ci
# Python — cache pip
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
# PHP — cache Composer
- name: Cache Composer
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles('composer.lock') }}
Pour Node.js, l'action actions/setup-node intègre directement le cache via l'option
cache: 'npm' — pas besoin d'ajouter actions/cache séparément.
C'est la méthode recommandée pour les projets Node.
Les matrices de tests
La stratégie matrix permet de lancer le même job en parallèle sur plusieurs configurations :
plusieurs versions de Node, plusieurs OS, plusieurs navigateurs.
Tu multiplies la couverture sans dupliquer le code du workflow.
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
fail-fast: false # continuer même si une combinaison échoue
steps:
- uses: actions/checkout@v4
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm test
Avec cet exemple, GitHub Actions lance 6 jobs en parallèle (3 versions × 2 OS).
Si une combinaison échoue, fail-fast: false laisse les autres se terminer — utile pour voir
exactement sur quelles configurations les tests cassent.
Tu peux aussi exclure certaines combinaisons avec exclude: ou en ajouter
des spécifiques avec include:. Pratique pour éviter de tester des combinaisons
qui n'ont pas de sens (ex. une version Windows uniquement pour Node 20).
Réutiliser des workflows
Quand plusieurs dépôts partagent la même logique CI (tests, lint, déploiement),
copier-coller le YAML partout devient un cauchemar à maintenir.
GitHub Actions propose deux solutions : les workflows réutilisables (workflow_call)
et les actions composites.
on:
workflow_call: # ce workflow peut être appelé par d'autres
inputs:
node-version:
required: false
type: string
default: '20'
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'npm'
- run: npm ci && npm test
jobs:
run-tests:
uses: mon-org/shared-workflows/.github/workflows/reusable-test.yml@main
with:
node-version: '22'
Timeouts pour éviter les workflows bloqués
Un test qui attend indéfiniment, une connexion réseau qui ne répond pas, une tâche bloquée sur une entrée interactive — sans timeout, le job tourne jusqu'à la limite GitHub (6 heures) et consomme inutilement des minutes de CI.
Définis timeout-minutes au niveau du job ou d'un step individuel.
Choisir une valeur raisonnable selon la durée habituelle du job.
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 15 # timeout pour tout le job
steps:
- name: Tests e2e
run: npm run test:e2e
timeout-minutes: 10 # timeout pour ce step uniquement
Sans timeout-minutes, un job peut tourner jusqu'à 6 heures par défaut sur GitHub.
Cela consomme ton quota de minutes CI gratuites et bloque les autres workflows en attente.
Mets toujours un timeout adapté, même conservateur.
Permissions minimales
Par défaut, le token GITHUB_TOKEN a des permissions en écriture sur le dépôt.
Si un job est compromis (dépendance malveillante, injection de commande), l'attaquant peut
modifier le code, créer des releases, etc.
La bonne pratique : déclarer des permissions explicites au niveau du workflow ou du job, en accordant uniquement ce qui est nécessaire.
# Permissions globales restrictives pour tout le workflow
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
# Ce job hérite de "contents: read" — suffisant pour les tests
steps:
- uses: actions/checkout@v4
- run: npm ci && npm test
deploy:
runs-on: ubuntu-latest
# Ce job a besoin d'écrire des packages
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- run: docker push ghcr.io/mon-org/mon-app:latest
Pinning des actions à un SHA
Quand tu écris uses: actions/checkout@v4, tu utilises un tag Git mutable.
Si le mainteneur de l'action pousse du code malveillant sur ce tag (attaque supply chain),
ton workflow exécuterait ce code sans que tu le voies.
La solution : épingler l'action à son hash de commit SHA, qui est immuable. Un tag peut bouger, un SHA ne change jamais.
# Moins sûr — le tag v4 peut pointer vers un nouveau commit demain
- uses: actions/checkout@v4
# Plus sûr — SHA immuable + commentaire pour savoir quelle version
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
Le pinning SHA est surtout important pour les dépôts publics ou les pipelines de production
critiques. Pour des projets personnels ou d'apprentissage, @v4 est acceptable.
Des outils comme Dependabot ou Renovate peuvent automatiser la mise à jour des SHA pinned.
Récapitulatif du module
En six leçons, tu as parcouru l'essentiel de GitHub Actions :
- Leçon 01 — Comprendre les concepts : workflow, job, step, runner, déclencheurs.
- Leçon 02 — Écrire ton premier workflow CI : linter, tests automatiques à chaque push.
- Leçon 03 — Utiliser les secrets et variables d'environnement de façon sécurisée.
- Leçon 04 — Construire et publier des images Docker sur le GitHub Container Registry.
- Leçon 05 — Déployer automatiquement sur un serveur via SSH ou un service cloud.
- Leçon 06 — Optimiser et sécuriser : cache, matrices, réutilisation, timeouts, permissions, pinning.
Prochaines étapes
GitHub Actions est souvent le point d'entrée vers des pratiques DevOps plus avancées. Voici ce que tu peux explorer ensuite :
- Ansible — automatiser la configuration de tes serveurs (installation de paquets, gestion des fichiers de config, déploiements répétables).
- Terraform — provisionner ton infrastructure cloud (VMs, bases de données, réseaux) sous forme de code versionné.
- Kubernetes — orchestrer des conteneurs Docker à grande échelle, avec gestion automatique de la disponibilité.
- OpenID Connect (OIDC) — s'authentifier auprès des fournisseurs cloud (AWS, GCP, Azure) sans stocker de clé secrète dans les secrets GitHub.
- Cache les dépendances avec
actions/cacheou l'optioncache:desetup-node— gain de temps significatif. strategy.matrixlance le même job sur plusieurs configurations en parallèle sans dupliquer le YAML.workflow_callpermet de centraliser la logique CI dans un workflow réutilisable appelé par d'autres dépôts.- Définis toujours un
timeout-minutespour éviter les jobs bloqués qui consomment ton quota. - Déclare des
permissions:minimales par job — le principe du moindre privilège. - Épingle les actions à un SHA immuable plutôt qu'à un tag mutable pour sécuriser ta supply chain.