xpeditis2.0/.github/CI-CD-WORKFLOW.md
David 890bc189ee
Some checks failed
CI/CD Pipeline - Xpeditis PreProd / Frontend - Build & Test (push) Failing after 5m31s
CI/CD Pipeline - Xpeditis PreProd / Frontend - Docker Build & Push (push) Has been skipped
CI/CD Pipeline - Xpeditis PreProd / Backend - Build & Test (push) Failing after 5m42s
CI/CD Pipeline - Xpeditis PreProd / Backend - Docker Build & Push (push) Has been skipped
CI/CD Pipeline - Xpeditis PreProd / Deploy to PreProd Server (push) Has been skipped
CI/CD Pipeline - Xpeditis PreProd / Run Smoke Tests (push) Has been skipped
fix v0.2
2025-11-12 18:00:33 +01:00

15 KiB

CI/CD Workflow - Xpeditis PreProd

Ce document décrit le pipeline CI/CD automatisé pour déployer Xpeditis sur l'environnement de préproduction.

Vue d'Ensemble

Le pipeline CI/CD s'exécute automatiquement à chaque push ou pull request sur la branche preprod. Il effectue les opérations suivantes :

┌─────────────────────────────────────────────────────────────────┐
│                    TRIGGER: Push sur preprod                     │
└────────────────────────┬────────────────────────────────────────┘
                         │
         ┌───────────────┴───────────────┐
         │                               │
         ▼                               ▼
┌──────────────────┐            ┌──────────────────┐
│  Backend Build   │            │ Frontend Build   │
│  & Test          │            │  & Test          │
│                  │            │                  │
│ • ESLint         │            │ • ESLint         │
│ • Unit Tests     │            │ • Type Check     │
│ • Integration    │            │ • Build Next.js  │
│ • Build NestJS   │            │                  │
└────────┬─────────┘            └────────┬─────────┘
         │                               │
         ▼                               ▼
┌──────────────────┐            ┌──────────────────┐
│  Backend Docker  │            │ Frontend Docker  │
│  Build & Push    │            │  Build & Push    │
│                  │            │                  │
│ • Build Image    │            │ • Build Image    │
│ • Push to SCW    │            │ • Push to SCW    │
│ • Tag: preprod   │            │ • Tag: preprod   │
└────────┬─────────┘            └────────┬─────────┘
         │                               │
         └───────────────┬───────────────┘
                         │
                         ▼
                ┌────────────────┐
                │ Deploy PreProd │
                │                │
                │ • Portainer    │
                │   Webhook      │
                │ • Health Check │
                │ • Notification │
                └────────┬───────┘
                         │
                         ▼
                ┌────────────────┐
                │  Smoke Tests   │
                │                │
                │ • API Health   │
                │ • Endpoints    │
                │ • Frontend     │
                └────────────────┘

Jobs Détaillés

1. Backend Build & Test (~5-7 minutes)

Objectif : Valider le code backend et s'assurer qu'il compile sans erreur

Étapes :

  1. Checkout : Récupère le code source
  2. Setup Node.js : Configure Node.js 20 avec cache npm
  3. Install Dependencies : npm ci dans apps/backend
  4. ESLint : Vérifie le style et la qualité du code
  5. Unit Tests : Exécute les tests unitaires (domaine)
  6. Integration Tests : Lance PostgreSQL + Redis et exécute les tests d'intégration
  7. Build : Compile TypeScript → JavaScript
  8. Upload Artifacts : Sauvegarde le dossier dist pour inspection

Technologies :

  • Node.js 20
  • PostgreSQL 15 (container)
  • Redis 7 (container)
  • Jest
  • TypeScript

Conditions d'échec :

  • Erreurs de syntaxe TypeScript
  • Tests unitaires échoués
  • Tests d'intégration échoués
  • Erreurs ESLint

2. Frontend Build & Test (~4-6 minutes)

Objectif : Valider le code frontend et s'assurer qu'il compile sans erreur

Étapes :

  1. Checkout : Récupère le code source
  2. Setup Node.js : Configure Node.js 20 avec cache npm
  3. Install Dependencies : npm ci dans apps/frontend
  4. ESLint : Vérifie le style et la qualité du code
  5. Type Check : Vérifie les types TypeScript (tsc --noEmit)
  6. Build : Compile Next.js avec les variables d'environnement preprod
  7. Upload Artifacts : Sauvegarde le dossier .next pour inspection

Technologies :

  • Node.js 20
  • Next.js 14
  • TypeScript
  • Tailwind CSS

Variables d'environnement :

NEXT_PUBLIC_API_URL=https://api-preprod.xpeditis.com
NEXT_PUBLIC_WS_URL=wss://api-preprod.xpeditis.com

Conditions d'échec :

  • Erreurs de syntaxe TypeScript
  • Erreurs de compilation Next.js
  • Erreurs ESLint
  • Type errors

3. Backend Docker Build & Push (~3-5 minutes)

Objectif : Construire l'image Docker du backend et la pousser vers le registre Scaleway

