pipeline { agent any // 🔁 VĂ©rifie toutes les 2 minutes si du nouveau code a Ă©tĂ© poussĂ© triggers { pollSCM('H/2 * * * *') } // ⚙ ParamĂštre manuel (fallback) parameters { choice( name: 'ENV', choices: ['dev', 'preprod', 'prod'], description: 'Choisir l’environnement de dĂ©ploiement (automatique si branche correspondante)' ) } environment { REGISTRY_URL = "registry.wk-archi-o24a-15m-g3.fr" IMAGE_NAME = "the-tip-top-backend" } stages { /* ─────────────────────────────── * 1ïžâƒŁ Init — DĂ©tection automatique de l’environnement * ─────────────────────────────── */ stage('Init') { steps { script { // 🔍 DĂ©termine la branche Git courante def currentBranch = sh(script: "git rev-parse --abbrev-ref HEAD", returnStdout: true).trim() echo "🧭 Branche dĂ©tectĂ©e : ${currentBranch}" // đŸ§© Si la branche correspond Ă  un environnement connu, on l’utilise if (["dev", "preprod", "main"].contains(currentBranch)) { env.ENV = (currentBranch == "main") ? "prod" : currentBranch } else { env.ENV = params.ENV ?: "dev" } // đŸ§± Variables de dĂ©ploiement dĂ©rivĂ©es env.TAG = "${env.ENV}-latest" env.DEPLOY_PATH = "/srv/devops/the-tip-top/${env.ENV}" echo """ 🌍 Environnement = ${env.ENV} đŸ·ïž Tag Docker = ${env.TAG} 📂 Chemin de dĂ©ploiement = ${env.DEPLOY_PATH} """ } } } stage('Checkout') { steps { echo "📩 RĂ©cupĂ©ration du code source depuis Gitea..." checkout scm } } stage('Tests & QualitĂ©') { steps { echo "đŸ§Ș Lancement des tests et analyse de code..." sh ''' npm ci npm run lint || echo "⚠ Erreurs de lint dĂ©tectĂ©es" npm test || echo "⚠ Tests Ă©chouĂ©s — vĂ©rifier les logs" ''' } } stage('Build Docker image') { steps { echo "🐳 Construction de l’image Docker backend..." sh """ docker build -t ${REGISTRY_URL}/${IMAGE_NAME}:${TAG} . docker tag ${REGISTRY_URL}/${IMAGE_NAME}:${TAG} ${REGISTRY_URL}/${IMAGE_NAME}:latest """ } } stage('Push to Registry') { steps { echo "đŸ“€ Envoi de l’image vers le registre Docker privĂ©..." withCredentials([usernamePassword(credentialsId: 'registry-credentials', usernameVariable: 'REG_USER', passwordVariable: 'REG_PASS')]) { sh """ echo "$REG_PASS" | docker login ${REGISTRY_URL} -u "$REG_USER" --password-stdin docker push ${REGISTRY_URL}/${IMAGE_NAME}:${TAG} docker push ${REGISTRY_URL}/${IMAGE_NAME}:latest """ } } } stage('Backup Before Deploy') { steps { echo "đŸ’Ÿ ExĂ©cution du script de sauvegarde avant dĂ©ploiement..." sh ''' if [ -f /srv/devops/the-tip-top/backup.sh ]; then bash /srv/devops/the-tip-top/backup.sh else echo "⚠ Aucun script backup.sh trouvĂ©." fi ''' } } stage('Deploy') { steps { echo "🚀 DĂ©ploiement du backend sur ${env.ENV}..." sh ''' if [ ! -f "${DEPLOY_PATH}/docker-compose.yml" ]; then echo "❌ Fichier docker-compose.yml introuvable dans ${DEPLOY_PATH}" exit 1 fi cd "${DEPLOY_PATH}" docker compose pull backend docker compose up -d --force-recreate backend ''' } } stage('Health Check') { steps { echo "đŸ©ș VĂ©rification du backend aprĂšs dĂ©ploiement..." script { def domain = (env.ENV == 'dev') ? "api.dev.dsp5-archi-o24a-15m-g3.fr" : (env.ENV == 'preprod') ? "api.preprod.dsp5-archi-o24a-15m-g3.fr" : "api.dsp5-archi-o24a-15m-g3.fr" def statusCode = "000" for (int i = 1; i <= 10; i++) { statusCode = sh(script: "curl -k -s -o /dev/null -w '%{http_code}' https://${domain}/health || echo 000", returnStdout: true).trim() if (statusCode in ['200', '301', '302']) { echo "✅ Backend ${env.ENV} opĂ©rationnel (HTTP ${statusCode})" return } echo "⏳ Tentative ${i}/10 → HTTP ${statusCode}" sleep 5 } error("❌ Health check Ă©chouĂ© - code HTTP ${statusCode}") } } } } post { success { echo "✅ Pipeline backend ${env.ENV} terminĂ© avec succĂšs !" } failure { echo "❌ Échec du pipeline backend pour ${env.ENV}." } } }