CI/CD : Introduction et Fondamentaux

CI/CD
Lecture
Cette leçon introduit les concepts de l’intégration continue (CI) et du déploiement continu (CD), expliquant leur importance dans le développement logiciel moderne. Nous explorerons les outils et les pratiques courantes pour automatiser les tests, la construction et le déploiement des applications.
Auteur
Affiliations

Université de Toulon

LIS UMR CNRS 7020

Date de publication

2026-10-06

Contexte : L’évolution du développement logiciel

Note

Acronymes (premier usage) - CI = Continuous Integration (Intégration Continue) - CD = Continuous Delivery / Continuous Deployment (Livraison / Déploiement Continu) - E2E = End-to-End (tests bout-en-bout) - IaC = Infrastructure as Code (Infrastructure en tant que code) - SAST = Static Application Security Testing (analyse statique de sécurité) - RBAC = Role-Based Access Control (contrôle d’accès par rôle) - K8s = Kubernetes

Du développement isolé au DevOps moderne

  • Années 2000 : Développement en silos
    • Équipes dev vs ops séparées
      • Devs codent, ops déploient
    • Déploiements manuels, rares, risqués
    • “Ça marche sur ma machine” → problème en production
  • Problèmes identifiés :
    • Déploiements longs et complexes
    • Bugs découverts tard (coût élevé)
    • Conflits d’intégration (“merge hell”)
    • Feedback lent sur la qualité du code
  • Besoin : Automatisation et collaboration entre dev et ops

La problématique centrale

Comment passer du code sur ma machine à la production de manière fiable, rapide et répétable ?

C’est LA question à laquelle CI/CD répond. Aujourd’hui, ce qui prenait des jours ou semaines peut prendre quelques minutes.

Attentes modernes :

  • Déployer plusieurs fois par jour
  • Revenir en arrière instantanément si problème
  • Confiance totale dans les déploiements
  • Zéro intervention manuelle

Architecture cible de ce cours

%%{init: {"config": {"theme": "base"}, "themeVariables": {"primaryColor":"#A8D5E2","secondaryColor":"#B4E7A0","tertiaryColor":"#FFD6A5","accentColor":"#E8B4E8","background":"#FFFFFF","textColor":"#000"}}}%%
graph LR
    A[Code Source] --> B[CI: Build & Test]
    B --> C[CD: Delivery]
    C --> D[CD: Deployment]
    D --> E[GitOps]
    E --> F[Production]
    
    style A fill:#E8F4F8,color:#000
    style B fill:#A8D5E2,color:#000
    style C fill:#B4E7A0,color:#000
    style D fill:#FFD6A5,color:#000
    style E fill:#E8B4E8,color:#000
    style F fill:#C5E1A5,color:#000

Rappels essentiels

Git Workflows

Feature Branch Workflow

%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#A8D5E2",
    "secondaryColor": "#B4E7A0",
    "tertiaryColor": "#FFD6A5",
    "background": "#E8F4F8",
    "primaryTextColor": "#000",
    "lineColor": "#333"
  }
}}%%
gitGraph
    commit
    branch feature
    checkout feature
    commit
    commit
    checkout main
    merge feature
    commit

  • Branches par fonctionnalité
  • Pull/Merge Requests
  • Code review avant merge

Trunk-Based Development