Étapes :

  1. Checkout : Récupère le code source
  2. Setup QEMU : Support multi-plateforme (ARM64, AMD64)
  3. Setup Buildx : Builder Docker avancé avec cache
  4. Login Registry : Authentification Scaleway Container Registry
  5. Extract Metadata : Génère les tags pour l'image (preprod, preprod-SHA)
  6. Build & Push : Construit et pousse l'image avec cache layers
  7. Docker Cleanup : Nettoie les images temporaires

Image produite :

rg.fr-par.scw.cloud/xpeditis/backend:preprod
rg.fr-par.scw.cloud/xpeditis/backend:preprod-abc1234

Cache :

  • Cache des layers Docker pour accélérer les builds suivants
  • Cache des dépendances npm

Taille estimée : ~800 MB (Node.js Alpine + dépendances)


4. Frontend Docker Build & Push (~3-5 minutes)

Objectif : Construire l'image Docker du frontend et la pousser vers le registre Scaleway

Étapes :

  1. Checkout : Récupère le code source
  2. Setup QEMU : Support multi-plateforme
  3. Setup Buildx : Builder Docker avancé avec cache
  4. Login Registry : Authentification Scaleway Container Registry
  5. Extract Metadata : Génère les tags pour l'image
  6. Build & Push : Construit et pousse l'image avec build args
  7. Docker Cleanup : Nettoie les images temporaires

Build Args :

NODE_ENV=production
NEXT_PUBLIC_API_URL=https://api-preprod.xpeditis.com
NEXT_PUBLIC_WS_URL=wss://api-preprod.xpeditis.com

Image produite :

rg.fr-par.scw.cloud/xpeditis/frontend:preprod
rg.fr-par.scw.cloud/xpeditis/frontend:preprod-abc1234

Taille estimée : ~500 MB (Node.js Alpine + Next.js build)


5. Deploy to PreProd (~2-3 minutes)

Objectif : Déployer les nouvelles images sur le serveur preprod via Portainer

Étapes :

5.1 Trigger Backend Webhook

POST https://portainer.xpeditis.com/api/webhooks/xxx-backend
{
  "service": "backend",
  "image": "rg.fr-par.scw.cloud/xpeditis/backend:preprod",
  "timestamp": "2025-01-15T10:30:00Z"
}

Ce qui se passe côté Portainer :

  1. Portainer reçoit le webhook
  2. Pull la nouvelle image backend:preprod
  3. Effectue un rolling update du service xpeditis-backend
  4. Démarre les nouveaux conteneurs
  5. Arrête les anciens conteneurs (0 downtime)

5.2 Wait for Backend Deployment

  • Attend 30 secondes pour que le backend démarre

5.3 Trigger Frontend Webhook

POST https://portainer.xpeditis.com/api/webhooks/xxx-frontend
{
  "service": "frontend",
  "image": "rg.fr-par.scw.cloud/xpeditis/frontend:preprod",
  "timestamp": "2025-01-15T10:30:00Z"
}

5.4 Wait for Frontend Deployment

  • Attend 30 secondes pour que le frontend démarre

5.5 Health Check Backend

# Vérifie que l'API répond (max 10 tentatives)
GET https://api-preprod.xpeditis.com/health
# Expected: HTTP 200 OK

5.6 Health Check Frontend

# Vérifie que le frontend répond (max 10 tentatives)
GET https://app-preprod.xpeditis.com
# Expected: HTTP 200 OK

5.7 Send Notification

Envoie une notification Discord (si configuré) avec :

  • Statut du déploiement (SUCCESS / FAILED)
  • 📝 Message du commit
  • 👤 Auteur du commit
  • 🔗 URLs des services
  • Timestamp

Exemple de notification Discord :

✅ Deployment PreProd - SUCCESS

Branch: preprod
Commit: abc1234
Author: David
Message: feat: add CSV booking workflow

Backend: https://api-preprod.xpeditis.com
Frontend: https://app-preprod.xpeditis.com

Timestamp: 2025-01-15T10:30:00Z

6. Smoke Tests (~1-2 minutes)

Objectif : Vérifier que les services déployés fonctionnent correctement

Tests Backend :

  1. Health Endpoint

    GET https://api-preprod.xpeditis.com/health
    Expected: HTTP 200 OK
    
  2. Swagger Documentation

    GET https://api-preprod.xpeditis.com/api/docs
    Expected: HTTP 200 or 301
    
  3. Rate Search Endpoint

    POST https://api-preprod.xpeditis.com/api/v1/rates/search-csv
    Body: {
      "origin": "NLRTM",
      "destination": "USNYC",
      "volumeCBM": 5,
      "weightKG": 1000,
      "palletCount": 3
    }
    Expected: HTTP 200 or 401 (unauthorized)
    

Tests Frontend :

  1. Homepage

    GET https://app-preprod.xpeditis.com
    Expected: HTTP 200 OK
    
  2. Login Page

    GET https://app-preprod.xpeditis.com/login
    Expected: HTTP 200 OK
    

Résultat :

================================================
✅ All smoke tests passed successfully!
================================================
Backend API:  https://api-preprod.xpeditis.com
Frontend App: https://app-preprod.xpeditis.com
Swagger Docs: https://api-preprod.xpeditis.com/api/docs
================================================

