pipeline { agent any parameters { string( name: 'REPO_URL', defaultValue: 'https://git.crowmate.fr/crowmate/Nest.git', description: 'URL du repo Gitea (pour récupérer le docker-compose.prod.yml)' ) string( name: 'BRANCH', defaultValue: 'main', description: 'Branche' ) string( name: 'STACK_NAME', defaultValue: 'nest', description: 'Nom de la stack dans Portainer' ) string( name: 'IMAGE_TAG', defaultValue: 'latest', description: 'Tag des images à déployer' ) } environment { GITEA_CREDENTIALS_ID = 'gitea-token' PORTAINER_URL = 'https://docker.devgoblin.fr' PORTAINER_ENV_ID = '3' } stages { stage('Clone') { steps { cleanWs() checkout([ $class: 'GitSCM', branches: [[name: "*/${params.BRANCH}"]], userRemoteConfigs: [[ url: params.REPO_URL, credentialsId: env.GITEA_CREDENTIALS_ID ]] ]) echo "✅ Repo cloné" } } stage('Validation') { steps { script { if (!fileExists('docker-compose.prod.yml')) { error("❌ docker-compose.prod.yml introuvable à la racine du repo !") } echo "✅ docker-compose.prod.yml trouvé" } } } stage('Deploy sur Portainer') { steps { withCredentials([string(credentialsId: 'portainer-token', variable: 'PORTAINER_TOKEN')]) { sh ''' COMPOSE_CONTENT=$(base64 -w 0 docker-compose.prod.yml) # Récupère la liste des stacks STACKS=$(curl -s -X GET "''' + env.PORTAINER_URL + '''/api/stacks" \ -H "X-API-Key: $PORTAINER_TOKEN") # Cherche si la stack existe déjà STACK_ID=$(echo "$STACKS" | jq -r '.[] | select(.Name == "''' + params.STACK_NAME + '''") | .Id') if [ -n "$STACK_ID" ]; then echo "🔄 Stack existante (ID: $STACK_ID), mise à jour..." RESPONSE=$(curl -s -X PUT "''' + env.PORTAINER_URL + '''/api/stacks/$STACK_ID?endpointId=''' + env.PORTAINER_ENV_ID + '''" \ -H "X-API-Key: $PORTAINER_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"stackFileContent\": \"$COMPOSE_CONTENT\", \"prune\": true, \"pullImage\": true}") else echo "🚀 Création de la stack ''' + params.STACK_NAME + '''..." RESPONSE=$(curl -s -X POST "''' + env.PORTAINER_URL + '''/api/stacks/create/standalone/string?endpointId=''' + env.PORTAINER_ENV_ID + '''" \ -H "X-API-Key: $PORTAINER_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"name\": \"''' + params.STACK_NAME + '''\", \"stackFileContent\": \"$COMPOSE_CONTENT\"}") fi # Vérifie si la réponse contient une erreur if echo "$RESPONSE" | jq -e '.message' > /dev/null 2>&1; then echo "❌ Erreur Portainer : $(echo $RESPONSE | jq -r '.message')" exit 1 fi echo "✅ Stack déployée avec succès !" ''' } } } } post { success { echo "🎉 Stack '${params.STACK_NAME}' déployée sur Portainer (tag: ${params.IMAGE_TAG})" } failure { echo "💥 Échec du déploiement de la stack '${params.STACK_NAME}'" } } }