pipeline { agent any options { disableConcurrentBuilds() } environment { DEPLOY_USER = 'hskwon' RELEASE_ID = new Date().format('yyyyMMdd_HHmmss') } stages { stage('Checkout') { steps { checkout scm script { env.GIT_COMMIT_MSG = sh(script: "git log -1 --pretty=format:'%s'", returnStdout: true).trim() } slackSend channel: '#product_infra', color: '#439FE0', tokenCredentialId: 'slack-token', message: "πŸš€ *api* λΉŒλ“œ μ‹œμž‘ (`${env.BRANCH_NAME}`)\n${env.GIT_COMMIT_MSG}\n<${env.BUILD_URL}|λΉŒλ“œ #${env.BUILD_NUMBER}>" } } // ── main β†’ μš΄μ˜μ„œλ²„ Stage 배포 ── stage('Deploy Stage') { when { branch 'main' } steps { sshagent(credentials: ['deploy-ssh-key']) { sh """ ssh ${DEPLOY_USER}@211.117.60.189 'mkdir -p /home/webservice/api-stage/releases/${RELEASE_ID}' rsync -az --delete \ --exclude='.git' --exclude='.env' \ --exclude='storage/app' --exclude='storage/logs' \ --exclude='storage/framework/sessions' --exclude='storage/framework/cache' \ . ${DEPLOY_USER}@211.117.60.189:/home/webservice/api-stage/releases/${RELEASE_ID}/ ssh ${DEPLOY_USER}@211.117.60.189 ' cd /home/webservice/api-stage/releases/${RELEASE_ID} && mkdir -p bootstrap/cache storage/framework/{views,cache/data,sessions} storage/logs && sudo chown -R www-data:webservice storage bootstrap/cache && sudo chmod -R 775 storage bootstrap/cache && ln -sfn /home/webservice/api-stage/shared/.env .env && sudo chmod 640 /home/webservice/api-stage/shared/.env && ln -sfn /home/webservice/api-stage/shared/storage/app storage/app && composer install --no-dev --optimize-autoloader --no-interaction && php artisan config:cache && php artisan route:cache && php artisan view:cache && php artisan migrate --force && ln -sfn /home/webservice/api-stage/releases/${RELEASE_ID} /home/webservice/api-stage/current && sudo systemctl reload php8.4-fpm && cd /home/webservice/api-stage/releases && ls -1dt */ | tail -n +4 | xargs rm -rf 2>/dev/null || true ' """ } } } // ── 운영 배포 승인 (런칭 ν›„ ν™œμ„±ν™”) ── // stage('Production Approval') { // when { branch 'main' } // steps { // slackSend channel: '#product_deploy', color: '#FF9800', tokenCredentialId: 'slack-token', // message: "πŸ”” *api* 운영 배포 승인 λŒ€κΈ° 쀑\n${env.GIT_COMMIT_MSG}\nStage API: https://stage-api.sam.it.kr\n<${env.BUILD_URL}input|μŠΉμΈν•˜λŸ¬ κ°€κΈ°>" // timeout(time: 24, unit: 'HOURS') { // input message: 'Stage 확인 ν›„ 운영 배포λ₯Ό μ§„ν–‰ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?\nStage API: https://stage-api.sam.it.kr', // ok: '운영 배포 μ§„ν–‰' // } // } // } // ── main β†’ μš΄μ˜μ„œλ²„ Production 배포 ── stage('Deploy Production') { when { branch 'main' } steps { sshagent(credentials: ['deploy-ssh-key']) { sh """ ssh ${DEPLOY_USER}@211.117.60.189 'mkdir -p /home/webservice/api/releases/${RELEASE_ID}' rsync -az --delete \ --exclude='.git' --exclude='.env' \ --exclude='storage/app' --exclude='storage/logs' \ --exclude='storage/framework/sessions' --exclude='storage/framework/cache' \ . ${DEPLOY_USER}@211.117.60.189:/home/webservice/api/releases/${RELEASE_ID}/ ssh ${DEPLOY_USER}@211.117.60.189 ' cd /home/webservice/api/releases/${RELEASE_ID} && mkdir -p bootstrap/cache storage/framework/{views,cache/data,sessions} storage/logs && sudo chown -R www-data:webservice storage bootstrap/cache && sudo chmod -R 775 storage bootstrap/cache && ln -sfn /home/webservice/api/shared/.env .env && sudo chmod 640 /home/webservice/api/shared/.env && ln -sfn /home/webservice/api/shared/storage/app storage/app && composer install --no-dev --optimize-autoloader --no-interaction && php artisan config:cache && php artisan route:cache && php artisan view:cache && php artisan migrate --force && ln -sfn /home/webservice/api/releases/${RELEASE_ID} /home/webservice/api/current && sudo systemctl reload php8.4-fpm && sudo supervisorctl restart sam-queue-worker:* && cd /home/webservice/api/releases && ls -1dt */ | tail -n +6 | xargs rm -rf 2>/dev/null || true ' """ } } } // develop β†’ Jenkins κ΄€μ—¬ μ•ˆν•¨ (κΈ°μ‘΄ post-update hook μœ μ§€) } post { success { slackSend channel: '#product_infra', color: 'good', tokenCredentialId: 'slack-token', message: "βœ… *api* 배포 성곡 (`${env.BRANCH_NAME}`)\n${env.GIT_COMMIT_MSG}\n<${env.BUILD_URL}|λΉŒλ“œ #${env.BUILD_NUMBER}>" } failure { slackSend channel: '#product_infra', color: 'danger', tokenCredentialId: 'slack-token', message: "❌ *api* 배포 μ‹€νŒ¨ (`${env.BRANCH_NAME}`)\n${env.GIT_COMMIT_MSG}\n<${env.BUILD_URL}|λΉŒλ“œ #${env.BUILD_NUMBER}>" script { if (env.BRANCH_NAME == 'main') { sshagent(credentials: ['deploy-ssh-key']) { sh """ ssh ${DEPLOY_USER}@211.117.60.189 ' PREV=\$(ls -1dt /home/webservice/api/releases/*/ | sed -n "2p" | xargs basename 2>/dev/null) && [ -n "\$PREV" ] && ln -sfn /home/webservice/api/releases/\$PREV /home/webservice/api/current && sudo systemctl reload php8.4-fpm ' || true """ } } } } } }