Pierry Lim

Principes et mise en place du CI/CD

· Mis à jour le 7 septembre 2024 · 11 min de lecture
CI/CD
DevOps
Automatisation
Pipeline

Guide complet sur les principes CI/CD : intégration continue, déploiement continu, mise en place pratique avec exemples concrets. Parfait pour débuter avec les pipelines.

Principes et mise en place du CI/CD

Sommaire

Introduction

Vous avez probablement entendu parler de CI/CD sans vraiment comprendre ce que cela apporte concrètement. Peut-être que vous déployez encore manuellement vos applications, en croisant les doigts pour que tout se passe bien ?

Le CI/CD va révolutionner votre façon de développer en automatisant les tâches répétitives et en réduisant drastiquement les risques d’erreur. Dans cet article, nous allons démystifier ces concepts et voir comment les mettre en place simplement.

Comprendre le CI/CD

Qu’est-ce que l’intégration continue (CI) ?

L’intégration Continue consiste à automatiser la validation de votre code à chaque modification :

Le processus traditionnel :

  1. Développeur A travaille sur sa fonctionnalité (3 jours)
  2. Développeur B travaille sur la sienne (3 jours)
  3. Ils fusionnent leur code -> Conflits et bugs =1
  4. 2 jours pour résoudre les problèmes
  5. Tests manuels -> Encore des bugs
  6. Correction -> Nouveaux tests…

Avec l’intégration continue :

  1. Chaque commit déclenche automatiquement :
    • Tests unitaires
    • Tests d’intégration
    • Vérifications de qualité de code
    • Build automatique
  2. Feedback immédiat en cas de problème
  3. Conflits détectés rapidement

Qu’est-ce que le déploiement continu (CD) ?

Le déploiement Continu automatise la mise en production :

Continuous Delivery (Livraison Continue) :

  • Le code est automatiquement préparé pour le déploiement
  • déploiement manuel après validation

Continuous Deployment (déploiement Continu) :

  • Le code est automatiquement déployé en production
  • Aucune intervention manuelle

Les bénéfices du CI/CD

Rapidité de livraison :

  • De quelques semaines à quelques heures
  • Mise sur le marché accélérée

Qualité améliorée :

  • Tests systématiques
  • Détection précoce des bugs
  • Rollback automatique si problème

Réduction du stress :

  • Fini les déploiements du vendredi soir
  • Process reproductible et fiable

Collaboration renforcée :

  • Feedback rapide entre équipes
  • Intégration facilitée du code

Anatomie d’une pipeline CI/CD

Les étapes essentielles

Code Push → Build → Test → Deploy → Monitor
     →         →       →       →        →
   Trigger   Compile  Unit   Staging  Alerts
             Install  E2E    Prod     Metrics
             Lint     API            Logs

1. Déclenchement (Trigger) :

  • Push sur une branche
  • Pull Request
  • Tag de version
  • Programmation (cron)

2. Construction (Build) :

  • Installation des dépendances
  • Compilation du code
  • Vérification du linting
  • Génération des assets

3. Tests :

  • Tests unitaires
  • Tests d’intégration
  • Tests end-to-end
  • Tests de sécurité

4. déploiement :

  • déploiement en staging
  • Tests de validation
  • déploiement en production
  • Vérifications post-déploiement

5. Monitoring :

  • Surveillance des erreurs
  • Métriques de performance
  • Alertes automatiques

Les outils populaires

Plateformes CI/CD intégrées :

  • GitHub Actions - Intégré é GitHub
  • GitLab CI - Intégré é GitLab
  • Bitbucket Pipelines - Intégré é Bitbucket

Solutions dédiées :

  • Jenkins - Open source, très flexible
  • CircleCI - Cloud, facile à configurer
  • Travis CI - Populaire pour l’open source

Cloud providers :

  • AWS CodePipeline - écosystème AWS
  • Azure DevOps - Microsoft
  • Google Cloud Build - Google Cloud

Mise en place pratique

Exemple avec GitHub Actions

Créons une pipeline complète pour une application Node.js :

.github/workflows/ci-cd.yml :

name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

