From 72bdd217437ed3569d48f0c4dc3b3738b8e9e2e9 Mon Sep 17 00:00:00 2001 From: soufiane Date: Mon, 1 Dec 2025 23:30:44 +0100 Subject: [PATCH] fix: run SonarQube after tests to include coverage report MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tests and SonarQube were running in parallel in separate Docker containers. This meant SonarQube never had access to the coverage/lcov.info file generated by Jest. Changes: - Run Lint & Tests stage first - Stash coverage report after tests - Run SonarQube stage after, unstashing coverage - Update pipeline documentation This fix ensures SonarQube receives the actual test coverage data. đŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- Jenkinsfile | 117 +++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 61 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 81e27f2..b40b40f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -9,7 +9,8 @@ * 1. Init - DĂ©tection de l'environnement (dev/preprod/prod) * 2. Checkout - RĂ©cupĂ©ration du code source depuis Git * 3. Install - Installation des dĂ©pendances Node.js - * 4. Quality - VĂ©rification qualitĂ© (ESLint + Jest + SonarQube) + * 4a. Lint & Tests - ESLint + Jest avec couverture de code + * 4b. SonarQube - Analyse statique (aprĂšs tests pour avoir la couverture) * 5. Build - Construction de l'image Docker (avec variables env) * 6. Push - Envoi de l'image vers le registre Docker privĂ© * 7. Deploy - DĂ©ploiement sur le serveur cible @@ -130,73 +131,67 @@ pipeline { } // ===================================================================== - // ÉTAPE 4 : CONTRÔLES QUALITÉ (ExĂ©cution parallĂšle) + // ÉTAPE 4a : LINT & TESTS // --------------------------------------------------------------------- - // ExĂ©cute en parallĂšle : - // - Lint & Tests : ESLint + Jest avec couverture de code - // - SonarQube : Analyse statique de la qualitĂ© du code + // ESLint : VĂ©rifie le style et les erreurs de code + // Jest : ExĂ©cute les tests unitaires React/Next.js + // Couverture : GĂ©nĂšre un rapport de couverture (lcov) // ===================================================================== - stage('🔍 Quality - ContrĂŽles qualitĂ©') { - parallel { - // ------------------------------------------------------------- - // 4a. LINT & TESTS - // ------------------------------------------------------------- - // ESLint : VĂ©rifie le style et les erreurs de code - // Jest : ExĂ©cute les tests unitaires React/Next.js - // Couverture : GĂ©nĂšre un rapport de couverture (lcov) - // ------------------------------------------------------------- - stage('đŸ§Ș Lint & Tests') { - agent { - docker { - image 'node:20' - args "-u root -v ${NPM_CACHE}:/root/.npm" - } - } - steps { - unstash 'node_modules' - echo "đŸ§Ș Lancement ESLint et Jest..." - script { - def lintStatus = sh(script: 'npm run lint', returnStatus: true) - def testStatus = sh(script: 'npm test', returnStatus: true) - - if (lintStatus != 0) { - error "❌ ESLint a Ă©chouĂ© - Corrigez les erreurs de style" - } - if (testStatus != 0) { - error "❌ Les tests ont Ă©chouĂ© - VĂ©rifiez les tests unitaires" - } - echo "✅ Lint et tests passĂ©s avec succĂšs" - } - } + stage('đŸ§Ș Lint & Tests') { + agent { + docker { + image 'node:20' + args "-u root -v ${NPM_CACHE}:/root/.npm" } + } + steps { + unstash 'node_modules' + echo "đŸ§Ș Lancement ESLint et Jest..." + script { + def lintStatus = sh(script: 'npm run lint', returnStatus: true) + def testStatus = sh(script: 'npm test', returnStatus: true) - // ------------------------------------------------------------- - // 4b. SONARQUBE - // ------------------------------------------------------------- - // Analyse statique du code pour dĂ©tecter : - // - Bugs potentiels - // - VulnĂ©rabilitĂ©s de sĂ©curitĂ© - // - Code smells (mauvaises pratiques) - // - Couverture de code insuffisante - // - Duplications de code - // ------------------------------------------------------------- - stage('📊 SonarQube Analysis') { - agent { - docker { - image 'sonarsource/sonar-scanner-cli:latest' - args '-u root' - } + if (lintStatus != 0) { + error "❌ ESLint a Ă©chouĂ© - Corrigez les erreurs de style" } - steps { - echo "📊 Analyse SonarQube en cours..." - withSonarQubeEnv('SonarQube') { - sh """ - sonar-scanner - """ - } - echo "✅ Analyse SonarQube terminĂ©e" + if (testStatus != 0) { + error "❌ Les tests ont Ă©chouĂ© - VĂ©rifiez les tests unitaires" } + echo "✅ Lint et tests passĂ©s avec succĂšs" } + // Stash coverage report for SonarQube + stash includes: 'coverage/**', name: 'coverage' + } + } + + // ===================================================================== + // ÉTAPE 4b : SONARQUBE + // --------------------------------------------------------------------- + // Analyse statique du code pour dĂ©tecter : + // - Bugs potentiels + // - VulnĂ©rabilitĂ©s de sĂ©curitĂ© + // - Code smells (mauvaises pratiques) + // - Couverture de code insuffisante + // - Duplications de code + // NOTE: ExĂ©cutĂ© APRÈS les tests pour avoir accĂšs au rapport de couverture + // ===================================================================== + stage('📊 SonarQube Analysis') { + agent { + docker { + image 'sonarsource/sonar-scanner-cli:latest' + args '-u root' + } + } + steps { + // Unstash coverage report from tests + unstash 'coverage' + echo "📊 Analyse SonarQube en cours..." + withSonarQubeEnv('SonarQube') { + sh """ + sonar-scanner + """ + } + echo "✅ Analyse SonarQube terminĂ©e" } }