GitHub Actions CI/CD : Créer, tester et déployer des workflows de zéro
Apprenez à configurer GitHub Actions pour l'intégration et le déploiement continus. Couvre les déclencheurs, les jobs, les matrices, les secrets, la mise en cache, Docker et des exemples de workflows concrets.
GitHub Actions transforme chaque push, pull request et merge en pipeline automatisé — exécutant les tests, compilant les artefacts, analysant les vulnérabilités et déployant en production. C'est la plateforme CI/CD intégrée directement dans votre dépôt, sans aucune infrastructure à gérer.
Comment fonctionne GitHub Actions
Chaque workflow est un fichier YAML dans .github/workflows/. Lorsqu'un événement déclencheur se produit, GitHub lance une machine virtuelle fraîche, exécute vos jobs et rapporte les résultats — le tout en quelques secondes.
Push vers main
↓
Workflow déclenché
↓
Job : Build & Test (ubuntu-latest)
├── Étape 1 : Checkout du code
├── Étape 2 : Installation de Node.js
├── Étape 3 : npm ci
├── Étape 4 : npm test
└── Étape 5 : npm run build
↓
✅ Toutes les vérifications réussies
Votre premier workflow
Créez .github/workflows/ci.yml :
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm test
- run: npm run build
C'est tout. Chaque push vers main et chaque PR exécute désormais automatiquement votre suite de tests.
Déclencheurs : quand les workflows s'exécutent
Événements de code
on:
push:
branches: [main, develop]
paths: ['src/**', 'package.json'] # S'exécute uniquement si ces fichiers changent
pull_request:
types: [opened, synchronize]
Planification (cron)
on:
schedule:
- cron: '0 6 * * 1' # Tous les lundis à 6h00 UTC
Déclenchement manuel
on:
workflow_dispatch:
inputs:
environment:
description: 'Cible de déploiement'
required: true
type: choice
options: [staging, production]
Cela ajoute un bouton « Run workflow » dans l'interface GitHub où vous pouvez sélectionner des paramètres.
Workflows réutilisables
on:
workflow_call:
inputs:
node-version:
type: string
default: '20'
Appelez-le depuis un autre workflow avec uses: ./.github/workflows/reusable.yml.
Jobs et étapes
Jobs parallèles
Les jobs s'exécutent en parallèle par défaut :
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
build:
runs-on: ubuntu-latest
needs: [lint, test] # Attend que les deux réussissent
steps:
- uses: actions/checkout@v4
- run: npm run build
Stratégie de matrice — tester sur plusieurs versions
Exécutez le même job sur plusieurs configurations :
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
Cela crée 6 jobs parallèles (3 versions × 2 systèmes d'exploitation).
Secrets et variables d'environnement
Utiliser les secrets
Stockez les valeurs sensibles dans Settings → Secrets and variables → Actions :
steps:
- name: Deploy
env:
API_KEY: ${{ secrets.API_KEY }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
run: ./deploy.sh
Les secrets sont masqués dans les logs et ne sont jamais exposés aux forks.
Variables d'environnement
# Au niveau du workflow
env:
NODE_ENV: production
jobs:
build:
# Au niveau du job
env:
CI: true
steps:
- name: Build
# Au niveau de l'étape
env:
VITE_API_URL: https://api.example.com
run: npm run build
Mise en cache pour des builds plus rapides
Sans mise en cache, chaque exécution télécharge toutes les dépendances depuis zéro. La mise en cache réduit les temps de build de 50 à 80 % :
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm # Mise en cache npm intégrée
# Ou mise en cache manuelle pour d'autres outils
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
Artefacts : partager des données entre les jobs
Uploadez les sorties de build depuis un job et téléchargez-les dans un autre :
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: dist
- run: ./deploy.sh
Exemples de workflows concrets
Build et push Docker
name: Docker
on:
push:
tags: ['v*']
permissions:
packages: write
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
cache-from: type=gha
cache-to: type=gha,mode=max
Déploiement sur Cloudflare Pages
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci && npm run build
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
command: pages deploy dist --project-name=my-site
Release avec changelog
name: Release
on:
push:
tags: ['v*.*.*']
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate changelog
run: |
git log $(git describe --tags --abbrev=0 HEAD^)..HEAD \
--pretty=format:"- %s" > CHANGELOG.md
- uses: softprops/action-gh-release@v2
with:
body_path: CHANGELOG.md
generate_release_notes: true
Exécution conditionnelle
Contrôlez quand les étapes et les jobs s'exécutent :
steps:
- name: Deploy to production
if: github.ref == 'refs/heads/main'
run: ./deploy-prod.sh
- name: Deploy to staging
if: github.event_name == 'pull_request'
run: ./deploy-staging.sh
- name: Notify on failure
if: failure()
run: curl -X POST ${{ secrets.SLACK_WEBHOOK }} -d '{"text":"Build failed!"}'
Bonnes pratiques de sécurité
1. Épinglez les versions des actions au SHA
# ❌ Tag mutable — peut être compromis
- uses: actions/checkout@v4
# ✅ Épinglé au SHA exact du commit
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
2. Utilisez les permissions minimales nécessaires
permissions:
contents: read # Uniquement ce qui est nécessaire
packages: write
3. N'affichez jamais les secrets
# ❌ Ne JAMAIS faire cela
- run: echo ${{ secrets.API_KEY }}
# ✅ Utilisez des variables d'environnement
- env:
API_KEY: ${{ secrets.API_KEY }}
run: ./script-that-uses-api-key.sh
4. Limitez les permissions pour les PR venant de forks
on:
pull_request_target: # S'exécute dans le contexte de la branche de base
types: [opened, synchronize]
Déboguer les workflows en échec
- Consultez les logs — Cliquez sur n'importe quelle étape en échec pour voir la sortie complète
- Activez les logs de débogage — Définissez le secret
ACTIONS_STEP_DEBUGsurtrue - Utilisez
acten local — Exécutez les workflows sur votre machine avec nektos/act - Accédez au runner en SSH — Utilisez
mxschmitt/action-tmatepour le débogage interactif
Créer des workflows visuellement
Vous ne souhaitez pas écrire du YAML à la main ? Utilisez notre GitHub Actions Generator pour construire des workflows visuellement avec des templates pour Node.js, Python, Docker, les déploiements et bien plus encore — puis téléchargez un YAML prêt pour la production.
En résumé
GitHub Actions vous offre un CI/CD intégré directement dans votre dépôt :
- Commencez simplement — Un fichier de workflow avec build + test
- Ajoutez la mise en cache — Réduisez les temps de build avec
actions/cacheou la mise en cache intégrée par langage - Utilisez la matrice — Testez sur plusieurs versions et systèmes d'exploitation
- Protégez les secrets — Ne les codez jamais en dur, utilisez toujours des secrets chiffrés
- Automatisez tout — Releases, déploiements, analyses de sécurité, tâches planifiées
Le meilleur pipeline CI/CD est celui qui s'exécute à chaque commit sans que vous ayez à y penser. Configurez-le une fois, et laissez GitHub s'occuper du reste.