Durée Totale du Pipeline

Temps estimé : ~18-26 minutes

Job Durée Parallèle
Backend Build & Test 5-7 min
Frontend Build & Test 4-6 min
Backend Docker 3-5 min
Frontend Docker 3-5 min
Deploy PreProd 2-3 min
Smoke Tests 1-2 min

Avec parallélisation :

  • Build & Test (parallèle) : ~7 min
  • Docker (parallèle) : ~5 min
  • Deploy : ~3 min
  • Tests : ~2 min
  • Total : ~17 minutes

Variables d'Environnement

Backend (Production)

NODE_ENV=production
PORT=4000
DATABASE_HOST=xpeditis-db
DATABASE_PORT=5432
DATABASE_USER=xpeditis
DATABASE_PASSWORD=*** (secret Portainer)
DATABASE_NAME=xpeditis_prod
DATABASE_SSL=false
REDIS_HOST=xpeditis-redis
REDIS_PORT=6379
REDIS_PASSWORD=*** (secret Portainer)
JWT_SECRET=*** (secret Portainer)
AWS_S3_ENDPOINT=http://xpeditis-minio:9000
AWS_ACCESS_KEY_ID=*** (secret Portainer)
AWS_SECRET_ACCESS_KEY=*** (secret Portainer)
CORS_ORIGIN=https://app-preprod.xpeditis.com
FRONTEND_URL=https://app-preprod.xpeditis.com
API_URL=https://api-preprod.xpeditis.com

Frontend (Build Time)

NODE_ENV=production
NEXT_PUBLIC_API_URL=https://api-preprod.xpeditis.com
NEXT_PUBLIC_WS_URL=wss://api-preprod.xpeditis.com

Rollback en Cas d'Échec

Si un déploiement échoue, vous pouvez facilement revenir à la version précédente :

Option 1 : Via Portainer UI

  1. Allez dans Stacksxpeditis
  2. Sélectionnez le service (backend ou frontend)
  3. Cliquez sur Rollback
  4. Sélectionnez la version précédente
  5. Cliquez sur Apply

Option 2 : Via Portainer API

# Rollback backend
curl -X POST "https://portainer.xpeditis.com/api/services/xpeditis_xpeditis-backend/update?version=123" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"rollback": {"force": true}}'

# Rollback frontend
curl -X POST "https://portainer.xpeditis.com/api/services/xpeditis_xpeditis-frontend/update?version=456" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"rollback": {"force": true}}'

Option 3 : Redéployer une Version Précédente

# Sur votre machine locale
git checkout preprod
git log  # Trouver le SHA du commit précédent

# Revenir à un commit précédent
git reset --hard abc1234
git push origin preprod --force

# Le CI/CD va automatiquement déployer cette version

Monitoring du Pipeline

Voir les Logs GitHub Actions

  1. Allez sur GitHub : https://github.com/VOTRE_USERNAME/xpeditis/actions
  2. Cliquez sur le workflow en cours
  3. Cliquez sur un job pour voir ses logs détaillés

Voir les Logs des Services Déployés

# Logs backend
docker service logs xpeditis_xpeditis-backend -f --tail 100

# Logs frontend
docker service logs xpeditis_xpeditis-frontend -f --tail 100

Vérifier les Health Checks

# Backend
curl https://api-preprod.xpeditis.com/health

# Frontend
curl https://app-preprod.xpeditis.com

Optimisations Possibles

1. Cache des Dépendances npm

Déjà implémenté : Les dépendances npm sont cachées via actions/setup-node@v4

2. Cache des Layers Docker

Déjà implémenté : Utilise cache-from et cache-to de Buildx

3. Parallélisation des Jobs

Déjà implémenté : Backend et Frontend build/test en parallèle

4. Skip Tests pour Hotfix (Non recommandé)

# Ajouter dans le workflow
if: "!contains(github.event.head_commit.message, '[skip tests]')"

Puis commit avec :

git commit -m "hotfix: fix critical bug [skip tests]"

⚠️ Attention : Utiliser uniquement en cas d'urgence absolue !


Troubleshooting

Le pipeline échoue sur "Backend Build & Test"

Causes possibles :

  • Tests unitaires échoués
  • Tests d'intégration échoués
  • Erreurs TypeScript

Solution :

# Lancer les tests localement
cd apps/backend
npm run test
npm run test:integration

# Vérifier la compilation
npm run build

Le pipeline échoue sur "Docker Build & Push"

Causes possibles :

  • Token Scaleway invalide
  • Dockerfile incorrect
  • Dépendances manquantes

Solution :

# Tester le build localement
docker build -t test -f apps/backend/Dockerfile .

# Vérifier les logs GitHub Actions pour plus de détails

Le déploiement échoue sur "Health Check"

Causes possibles :

  • Service ne démarre pas correctement
  • Variables d'environnement incorrectes
  • Base de données non accessible

Solution :

  1. Vérifier les logs Portainer
  2. Vérifier les variables d'environnement dans la stack
  3. Vérifier que PostgreSQL, Redis, MinIO sont opérationnels

Support

Pour plus d'informations :