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
525 lines
15 KiB
Markdown
525 lines
15 KiB
Markdown
# 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)
|