# 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** :
```bash
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** :
```dockerfile
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
```bash
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
```bash
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
```bash
# 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
```bash
# 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**
   ```bash
   GET https://api-preprod.xpeditis.com/health
   Expected: HTTP 200 OK
   ```

2. **Swagger Documentation**
   ```bash
   GET https://api-preprod.xpeditis.com/api/docs
   Expected: HTTP 200 or 301
   ```

3. **Rate Search Endpoint**
   ```bash
   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**
   ```bash
   GET https://app-preprod.xpeditis.com
   Expected: HTTP 200 OK
   ```

2. **Login Page**
   ```bash
   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)
```bash
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)
```bash
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 **Stacks** → **xpeditis**
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
```bash
# 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
```bash
# 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

```bash
# 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

```bash
# 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é)
```yaml
# Ajouter dans le workflow
if: "!contains(github.event.head_commit.message, '[skip tests]')"
```

Puis commit avec :
```bash
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** :
```bash
# 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** :
```bash
# 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 :
- [Configuration des Secrets GitHub](GITHUB-SECRETS-SETUP.md)
- [Guide de Déploiement Portainer](../docker/PORTAINER-DEPLOYMENT-GUIDE.md)
- [Documentation GitHub Actions](https://docs.github.com/en/actions)