%%{init: {
  "theme": "base",
  "themeVariables": {
    "primaryColor": "#A8D5E2",
    "secondaryColor": "#B4E7A0",
    "tertiaryColor": "#FFD6A5",
    "background": "#E8F4F8",
    "primaryTextColor": "#000",
    "lineColor": "#333"
  }
}}%%
gitGraph
    commit
    commit
    commit
    commit
    commit

  • Commits fréquents sur main
  • Branches éphémères (<1 jour)
  • Feature flags pour WIP
    • Features Flagging : on/off en prod (see https://martinfowler.com/articles/feature-toggles.html)

Pourquoi c’est important pour CI/CD ?

  • Feature Branch : CI s’exécute sur chaque PR avant merge
  • Trunk-Based : CI ultra-rapide nécessaire (builds < 10 min)
  • Les deux approches nécessitent des tests automatisés solides

Rappel clé : Plus on intègre souvent, moins il y a de conflits

Tests automatisés et pyramide des tests

%%{init: {"themeVariables": {"primaryColor":"#A8D5E2","secondaryColor":"#B4E7A0","tertiaryColor":"#FFD6A5","accentColor":"#E8B4E8","background":"#E8F4F8","textColor":"#000"}}}%%
graph TB
    A[Tests E2E<br/>🐌 Lents, Coûteux] --> B
    B[Tests d'Intégration<br/>⚡ Moyens] --> C
    C[Tests Unitaires<br/>🚀 Rapides, Nombreux]
    
    style A fill:#FFD6A5,color:#000
    style B fill:#FFD6A5,color:#000
    style C fill:#C5E1A5,color:#000

Proportions idéales

  • 70% Unitaires
  • 20% Intégration
  • 10% E2E

Feedback rapide = CI efficace

Build Maven : cycle de vie et plugins

Cycle de vie par défaut

mvn clean      # Nettoie target/
mvn validate   # Vérifie le projet
mvn compile    # Compile sources
mvn test       # Tests unitaires
mvn package    # Crée JAR/WAR
mvn verify     # Tests intégration
mvn install    # Installe local repo
mvn deploy     # Déploie remote repo

Plugins essentiels pour CI

  • maven-compiler-plugin
  • maven-surefire-plugin (tests)
  • maven-failsafe-plugin (IT)
  • jacoco-maven-plugin (coverage)
  • maven-checkstyle-plugin
  • dockerfile-maven-plugin

Conteneurisation avec Docker

Pourquoi Docker en CI/CD ?

Reproductibilité

FROM openjdk:17-slim
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]

Même environnement partout

Isolation

Chaque build dans un conteneur propre

Pas de pollution d’état

Portabilité

docker run -p 8080:8080 \
  mon-app:latest

Fonctionne partout

Multi-stage builds

Optimiser les images Docker pour la production

# Stage 1: Build
FROM maven:3.9-openjdk-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# Stage 2: Runtime
FROM openjdk:17-slim
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

✅ Image finale légère

  • Pas de Maven
  • Pas de code source
  • Seulement le JAR + JRE

📉 Taille optimisée

  • Build stage (with JDK) : ~600 MB
  • Runtime stage (with JRE) : ~200 MB
  • Quarto with native image : ~50 MB

Concepts fondamentaux CI/CD

Qu’est-ce que l’Intégration Continue (CI) ?

Continuous Integration : Intégrer fréquemment pour détecter les problèmes tôt

%%{init: {"themeVariables": {"primaryColor":"#A8D5E2","secondaryColor":"#B4E7A0","tertiaryColor":"#FFD6A5","accentColor":"#E8B4E8","background":"#E8F4F8","textColor":"#000"}}}%%
graph LR
    A[💻 Dev<br/>Code] --> B[📤 Push]
    B --> C[🔨 Build<br/>Automatique]
    C --> D[🧪 Tests<br/>Automatiques]
    D --> E{✅ Success?}
    E -->|Oui| F[✅ Merge OK]
    E -->|Non| G[❌ Fix immédiat]
    
    style C fill:#A8D5E2,color:#000
    style D fill:#A8D5E2,color:#000
    style F fill:#C5E1A5,color:#000
    style G fill:#FFD6A5,color:#000

Principes clés

  1. Commit fréquents (quotidiens)
  2. Build automatique à chaque commit
  3. Tests automatiques systématiques
  4. Fix immédiat si échec
  5. Environnement partagé

Définition : L’Intégration Continue (CI) est une pratique de développement où les développeurs intègrent fréquemment leur code dans un dépôt partagé, chaque intégration étant vérifiée par une build automatisée et des tests.

Qu’est-ce que la Livraison Continue (Continuous Delivery) ?

Continuous Delivery : Toujours prêt à déployer

%%{init: {"themeVariables": {"primaryColor":"#A8D5E2","secondaryColor":"#B4E7A0","tertiaryColor":"#FFD6A5","accentColor":"#E8B4E8","background":"#E8F4F8","textColor":"#000"}}}%%
graph LR
    A[CI Build & Test] --> B[📦 Package]
    B --> C[🧪 Tests<br/>Intégration]
    C --> D[🧪 Tests<br/>Performance]
    D --> E[🎯 Staging]
    E --> F{👤 Décision<br/>Manuelle}
    F -->|Deploy| G[🚀 Production]
    
    style A fill:#A8D5E2,color:#000
    style B fill:#B4E7A0,color:#000
    style C fill:#B4E7A0,color:#000
    style D fill:#B4E7A0,color:#000
    style E fill:#B4E7A0,color:#000
    style F fill:#FFD6A5,color:#000
    style G fill:#C5E1A5,color:#000

Caractéristiques

✅ Pipeline entièrement automatisé

✅ Chaque commit → artefact déployable

✅ Tests exhaustifs automatiques

⚠️ Déploiement manuel (bouton)

🎯 Déploiement à la demande

Définition : La Livraison Continue (Continuous Delivery) est une extension de CI où chaque changement qui passe les tests est automatiquement préparé pour être déployé en production.

Concept clé : Le code est toujours dans un état déployable. On peut déployer à tout moment, mais on choisit quand le faire.

Qu’est-ce que le Déploiement Continu (Continuous Deployment) ?

Continuous Deployment : Zéro intervention humaine

%%{init: {"themeVariables": {"primaryColor":"#A8D5E2","secondaryColor":"#B4E7A0","tertiaryColor":"#FFD6A5","accentColor":"#E8B4E8","background":"#E8F4F8","textColor":"#000"}}}%%
graph LR
    A[CI Build & Test] --> B[📦 Package]
    B --> C[🧪 Tests<br/>Intégration]
    C --> D[🧪 Tests<br/>Performance]
    D --> E[🎯 Staging<br/>Auto]
    E --> F[🤖 Deploy<br/>Automatique]
    F --> G[🚀 Production]
    
    style A fill:#A8D5E2,color:#000
    style B fill:#B4E7A0,color:#000
    style C fill:#B4E7A0,color:#000
    style D fill:#B4E7A0,color:#000
    style E fill:#B4E7A0,color:#000
    style F fill:#E8B4E8,color:#000
    style G fill:#C5E1A5,color:#000

Différence clé

✅ Pipeline 100% automatisé

✅ Chaque commit → production (si tests OK)

🤖 Zéro intervention humaine

⚡ Déploiements multiples/jour

🛡️ Nécessite grande confiance tests

Pas d’étape manuelle ! Du commit au production : 100% automatique.

Inconvénients : - Nécessite maturité technique élevée - Pas adapté à tous les contextes (médical, bancaire avec validation réglementaire)

Anatomie d’un Pipeline CI/CD

Structure typique d’un pipeline moderne

%%{init: {
"theme": "base",
"themeVariables": {
"background": "#F7F9FC",
"primaryTextColor": "#2F2F2F",
"lineColor": "#B8C4CC",
"fontFamily": "Inter, Arial"
}
}}%%

graph TB
%% ===== Subgraphs =====
subgraph S1["🌱 Stage 1: Build"]
A[Checkout Code] --> B[Restore Cache]
B --> C[Maven Build]
end

subgraph S2["🧪 Stage 2: Test"]
    C --> D[Tests Unitaires]
    C --> E[Tests Intégration]
    C --> F[Analyse Code]
end

subgraph S3["📦 Stage 3: Package"]
    D & E & F --> G[Build Docker Image]
    G --> H[Scan Sécurité]
end

subgraph S4["🚀 Stage 4: Deploy"]
    H --> I[Push Registry]
    I --> J{Env ?}
    J -->|Dev| K[Deploy Dev]
    J -->|Staging| L[Deploy Staging]
    J -->|Prod| M[Deploy Prod]
end

%% ===== Classes =====
classDef build fill:#CDE7F0,stroke:#9FC7D8,stroke-width:1px,color:#2F2F2F
classDef test fill:#DFF2E1,stroke:#A8D5B5,stroke-width:1px,color:#2F2F2F
classDef package fill:#FFF1D6,stroke:#E5CFA3,stroke-width:1px,color:#2F2F2F
classDef deploy fill:#EAD7F5,stroke:#C7A9E3,stroke-width:1px,color:#2F2F2F
classDef decision fill:#FBE6F2,stroke:#E0AFCB,stroke-width:1px,color:#2F2F2F

%% ===== Apply classes =====
class A,B,C build
class D,E,F test
class G,H package
class I,K,L,M deploy
class J decision

%% ===== Subgraph styling (IMPORTANT) =====
style S1 fill:#EEF7FB,stroke:#9FC7D8,stroke-width:2px
style S2 fill:#EFF9F1,stroke:#A8D5B5,stroke-width:2px
style S3 fill:#FFF7E6,stroke:#E5CFA3,stroke-width:2px
style S4 fill:#F6EEFB,stroke:#C7A9E3,stroke-width:2px

Qualité logicielle dans le pipeline

La qualité ne se limite pas à la couverture de code

📊 Métriques de qualité

Quality Gates:
  ✓ Couverture tests: >80%
  ✓ Code smells: <50
  ✓ Complexité: <15
  ✓ Duplication: <3%
  ✓ Vulnérabilités: 0 critiques
  ✓ Bugs: 0 bloquants
  ✓ Dette technique: <5 jours

Outils : SonarQube, CodeClimate

🔍 Dimensions de qualité

  1. Analyse statique
    • Linting (PMD, Checkstyle)
    • Code style & conventions
  2. Maintenabilité
    • Complexité cyclomatique
    • Code smells, duplication
  3. Sécurité (SAST)
    • CVE dans dépendances
    • OWASP Top 10
  4. Performance
    • Hotspots détectés

Pourquoi c’est crucial en CI/CD ?

La qualité doit être une porte d’entrée, pas une option. Si la qualité n’est pas suffisante, le pipeline doit échouer.

1. Analyse statique de code - Linting : PMD, Checkstyle, SpotBugs - Détecte les anti-patterns Java - Vérifie le respect des conventions - Exemple : variables non utilisées, imports inutiles

  • Code style : Formatters (google-java-format)
    • Cohérence du codebase
    • Évite les débats de style en PR

2. Métriques de maintenabilité - Complexité cyclomatique : Nombre de chemins dans le code - Seuil recommandé : < 10 par méthode - Haut = difficile à tester et maintenir

  • Code smells :
    • Méthodes trop longues (> 50 lignes)
    • Classes avec trop de responsabilités
    • Couplage excessif
  • Duplication :
    • Code copié-collé = maintenance cauchemar
    • Seuil : < 3% du codebase
  • Dette technique :
    • Temps estimé pour corriger tous les problèmes
    • Visualisation de la tendance (augmente ou diminue ?)

3. Sécurité (SAST - Static Application Security Testing) - Dependency Check : OWASP Dependency Check, Snyk - Scanne pom.xml pour CVE connus - Base de données National Vulnerability Database

  • Code vulnerabilities :
    • Injection SQL potentielle
    • Cross-Site Scripting (XSS)
    • Hard-coded secrets

4. Architecture & Design - Metrics Maven Plugin : - Couplage afférent/efférent - Instabilité des packages

  • ArchUnit : Tests d’architecture as code
    • “Les controllers ne doivent pas appeler les repositories”
    • “Les entities ne doivent pas dépendre de services”

Exemple de Quality Gate SonarQube :

Quality Gate Failed si:
  - Couverture < 80%
  - New bugs > 0
  - Vulnerabilités critiques > 0
  - Code smells > 50
  - Duplication > 3%
  - Complexité cyclomatique > 15

Intégration dans le pipeline :

mvn sonar:sonar -Dsonar.qualitygate.wait=true
# Échoue si Quality Gate not passed

Visualisation : - Badge sur le README - Dashboard d’équipe - Trend over time (la qualité s’améliore-t-elle ?)

Philosophie : “Shift Left” - détecter les problèmes le plus tôt possible, idéalement dans l’IDE, sinon dans le pipeline CI.

Principe du Feedback rapide : Fail Fast

Plus vite on détecte un problème, moins il coûte cher

%%{init: {"themeVariables": {"primaryColor":"#A8D5E2","secondaryColor":"#B4E7A0","tertiaryColor":"#FFD6A5","accentColor":"#E8B4E8","background":"#E8F4F8","textColor":"#000"}}}%%
graph TD
    A[Commit Code] --> B{Compile?}
    B -->|❌| Z1[STOP<br/>⏱️ 30s]
    B -->|✅| C{Tests Unit?}
    C -->|❌| Z2[STOP<br/>⏱️ 2min]
    C -->|✅| D{Tests IT?}
    D -->|❌| Z3[STOP<br/>⏱️ 10min]
    D -->|✅| E{Security?}
    E -->|❌| Z4[STOP<br/>⏱️ 15min]
    E -->|✅| F[✅ Suite]
    
    style Z1 fill:#FFD6A5,color:#000
    style Z2 fill:#FFD6A5,color:#000
    style Z3 fill:#FFD6A5,color:#000
    style Z4 fill:#FFD6A5,color:#000
    style F fill:#C5E1A5,color:#000

Principe Fail Fast : Conception du pipeline pour détecter les problèmes le plus tôt possible.

Optimisations : - Paralléliser quand possible - Cacher les dépendances - Exécuter les tests les plus susceptibles d’échouer en premier - Utiliser des test selectors (tests modifiés d’abord)

Notifications : - Email/Slack sur échec - Badge de build sur README - Dashboard visible de l’équipe

Métrique : “Time to feedback”

Les bénéfices de CI/CD

Un pipeline CI/CD bien conçu augmente la vitesse, la qualité et la confiance dans les livraisons.

Vélocité

  • Déploiements fréquents et prévisibles
  • Réduction du Time-to-market

KPI : Deployment Frequency

Qualité

  • Détection précoce des régressions
  • Tests automatisés systématiques

KPI : Change Failure Rate

Confiance

  • Rollback simple et traçabilité
  • Déployable à tout instant

KPI : Lead Time & MTTR

DORA Metrics (essentiel)
- Deployment Frequency : fréquence des déploiements.
- Lead Time for Changes : temps commit → production.
- Change Failure Rate : % de déploiements causant incident.
- Time to Restore Service (MTTR) : temps moyen de rétablissement.

Actions concrètes (intégrer au pipeline)
1. Exiger Quality Gate Sonar pour les PRs (ex.: couverture > 80%).
2. Automatiser tests unitaires + integration avant merge.
3. Mettre en place badges + dashboard DORA pour suivi continu.

Réutilisation