|
|
@@ -40,60 +40,60 @@ pipeline {
|
|
|
}
|
|
|
|
|
|
// 2. Installation des dépendances et tests unitaires Angular
|
|
|
- stage('Unit Tests') {
|
|
|
- agent {
|
|
|
- docker {
|
|
|
- image 'cypress/browsers:node14.17.0-chrome91-ff89'
|
|
|
- args '-u root:root --shm-size=2g'
|
|
|
- }
|
|
|
- }
|
|
|
- environment {
|
|
|
- CHROME_BIN = '/usr/bin/google-chrome'
|
|
|
- NODE_OPTIONS = '--max-old-space-size=4096'
|
|
|
- DISPLAY = ':99'
|
|
|
- }
|
|
|
- steps {
|
|
|
- dir('angular-client') {
|
|
|
- sh '''
|
|
|
- echo "🔧 Configuration de l'environnement"
|
|
|
- export DISPLAY=:99
|
|
|
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
|
|
|
-
|
|
|
- echo "✅ Installation des dépendances"
|
|
|
- npm install --legacy-peer-deps
|
|
|
-
|
|
|
- echo "🧪 Vérification de Chrome"
|
|
|
- google-chrome --version
|
|
|
-
|
|
|
- echo "🚀 Lancement des tests unitaires avec couverture"
|
|
|
- npx ng test --no-watch --no-progress --browsers=ChromeHeadlessCI --code-coverage
|
|
|
- '''
|
|
|
- }
|
|
|
- }
|
|
|
- post {
|
|
|
- always {
|
|
|
- // Publier le rapport de couverture HTML
|
|
|
- publishHTML([
|
|
|
- allowMissing: false,
|
|
|
- alwaysLinkToLastBuild: false,
|
|
|
- keepAll: true,
|
|
|
- reportDir: 'angular-client/coverage/fatboar-burger',
|
|
|
- reportFiles: 'index.html',
|
|
|
- reportName: 'Code Coverage Report',
|
|
|
- reportTitles: 'Coverage Report'
|
|
|
- ])
|
|
|
+// stage('Unit Tests') {
|
|
|
+// agent {
|
|
|
+// docker {
|
|
|
+// image 'cypress/browsers:node14.17.0-chrome91-ff89'
|
|
|
+// args '-u root:root --shm-size=2g'
|
|
|
+// }
|
|
|
+// }
|
|
|
+// environment {
|
|
|
+// CHROME_BIN = '/usr/bin/google-chrome'
|
|
|
+// NODE_OPTIONS = '--max-old-space-size=4096'
|
|
|
+// DISPLAY = ':99'
|
|
|
+// }
|
|
|
+// steps {
|
|
|
+// dir('angular-client') {
|
|
|
+// sh '''
|
|
|
+// echo "🔧 Configuration de l'environnement"
|
|
|
+// export DISPLAY=:99
|
|
|
+// Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
|
|
|
+
|
|
|
+// echo "✅ Installation des dépendances"
|
|
|
+// npm install --legacy-peer-deps
|
|
|
+
|
|
|
+// echo "🧪 Vérification de Chrome"
|
|
|
+// google-chrome --version
|
|
|
+
|
|
|
+// echo "🚀 Lancement des tests unitaires avec couverture"
|
|
|
+// npx ng test --no-watch --no-progress --browsers=ChromeHeadlessCI --code-coverage
|
|
|
+// '''
|
|
|
+// }
|
|
|
+// }
|
|
|
+// post {
|
|
|
+// always {
|
|
|
+// // Publier le rapport de couverture HTML
|
|
|
+// publishHTML([
|
|
|
+// allowMissing: false,
|
|
|
+// alwaysLinkToLastBuild: false,
|
|
|
+// keepAll: true,
|
|
|
+// reportDir: 'angular-client/coverage/fatboar-burger',
|
|
|
+// reportFiles: 'index.html',
|
|
|
+// reportName: 'Code Coverage Report',
|
|
|
+// reportTitles: 'Coverage Report'
|
|
|
+// ])
|
|
|
|
|
|
- // Archiver les artefacts de couverture
|
|
|
- archiveArtifacts artifacts: 'angular-client/coverage/**/*', fingerprint: true
|
|
|
- }
|
|
|
- failure {
|
|
|
- echo '❌ Tests échoués - Vérifiez les logs ci-dessus'
|
|
|
- }
|
|
|
- success {
|
|
|
- echo '✅ Tests réussis avec couverture générée'
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
+// // Archiver les artefacts de couverture
|
|
|
+// archiveArtifacts artifacts: 'angular-client/coverage/**/*', fingerprint: true
|
|
|
+// }
|
|
|
+// failure {
|
|
|
+// echo '❌ Tests échoués - Vérifiez les logs ci-dessus'
|
|
|
+// }
|
|
|
+// success {
|
|
|
+// echo '✅ Tests réussis avec couverture générée'
|
|
|
+// }
|
|
|
+// }
|
|
|
+// }
|
|
|
// 3. Analyse SonarQube pour la qualité du code
|
|
|
// stage('SonarQube Analysis') {
|
|
|
// steps {
|
|
|
@@ -133,11 +133,112 @@ pipeline {
|
|
|
// }
|
|
|
|
|
|
// 6. Lancement des backups après déploiement
|
|
|
+ // 6. Lancement des backups après déploiement
|
|
|
stage('Backup') {
|
|
|
steps {
|
|
|
script {
|
|
|
- echo "Lancement du backup sur le container ${env.BACKUP_CONTAINER}"
|
|
|
- sh "docker exec ${env.BACKUP_CONTAINER} /backup.sh || echo '⚠️ Backup ${env.ENV.toUpperCase()} échoué'"
|
|
|
+ echo "🚀 Lancement du backup sur le container ${env.BACKUP_CONTAINER}"
|
|
|
+
|
|
|
+ try {
|
|
|
+ // Vérifier que le conteneur backup existe
|
|
|
+ def containerExists = sh(
|
|
|
+ script: "docker ps -a --filter name=${env.BACKUP_CONTAINER} --format '{{.Names}}'",
|
|
|
+ returnStdout: true
|
|
|
+ ).trim()
|
|
|
+
|
|
|
+ if (!containerExists) {
|
|
|
+ echo "⚠️ Container ${env.BACKUP_CONTAINER} n'existe pas, lancement du service..."
|
|
|
+ sh "docker-compose -f ${env.COMPOSE_FILE} up -d mongodb-backup-${env.ENV}"
|
|
|
+ sleep(30) // Attendre que le service soit prêt
|
|
|
+ }
|
|
|
+
|
|
|
+ // Vérifier que le conteneur est en cours d'exécution
|
|
|
+ def containerStatus = sh(
|
|
|
+ script: "docker ps --filter name=${env.BACKUP_CONTAINER} --format '{{.Status}}'",
|
|
|
+ returnStdout: true
|
|
|
+ ).trim()
|
|
|
+
|
|
|
+ if (containerStatus.contains('Up')) {
|
|
|
+ echo "✅ Container ${env.BACKUP_CONTAINER} est actif"
|
|
|
+
|
|
|
+ // Attendre un peu que MongoDB soit prêt si le conteneur vient d'être démarré
|
|
|
+ echo "⏳ Vérification de la connectivité MongoDB..."
|
|
|
+ sleep(10)
|
|
|
+
|
|
|
+ // Déclencher le backup manuel avec tiredofit/mongodb-backup
|
|
|
+ echo "💾 Déclenchement du backup manuel..."
|
|
|
+ def backupExitCode = sh(
|
|
|
+ script: "docker exec ${env.BACKUP_CONTAINER} /usr/sbin/backup-now",
|
|
|
+ returnStatus: true
|
|
|
+ )
|
|
|
+
|
|
|
+ if (backupExitCode == 0) {
|
|
|
+ // Vérifier les fichiers de backup créés
|
|
|
+ def backupFiles = sh(
|
|
|
+ script: "docker exec ${env.BACKUP_CONTAINER} find /backup -name '*.gz' -type f -mtime -1 | head -5",
|
|
|
+ returnStdout: true
|
|
|
+ ).trim()
|
|
|
+
|
|
|
+ if (backupFiles) {
|
|
|
+ echo "✅ Backup ${env.ENV.toUpperCase()} réussi !"
|
|
|
+ echo "📁 Fichiers de backup récents :"
|
|
|
+ backupFiles.split('\n').each { file ->
|
|
|
+ if (file.trim()) {
|
|
|
+ def fileInfo = sh(
|
|
|
+ script: "docker exec ${env.BACKUP_CONTAINER} ls -lh '${file.trim()}'",
|
|
|
+ returnStdout: true
|
|
|
+ ).trim()
|
|
|
+ echo " ${fileInfo}"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ echo "⚠️ Aucun fichier de backup récent trouvé"
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ echo "❌ Le processus de backup a retourné un code d'erreur : ${backupExitCode}"
|
|
|
+
|
|
|
+ // Afficher les logs pour diagnostic
|
|
|
+ def containerLogs = sh(
|
|
|
+ script: "docker logs --tail 20 ${env.BACKUP_CONTAINER} 2>&1 || echo 'Impossible de récupérer les logs'",
|
|
|
+ returnStdout: true
|
|
|
+ )
|
|
|
+ echo "📋 Logs du conteneur backup :"
|
|
|
+ echo "${containerLogs}"
|
|
|
+
|
|
|
+ // Marquer comme unstable mais ne pas faire échouer le pipeline
|
|
|
+ currentBuild.result = 'UNSTABLE'
|
|
|
+ echo "⚠️ Backup échoué mais le déploiement continue"
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ echo "❌ Container ${env.BACKUP_CONTAINER} n'est pas actif"
|
|
|
+ echo "🔄 Tentative de redémarrage du service..."
|
|
|
+
|
|
|
+ sh """
|
|
|
+ docker-compose -f ${env.COMPOSE_FILE} restart mongodb-backup-${env.ENV} || true
|
|
|
+ sleep 30
|
|
|
+ """
|
|
|
+
|
|
|
+ // Nouvelle tentative après redémarrage
|
|
|
+ def retryExitCode = sh(
|
|
|
+ script: "docker exec ${env.BACKUP_CONTAINER} /usr/sbin/backup-now",
|
|
|
+ returnStatus: true
|
|
|
+ )
|
|
|
+
|
|
|
+ if (retryExitCode == 0) {
|
|
|
+ echo "✅ Backup ${env.ENV.toUpperCase()} réussi après redémarrage"
|
|
|
+ } else {
|
|
|
+ echo "❌ Backup ${env.ENV.toUpperCase()} échoué même après redémarrage"
|
|
|
+ currentBuild.result = 'UNSTABLE'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ echo "❌ Erreur lors du backup: ${e.getMessage()}"
|
|
|
+ echo "⚠️ Le backup a échoué mais le déploiement continue"
|
|
|
+ currentBuild.result = 'UNSTABLE'
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|