pipeline { agent none options { timestamps() disableConcurrentBuilds() skipDefaultCheckout() // stage별 agent의 자동 SCM checkout 방지 (Deploy 노드는 git 접근 불필요, unstash로만 WAR 수신) buildDiscarder(logRotator(numToKeepStr: '20', artifactNumToKeepStr: '20')) } environment { GIT_SSH_COMMAND = 'ssh -o StrictHostKeyChecking=accept-new' WEBHOOK_URL = 'http://172.30.1.50:18000/api/hooks/01ba51b01d3c4c98ae8f3183a23a84ed713197857d024b5da4f303458195eb32' } stages { stage('Build (djb-vm)') { agent { label 'djb-vm' } environment { JAVA_HOME = '/apps/opts/jdk8' GRADLE_HOME = '/apps/opts/gradle-8.7' GRADLE_USER_HOME = '/apps/opts/gradle-home' NODE_HOME = '/apps/opts/node-v24' PATH = "/apps/opts/jdk8/bin:/apps/opts/gradle-8.7/bin:/apps/opts/node-v24/bin:/apps/opts/bin:${env.PATH}" } stages { stage('Checkout') { steps { checkout scm } } stage('Checkout dependencies') { steps { sh ''' set -eu cd "$WORKSPACE/.." if [ ! -d elink-portal-common/.git ]; then rm -rf elink-portal-common git clone --depth=1 --branch master \ ssh://git@172.30.1.50:2222/djb-eapim/elink-portal-common.git elink-portal-common else git -C elink-portal-common fetch --depth=1 origin master git -C elink-portal-common reset --hard origin/master git -C elink-portal-common clean -fdx fi mkdir -p eapim-online if [ ! -d eapim-online/elink-online-core-jpa/.git ]; then rm -rf eapim-online/elink-online-core-jpa git clone --depth=1 --branch master \ ssh://git@172.30.1.50:2222/djb-eapim/elink-online-core-jpa.git eapim-online/elink-online-core-jpa else git -C eapim-online/elink-online-core-jpa fetch --depth=1 origin master git -C eapim-online/elink-online-core-jpa reset --hard origin/master git -C eapim-online/elink-online-core-jpa clean -fdx fi ''' } } stage('Verify toolchain') { steps { sh 'set -eu; java -version; gradle --version' } } stage('Test') { steps { sh 'gradle clean test --no-daemon -Pprofile=weblogic' } post { always { junit allowEmptyResults: true, testResults: 'build/test-results/test/*.xml' archiveArtifacts allowEmptyArchive: true, artifacts: 'build/reports/tests/test/**,build/test-results/test/**' } } } stage('Build WAR') { steps { sh 'gradle build -x test --no-daemon -Pprofile=weblogic' } post { success { sh ''' set -eu cd build/libs sha256sum eapim-portal.war > eapim-portal.war.sha256 ''' archiveArtifacts artifacts: 'build/libs/eapim-portal.war,build/libs/eapim-portal.war.sha256', fingerprint: true stash name: 'war', includes: 'build/libs/eapim-portal.war' } } } } } stage('Deploy (weblogic)') { agent { label 'weblogic' } environment { JENKINS_NODE_COOKIE = 'dontKillMe' // background weblogic를 빌드 종료 시 죽이지 않게 WL_HOME = '/app/eapim/devportal' WL_DEPLOY_DIR = '/app/eapim/devportal' WL_WAR_NAME = 'eapim-portal.war' WL_HTTP_PORT = '39130' WL_NOHUP = '/logs/weblogic/domains/eapimDomain/nohup.devSvr11.out' } stages { stage('Stop WebLogic') { steps { sh '"$WL_HOME/stopDev11.sh"' // 동기: 완전 종료까지 블록, 미기동 시에도 안전 } } stage('Deploy WAR') { steps { unstash 'war' sh ''' set -eu cp build/libs/eapim-portal.war "$WL_DEPLOY_DIR/$WL_WAR_NAME" ls -la "$WL_DEPLOY_DIR" ''' } } stage('Start WebLogic and readiness') { steps { sh ''' set -eu "$WL_HOME/startDev11.sh" # nohup & 로 백그라운드 기동, 즉시 리턴 DEADLINE=$(($(date +%s) + 300)) STATUS=000 while [ "$(date +%s)" -lt "$DEADLINE" ]; do STATUS=$(curl -sS -o /dev/null -w '%{http_code}' --max-time 3 \ "http://localhost:$WL_HTTP_PORT/health/ready" 2>/dev/null || echo "000") [ "$STATUS" = "200" ] && { echo "Readiness OK (/health/ready)"; break; } sleep 3 done if [ "$STATUS" != "200" ]; then echo "Readiness failed within 300s, last HTTP=$STATUS" [ -f "$WL_NOHUP" ] && tail -120 "$WL_NOHUP" exit 1 fi ''' } } } } } post { success { node('weblogic') { sh ''' set +e payload=$(printf '{"text":"[%s #%s](%s) SUCCESS"}' "$JOB_NAME" "$BUILD_NUMBER" "$BUILD_URL") curl -sS --fail --max-time 5 -H 'Content-Type: application/json' -X POST --data "$payload" "$WEBHOOK_URL" >/dev/null || echo "Webhook failed" ''' } } failure { node('weblogic') { sh ''' set +e payload=$(printf '{"text":"[%s #%s](%s) FAILURE"}' "$JOB_NAME" "$BUILD_NUMBER" "$BUILD_URL") curl -sS --fail --max-time 5 -H 'Content-Type: application/json' -X POST --data "$payload" "$WEBHOOK_URL" >/dev/null || echo "Webhook failed" ''' } } } }