flowchart LR
A[📝 Push] --> B[🔍 Lint]
B --> C[🧪 Tests]
C --> D{Tout passe ?}
D -->|Oui| E[📦 Build]
D -->|Non| F[❌ Alerte]
E --> G[🚀 Deploy]
0.0.1 🎯 Objectifs d’apprentissage
- Expliquer les concepts de CI et CD et leurs bénéfices
- Écrire un workflow GitHub Actions complet
- Configurer des tests automatisés avec pytest
- Mettre en place du linting et formatage automatique
- Comprendre le déploiement continu
📚 Prérequis : Git, Docker, Python
⏱️ Temps estimé : 3 heures
1 Pourquoi automatiser ?
Sans CI/CD, chaque développeur doit manuellement lancer les tests, vérifier le formatage, et déployer. Résultat : des oublis, des bugs en production, des déploiements risqués.
| CI (Intégration Continue) | CD (Déploiement Continu) | |
|---|---|---|
| Quand | À chaque push ou PR | Après validation CI |
| Quoi | Tests, linting, build | Déploiement staging/prod |
| Objectif | Détecter les bugs tôt | Livrer rapidement |
💡 En data science, le CI/CD sert à valider que les modèles se chargent, que les prédictions sont cohérentes, et à déployer automatiquement les APIs de scoring.
2 Structure d’un workflow GitHub Actions
Un workflow est un fichier .yml dans .github/workflows/ :
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest black flake8
- name: Run linting
run: |
black --check .
flake8 . --max-line-length 120
- name: Run tests
run: pytest tests/ -v --tb=short| Concept | Description |
|---|---|
Trigger (on) |
Événement déclencheur (push, PR, schedule) |
| Job | Groupe de tâches sur une VM dédiée |
| Step | Étape individuelle dans un job |
| Action | Module réutilisable (actions/checkout@v4) |
| Secret | Variable chiffrée pour données sensibles |
3 Tests automatisés avec pytest
3.1 Écrire des tests pour l’assurance
# tests/test_sinistralite.py
import pytest
from models.sinistralite import calculer_frequence, calculer_sp
def test_frequence_normale():
"""Fréquence = nb_sinistres / exposition"""
assert calculer_frequence(100, 1000) == 0.1
def test_frequence_zero_exposition():
with pytest.raises(ZeroDivisionError):
calculer_frequence(10, 0)
def test_sp_normal():
assert calculer_sp(70000, 100000) == 0.7
@pytest.mark.parametrize("nb_sin,expo,expected", [
(50, 1000, 0.05),
(100, 1000, 0.10),
(200, 1000, 0.20),
])
def test_frequence_parametrique(nb_sin, expo, expected):
assert calculer_frequence(nb_sin, expo) == expected$ pytest tests/ -v
tests/test_sinistralite.py::test_frequence_normale PASSED
tests/test_sinistralite.py::test_frequence_zero_exposition PASSED
tests/test_sinistralite.py::test_sp_normal PASSED
tests/test_sinistralite.py::test_frequence_parametrique[50-1000-0.05] PASSED
tests/test_sinistralite.py::test_frequence_parametrique[100-1000-0.1] PASSED
tests/test_sinistralite.py::test_frequence_parametrique[200-1000-0.2] PASSED
============ 6 passed in 0.08s ============
📝 Bonnes pratiques
- Un test par comportement, pas par fonction
- Noms descriptifs (
test_frequence_zero_exposition) @pytest.mark.parametrizepour tester plusieurs cas- Toujours tester les cas limites et erreurs
4 Linting et formatage
Black formate le code automatiquement — plus de débats de style :
black --check . # Vérifier
black . # FormaterFlake8 détecte les erreurs de style et bugs potentiels :
flake8 . --max-line-length 120 --ignore=E203,W5035 Déploiement continu
deploy:
needs: [test, lint]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- run: docker build -t mon-api:${{ github.sha }} .
- run: docker push mon-registry/mon-api:${{ github.sha }}⚠️ Sécurité — Ne jamais stocker de secrets dans le code. Utiliser les GitHub Secrets :
env:
AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}Synthèse
5.0.1 🎯 Les 5 points essentiels
- CI détecte les bugs tôt — Tests et linting à chaque push
- CD accélère la livraison — Déploiement automatique après validation
- GitHub Actions = YAML — Triggers, jobs, steps
- pytest est le standard — Tests paramétriques, fixtures, markers
- Les secrets restent secrets — GitHub Secrets, jamais en dur
Auto-évaluation
Réponse : CI automatise tests et validation à chaque changement. CD automatise le déploiement après validation. La CI est un prérequis au CD.
Réponse : Les secrets dans le code sont visibles dans l’historique Git. GitHub Secrets les chiffre et les injecte uniquement pendant l’exécution du workflow.
Réponse : Pour vérifier qu’une fonction lève bien une exception dans un cas d’erreur (ex: division par zéro). C’est un test de robustesse.
Réponse : Déterministe et non configurable : élimine les débats de style, garantit un code homogène, permet de se concentrer sur la logique métier.