pipeline { agent any options { ansiColor('xterm'); timestamps(); disableConcurrentBuilds() timeout(time: 25, unit: 'MINUTES') } /* ให้ Gitea ยิง webhook แล้ว build ได้เลย */ triggers { giteaPush() } environment { REGISTRY = 'registry.aetherframe.tech' IMAGE = 'simulationable/eop-services-api' // แนะนำเป็นตัวพิมพ์เล็กทั้งหมด APP_PORT = '8080' // Kestrel ใน container ฟัง 8080 HOST_PORT = '5002' // พอร์ตฝั่ง host ที่ Nginx จะ proxy เข้า } stages { stage('Checkout') { steps { checkout scm } } stage('Unit Tests (optional)') { when { expression { fileExists('AMREZ.EOP.sln') } } steps { sh ''' docker run --rm -v "$PWD":/src -w /src mcr.microsoft.com/dotnet/sdk:9.0 \ bash -lc "dotnet test --configuration Release --nologo --logger trx; true" ''' } } stage('Docker Build') { steps { sh 'docker version' script { /* รองรับทั้ง Multibranch (BRANCH_NAME) และ Pipeline เดี่ยว (GIT_BRANCH) */ def branch = (env.BRANCH_NAME ?: env.GIT_BRANCH ?: 'main').replaceFirst(/^origin\\//,'') def tag = "${branch}-${env.BUILD_NUMBER}" sh """ docker build -t ${REGISTRY}/${IMAGE}:${tag} . docker tag ${REGISTRY}/${IMAGE}:${tag} ${REGISTRY}/${IMAGE}:latest """ env.IMAGE_TAG = tag } } } stage('Docker Push') { steps { withCredentials([usernamePassword(credentialsId: 'registry-basic', usernameVariable: 'REG_USER', passwordVariable: 'REG_PASS')]) { sh """ echo "\$REG_PASS" | docker login ${REGISTRY} -u "\$REG_USER" --password-stdin docker push ${REGISTRY}/${IMAGE}:${IMAGE_TAG} docker push ${REGISTRY}/${IMAGE}:latest docker logout ${REGISTRY} || true """ } } } stage('Deploy (same host)') { when { branch 'main' } steps { sh """ set -eux docker rm -f eop-services-api || true docker run -d --name eop-services-api \\ -p 127.0.0.1:${HOST_PORT}:${APP_PORT} \\ -e ASPNETCORE_URLS=http://+:${APP_PORT} \\ --restart=always \\ ${REGISTRY}/${IMAGE}:latest """ } } } post { success { echo "Deployed at http://127.0.0.1:${HOST_PORT} (จะเข้าผ่าน https หลังตั้ง Nginx)" } always { cleanWs() } } }