CI/CD avec GitHub Actions
Faire tourner automatiquement tes tests, builds et déploiements à chaque push ou pull request, sans serveur à gérer. Intégré directement à GitHub.
Cette fiche couvre la théorie. Pour un exemple appliqué, lis le retour d'expérience CI/CD sur ce site : workflow réel, les 5 erreurs rencontrées en route, et le pattern fail-loud / fail-soft auquel on a abouti. Les concepts ci-dessous y prennent forme.
À quoi ça sert
CI/CD = Continuous Integration / Continuous Deployment. L'idée : chaque fois que tu pousses du code, une machine inconnue (un runner) :
- Récupère ton code tel qu'il sera après merge.
- Lance les tests automatiquement.
- Build ton projet (image Docker, package, doc…).
- Déploie si tout est vert et que c'est la branche de prod.
Sans CI, on découvre les régressions le lundi matin. Avec CI, GitHub te dit dans la minute : « ✓ tests OK » ou « ✗ ça casse, regarde les logs ».
GitHub Actions est la solution intégrée à GitHub. Tu décris ce que tu veux dans un fichier YAML, GitHub fournit la machine et l'exécute. Pour les dépôts publics et les comptes gratuits, il y a des minutes incluses largement suffisantes pour des projets d'école.
Un dépôt GitHub (voir la fiche GitHub). Rien à installer en local — tout se passe sur GitHub. La seule chose que tu écris, c'est un fichier YAML versionné avec ton code.
Un exemple d'usage
Ton projet Python a des tests pytest. Tu veux qu'à chaque push ou PR, GitHub :
- Récupère le code,
- Installe Python 3.12,
- Installe tes dépendances,
- Lance
pytest, - Mette une croix ou un check sur ta PR selon le résultat.
Tu crées .github/workflows/ci.yml avec ces 25 lignes :
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"
- run: pip install -r requirements.txt
- run: pytest -v
Pousse, va sur l'onglet Actions de ton dépôt : ton workflow tourne en direct, log par log.
How-to : configurer ton premier workflow
-
Créer le fichier de workflow
Les workflows sont stockés dans le dossier
.github/workflows/à la racine du dépôt. Le nom du fichier importe peu (ci.yml,tests.yml…), seul le contenu compte.bashmkdir -p .github/workflows touch .github/workflows/ci.ymlTu peux aussi utiliser l'interface web : Actions → New workflow propose des templates pré-remplis selon le langage détecté.
-
Comprendre l'anatomie d'un workflow
yamlname: CI # nom affiché dans l'UI on: # quand est-ce que ça tourne ? push: branches: [main, dev] pull_request: workflow_dispatch: # bouton "Run" manuel schedule: - cron: "0 6 * * *" # tous les jours à 6h jobs: # 1+ "jobs" parallèles test: # identifiant du job runs-on: ubuntu-latest # machine fournie par GitHub steps: # suite d'étapes séquentielles - name: Récupère le code uses: actions/checkout@v4 # action du marketplace - name: Lance les tests run: pytest # commande shellLes actions (
uses:) sont des briques réutilisables publiées sur le Marketplace GitHub. Les commandes (run:) sont du shell classique. -
Activer le cache des dépendances
Réinstaller les paquets à chaque CI = lent et coûteux. Toutes les actions
setup-*ont une option de cache intégrée.yaml- uses: actions/setup-python@v5 with: python-version: "3.12" cache: "pip" # cache /home/.../pip cache-dependency-path: requirements*.txtAvec UV (voir la fiche UV) :
yaml- uses: astral-sh/setup-uv@v3 with: enable-cache: true - run: uv sync - run: uv run pytest -
Tester sur plusieurs versions / OS (matrix)
Pour vérifier que ton code marche sur Python 3.10, 3.11 et 3.12 en parallèle, utilise une
matrix:yamljobs: test: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - run: pip install -r requirements.txt && pytestGitHub va lancer 3 × 3 = 9 jobs en parallèle. Tu vois en un clin d'œil quelles combinaisons cassent.
-
Utiliser des secrets (clés API, tokens…)
Tu ne committes jamais un mot de passe ou une clé API. Tu les stockes dans : Settings → Secrets and variables → Actions → New repository secret.
Puis dans le workflow :
yaml- name: Déploie env: API_TOKEN: ${{ secrets.API_TOKEN }} run: ./deploy.shSécuritéLes secrets sont automatiquement masqués dans les logs (affichés comme
***). Mais ne les passe jamais à un script tiers non audité, et limite leur portée (par environnement, par branche). -
Conditionner des étapes
Exemple : ne déployer que si on est sur
mainet que les tests passent.yamljobs: test: runs-on: ubuntu-latest steps: [ ... ] deploy: needs: test # attend que test soit OK if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest steps: [ ... ] -
Lire les logs et déboguer
- Onglet Actions du dépôt → choisis le run.
- Clique sur le job (
test) → tu vois chaque étape, expand celle qui a échoué. - Pour activer le mode debug, ajoute le secret repository
ACTIONS_STEP_DEBUG = trueet relance. - Astuce :
actions/upload-artifactpour télécharger des fichiers générés (rapport HTML pytest, build logs…).
-
Afficher un badge de statut
Le petit ✓ vert dans les README, c'est juste une image dynamique :
markdownSur la page Actions → ouvre un workflow → bouton ... → Create status badge : GitHub te génère le snippet exact.
-
Configurer VS Code
-
Installe l'extension GitHub Actions
(
GitHub.vscode-github-actions) : tu vois tous tes workflows et leurs runs depuis l'éditeur, et l'autocomplétion YAML est branchée sur le schéma officiel. - Avec l'extension YAML de Red Hat, tu obtiens en plus la validation du schéma à la frappe.
Tester en localPour tester un workflow sans pousser, l'outil act (
brew install act) lance les jobs dans Docker sur ta machine. -
Installe l'extension GitHub Actions
(
Patterns utiles à connaître
Builder et pousser une image Docker
- uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_TOKEN }}
- uses: docker/build-push-action@v5
with:
push: true
tags: monuser/monapp:latest
Déployer la doc Sphinx sur GitHub Pages
Voir la fiche Sphinx, section « Publier la doc en ligne ».
Lancer un workflow manuellement
on:
workflow_dispatch:
inputs:
env:
type: choice
options: [staging, prod]
Apparaît comme un bouton « Run workflow » dans l'UI Actions.
Pour aller plus loin
- Doc officielle : docs.github.com/fr/actions
- Marketplace : github.com/marketplace
- Référence YAML complète : syntax workflows
- Outil act pour tester en local : github.com/nektos/act