Skip to content

Module 4 — Étude de cas réelle : les pipelines de ce site

Bonne lecture et bon apprentissage ! Junior TSAFACK – 12/09/2026 Temps de lecture estimé : 10 minutes


Plutôt qu’un exemple fictif, ce module analyse deux pipelines réellement en production : celui qui déploie ce site que vous lisez, et celui d’un dépôt compagnon — mcp-odoo-toolkit, présenté dans le cours Serveur MCP pour Odoo.

Cas 1 : le déploiement de ce site (Continuous Deployment)

Section titled “Cas 1 : le déploiement de ce site (Continuous Deployment)”

Ce site est un site statique (généré par Astro) hébergé sur AWS S3 derrière CloudFront. Voici son pipeline complet, .github/workflows/deploy.yml, sans aucune modification :

name: Deploy to AWS S3
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22.23.2'
- name: Install dependencies & Build
run: |
npm ci
npm run build
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-3
- name: Sync files to S3
run: |
aws s3 sync ./dist s3://${{ secrets.AWS_S3_BUCKET }} --delete
- name: Invalidate CloudFront cache (optional)
run: |
aws cloudfront create-invalidation \
--distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} \
--paths "/*"

Ce que révèle ce fichier, ligne par ligne

Section titled “Ce que révèle ce fichier, ligne par ligne”
  • on: push: branches: [main] : ce pipeline se déclenche automatiquement à chaque push sur mainaucune validation humaine intermédiaire. C’est du Continuous Deployment, pas seulement de la Continuous Delivery (voir Module 1) : un choix assumé pour un site personnel à faible risque, mais qui serait à reconsidérer pour une application avec des données utilisateurs sensibles.
  • workflow_dispatch : permet aussi un déclenchement manuel depuis l’interface GitHub — utile pour redéployer sans nouveau commit (par exemple après un changement de configuration DNS).
  • Un seul job, linéaire : checkoutbuildconfigure les identifiants AWSsynchroniser vers S3invalider le cache CDN. Pas d’étape de test explicite ici : npm run build échoue (et donc arrête le pipeline avant tout déploiement) si le site ne compile pas — un test implicite, pas une suite de tests dédiée.
  • Aucun secret en clair : ${{ secrets.AWS_ACCESS_KEY_ID }} etc. sont injectés depuis les GitHub Secrets du dépôt, jamais codés en dur — un point de sécurité fondamental détaillé au Module 5.
  • Pas d’environnement de staging séparé : ce site déploie directement en production. C’est un compromis délibéré pour un site statique à faible enjeu (voir Module 3) — une application avec plus d’enjeu ajouterait un job de staging avant la production.
Terminal window
gh run list --workflow="Deploy to AWS S3" --limit 3

Sortie réellement obtenue :

completed success feat: ajoute un cours complet sur OAuth 2.0 (5 modules) 34s
completed success feat: ajoute un cours complet sur les JWT (5 modules) 60s
completed success feat: ajoute une lecon SLI/SLO/SLA et une page de veille technologique 44s

Trois déploiements réels, chacun déclenché par un commit de contenu sur ce site — la boucle Développer → Push → Build → Déployer du Module 1, exécutée pour de vrai, plusieurs fois, en quelques dizaines de secondes à chaque fois.

Cas 2 : la CI de mcp-odoo-toolkit — un vrai échec, une vraie correction

Section titled “Cas 2 : la CI de mcp-odoo-toolkit — un vrai échec, une vraie correction”

Ce second exemple est plus intéressant : un vrai échec de pipeline, survenu pendant la construction de ce dépôt, et sa correction réelle. Le fichier .github/workflows/ci.yml :

name: CI
on:
push:
branches: [main]
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Installe les dépendances
run: pip install -r requirements-dev.txt
- name: Vérifie le formatage (black)
run: black --check src tests examples
- name: Analyse statique (flake8)
run: flake8 src tests examples
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Installe les dépendances
run: pip install -r requirements-dev.txt
- name: Exécute les tests unitaires
run: pytest -v

Notez needs: lint sur le job test : contrairement au déploiement du site (un seul job linéaire), ici deux jobs distincts s’enchaînent — test attend explicitement que lint réussisse avant de démarrer. Inutile de lancer une suite de tests complète si le code ne respecte même pas le format attendu.

Le premier push de ce pipeline a échoué :

Terminal window
gh run view 34675050916
X main CI · 34675050916
JOBS
✓ lint in 12s
X test in 14s
X Exécute les tests unitaires
Process completed with exit code 2.

Le détail de l’échec (gh run view --log-failed) :

ImportError while importing test module '/home/runner/work/mcp-odoo-toolkit/mcp-odoo-toolkit/tests/test_client.py'.
E ModuleNotFoundError: No module named 'mcp_odoo_toolkit'

Le job lint passait (le code respectait le format et l’analyse statique), mais pytest échouait dès la collecte des tests : le package src/mcp_odoo_toolkit/ n’était pas importable dans l’environnement CI, qui n’exécute que pip install -r requirements-dev.txt — sans jamais installer le projet lui-même.

La correction n’a pas touché au workflow, mais à la configuration pytest du projet — ajouter une seule ligne à pytest.ini :

[pytest]
asyncio_mode = auto
pythonpath = src
testpaths = tests

pythonpath = src ajoute le dossier src/ au chemin de recherche des modules Python avant de lancer les tests, sans avoir besoin d’installer le package. Après ce correctif :

Terminal window
gh run view 34675129549
✓ main CI · 34675129549
JOBS
✓ lint in 15s
✓ test in 26s
  • Un pipeline en Continuous Deployment total (comme celui de ce site) est un choix légitime pour un projet à faible enjeu — pas une obligation universelle.
  • needs: <job> permet d’ordonner des jobs qui, sinon, s’exécuteraient en parallèle — utile pour éviter de faire tourner une suite de tests coûteuse sur du code qui ne respecte même pas le format attendu.
  • Un échec de CI n’est pas un incident à contourner : il a révélé un vrai problème de configuration (le package n’était pas importable), corrigé à la source, jamais en désactivant le test qui le révélait.

Module 5 : Sécurité et bonnes pratiques