env:
  NODE_VERSION: '18'

jobs:
  # ==================
  # PHASE CI
  # ==================
  test:
    name: Tests et Qualité
    runs-on: ubuntu-latest
    
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
      
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ env.NODE_VERSION }}
        cache: 'npm'
        
    - name: Install dependencies
      run: npm ci
      
    - name: Run linting
      run: npm run lint
      
    - name: Run unit tests
      run: npm run test:unit
      
    - name: Run integration tests
      run: npm run test:integration
      
    - name: Build application
      run: npm run build
      
    - name: Upload build artifacts
      uses: actions/upload-artifact@v3
      with:
        name: build-files
        path: dist/

  # ==================
  # PHASE CD - STAGING
  # ==================
  deploy-staging:
    name: Deploy to Staging
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    
    environment:
      name: staging
      url: https://staging.monapp.com
    
    steps:
    - name: Download build artifacts
      uses: actions/download-artifact@v3
      with:
        name: build-files
        path: dist/
        
    - name: Deploy to staging server
      run: |
        echo "Deploying to staging..."
        # Vos commandes de déploiement ici
        rsync -av dist/ user@staging-server:/var/www/html/
        
    - name: Run smoke tests
      run: |
        curl -f https://staging.monapp.com/health || exit 1
        npm run test:e2e -- --baseUrl=https://staging.monapp.com

  # ==================
  # PHASE CD - PRODUCTION
  # ==================
  deploy-production:
    name: Deploy to Production
    needs: [test, deploy-staging]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    environment:
      name: production
      url: https://monapp.com
    
    steps:
    - name: Download build artifacts
      uses: actions/download-artifact@v3
      with:
        name: build-files
        path: dist/
        
    - name: Deploy to production
      run: |
        echo "Deploying to production..."
        # Blue-green deployment ou rolling update
        ./scripts/deploy-production.sh
        
    - name: Verify deployment
      run: |
        curl -f https://monapp.com/health || exit 1
        npm run test:smoke -- --baseUrl=https://monapp.com
        
    - name: Notify team
      if: success()
      run: |
        curl -X POST -H 'Content-type: application/json' \
             --data '{"text":"déploiement en production réussi!"}' \
             ${{ secrets.SLACK_WEBHOOK }}

Exemple avec GitLab CI

.gitlab-ci.yml :

stages:
  - build
  - test
  - deploy-staging
  - deploy-production

variables:
  NODE_VERSION: "18"

# ==================
# BUILD STAGE
# ==================
build:
  stage: build
  image: node:${NODE_VERSION}
  cache:
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour

# ==================
# TEST STAGE
# ==================
test:unit:
  stage: test
  image: node:${NODE_VERSION}
  script:
    - npm ci
    - npm run test:unit

test:integration:
  stage: test
  image: node:${NODE_VERSION}
  services:
    - postgres:13
    - redis:6-alpine
  script:
    - npm ci
    - npm run test:integration

# ==================
# DEPLOY STAGING
# ==================
deploy:staging:
  stage: deploy-staging
  script:
    - echo "Deploying to staging..."
    - rsync -av dist/ $STAGING_SERVER:/var/www/html/
  environment:
    name: staging
    url: https://staging.monapp.com
  only:
    - develop

# ==================
# DEPLOY PRODUCTION
# ==================
deploy:production:
  stage: deploy-production
  script:
    - echo "Deploying to production..."
    - ./scripts/deploy-production.sh
  environment:
    name: production
    url: https://monapp.com
  only:
    - main
  when: manual  # Nécessite une validation manuelle

Configuration des environnements

Variables d’environnement par stage :

# Staging
environment:
  name: staging
  variables:
    DATABASE_URL: $STAGING_DB_URL
    API_URL: https://api-staging.monapp.com
    CACHE_TTL: 300

# Production  
environment:
  name: production
  variables:
    DATABASE_URL: $PRODUCTION_DB_URL
    API_URL: https://api.monapp.com
    CACHE_TTL: 3600

Gestion des secrets :

  • Tokens d’API
  • Clés de déploiement
  • Mots de passe de base de données
  • Certificats SSL

Bonnes pratiques

Architecture des branches

GitFlow simplifié :

main (production)     -> Merge après validation

develop (staging)     -> intégration des features

feature/xxx           -> Développement des fonctionnalités

Tests en pyramide

E2E Tests (Peu)

Integration Tests (Quelques-uns)

Unit Tests (Beaucoup)

Répartition recommandée :

  • 70% Tests unitaires (rapides, isolés)
  • 20% Tests d’intégration (modules ensemble)
  • 10% Tests E2E (parcours utilisateur complets)

déploiement sécurisé

Stratégies de déploiement :

  1. Blue-Green Deployment :
Blue (v1.0) -> Traffic 100%
Green (v1.1) -> déploiement en parallèle
Switch -> Green -> Traffic 100%
  1. Rolling Deployment :
Serveur 1: v1.0 -> v1.1
Serveur 2: v1.0 -> v1.1  
Serveur 3: v1.0 -> v1.1
  1. Canary Deployment :
90% Traffic -> v1.0 (stable)
10% Traffic -> v1.1 (nouvelle version)
Si OK -> 100% vers v1.1

Monitoring et alertes

# Healthcheck automatique aprés déploiement
- name: Health Check
  run: |
    for i in {1..5}; do
      if curl -f https://monapp.com/health; then
        echo "Health check passed"
        exit 0
      fi
      echo "é Waiting for app to start..."
      sleep 10
    done
    echo "❌ Health check failed"
    exit 1

Gestion des échecs et rollbacks

Rollback automatique

- name: Deploy with rollback
  run: |
    # Sauvegarde de la version actuelle
    kubectl rollout history deployment/monapp
    
    # déploiement
    kubectl set image deployment/monapp app=monapp:${{ github.sha }}
    
    # Vérification
    kubectl rollout status deployment/monapp --timeout=300s
    
    # Rollback si échec
    if ! curl -f https://monapp.com/health; then
      echo "❌ Deployment failed, rolling back..."
      kubectl rollout undo deployment/monapp
      exit 1
    fi

Notifications d’échec

- name: Notify on failure
  if: failure()
  uses: actions/slack@v1
  with:
    message: |
      => déploiement échoué !
      Branche: ${{ github.ref }}
      Commit: ${{ github.sha }}
      Voir: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}

FAQ

Dois-je déployer automatiquement en production ?

Pour les équipes expériences : Oui, avec des tests robustes et du monitoring.

Pour débuter : Commencez par l’automatisation jusqu’au staging, puis déploiement manuel en production.

Combien de temps doit prendre ma pipeline ?

Objectifs recommandés :

  • CI (build + tests) : < 10 minutes
  • déploiement staging : < 5 minutes
  • déploiement production : < 15 minutes

Si c’est plus long, parallélisez ou optimisez.

Comment gérer les bases de données ?

Migrations :

- name: Run database migrations
  run: |
    npm run migrate:up
    npm run seed:production

Stratégies :

  • Migrations backward-compatible
  • Scripts de rollback préparés
  • Backup automatique avant migration

Que faire si un test est flaky (instable) ?

  1. Identifier la cause (timing, dépendances externes)
  2. Stabiliser le test (mocks, attentes explicites)
  3. En attendant : Retry automatique
- name: Run flaky tests with retry
  uses: nick-invision/retry@v2
  with:
    timeout_minutes: 10
    max_attempts: 3
    command: npm run test:e2e

Comment débuter simplement ?

Phase 1 : CI simple (tests + build) Phase 2 : déploiement automatique en staging
Phase 3 : déploiement automatique en production Phase 4 : Monitoring avancé et optimisations

Puis-je faire du CI/CD sans cloud ?

Oui ! Avec Jenkins ou GitLab self-hosted sur vos serveurs. Mais le cloud simplifie la maintenance.

Le CI/CD demande un investissement initial, mais les gains en productivité et en qualité sont énormes. Commencez petit, et itérez progressivement !

Travaillons ensemble

Vous cherchez un développeur freelance pour créer un site web ou une application sur mesure ? Contactez-moi pour discuter de votre projet et obtenir un devis personnalisé.