Agents (4): - jenkins-initializer: Jenkins 초기 설정, 플러그인, credentials, job 생성 - pipeline-architect: 5개 시스템별 Jenkinsfile 설계 + 작성 - deploy-scripter: deploy_server.py 업데이트, 배포/롤백 스크립트 - notification-wirer: ITSM 메신저 알림 연동 (빌드 성공/실패) Skills (2): - cicd-pipeline-orchestrator: Jenkins→Jenkinsfile→deploy→알림 전체 파이프라인 - jenkinsfile-generator: 5개 시스템 Jenkinsfile 패턴 (zioinfo-web/itsm/manager/messenger/docs) CLAUDE.md: CI/CD 하네스 포인터 등록 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
229 lines
6.2 KiB
Markdown
229 lines
6.2 KiB
Markdown
---
|
|
name: jenkinsfile-generator
|
|
description: "GUARDiA 5개 시스템(zioinfo-web, guardia-itsm, guardia-manager, guardia-messenger, guardia-docs)의 Jenkinsfile을 작성하는 스킬. 각 시스템의 빌드/테스트/배포/롤백 단계를 Groovy Pipeline DSL로 구현. 다음 상황에서 반드시 사용: (1) 'Jenkinsfile 작성', '파이프라인 작성'; (2) 특정 시스템 CI/CD 파이프라인 설계; (3) 빌드/배포 단계 추가·수정; (4) 다시 실행, 업데이트, 보완."
|
|
---
|
|
|
|
# GUARDiA Jenkinsfile 작성 스킬
|
|
|
|
## 공통 파이프라인 구조
|
|
|
|
```groovy
|
|
pipeline {
|
|
agent any
|
|
options {
|
|
buildDiscarder(logRotator(numToKeepStr: '5'))
|
|
timeout(time: 20, unit: 'MINUTES')
|
|
timestamps()
|
|
}
|
|
environment {
|
|
ITSM_BASE_URL = 'http://127.0.0.1:9001'
|
|
DEPLOY_LOG = '/var/log/zioinfo/deploy.log'
|
|
}
|
|
stages { ... }
|
|
post {
|
|
success { script { notifyITSM(success: true) } }
|
|
failure { script { notifyITSM(success: false) } }
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## zioinfo-web Jenkinsfile
|
|
|
|
```groovy
|
|
pipeline {
|
|
agent any
|
|
environment {
|
|
SRC_DIR = '/opt/zioinfo/src'
|
|
JAR_DIR = '/opt/zioinfo/app'
|
|
STATIC_DIR = '/var/www/zioinfo'
|
|
MVN = '/usr/bin/mvn'
|
|
}
|
|
options {
|
|
buildDiscarder(logRotator(numToKeepStr: '5'))
|
|
timeout(time: 20, unit: 'MINUTES')
|
|
}
|
|
stages {
|
|
stage('Checkout') {
|
|
steps {
|
|
checkout([
|
|
$class: 'GitSCM', branches: scm.branches,
|
|
userRemoteConfigs: scm.userRemoteConfigs,
|
|
extensions: [[$class: 'SparseCheckoutPaths',
|
|
sparseCheckoutPaths: [[path: 'frontend'], [path: 'backend']]
|
|
]]
|
|
])
|
|
}
|
|
}
|
|
stage('Frontend Build') {
|
|
steps {
|
|
dir('frontend') {
|
|
sh 'npm ci --legacy-peer-deps --prefer-offline 2>/dev/null || npm install --legacy-peer-deps'
|
|
sh 'npm run build'
|
|
}
|
|
}
|
|
}
|
|
stage('Backend Build') {
|
|
steps {
|
|
dir('backend') {
|
|
sh "${MVN} clean package -DskipTests -q"
|
|
}
|
|
}
|
|
}
|
|
stage('Deploy') {
|
|
when { branch 'main' }
|
|
steps {
|
|
sh '''
|
|
cp backend/target/*.jar ${JAR_DIR}/app.jar
|
|
cp -r backend/src/main/resources/static/. ${STATIC_DIR}/
|
|
systemctl restart zioinfo
|
|
sleep 4
|
|
systemctl is-active zioinfo || exit 1
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
post {
|
|
success { echo "✅ zioinfo-web 배포 완료" }
|
|
failure { echo "❌ zioinfo-web 빌드 실패" }
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## guardia-itsm Jenkinsfile
|
|
|
|
```groovy
|
|
pipeline {
|
|
agent any
|
|
environment {
|
|
APP_DIR = '/opt/guardia/app'
|
|
VENV = '/opt/guardia/venv'
|
|
SERVICE = 'guardia'
|
|
}
|
|
options { buildDiscarder(logRotator(numToKeepStr: '5')); timeout(time: 15, unit: 'MINUTES') }
|
|
stages {
|
|
stage('Checkout') { steps { checkout scm } }
|
|
stage('Install') {
|
|
steps {
|
|
sh "${VENV}/bin/pip install -r requirements.txt -q"
|
|
}
|
|
}
|
|
stage('Test') {
|
|
when { expression { fileExists('tests/') } }
|
|
steps {
|
|
sh "${VENV}/bin/pytest tests/ -q --tb=short || true"
|
|
}
|
|
}
|
|
stage('Deploy') {
|
|
when { branch 'main' }
|
|
steps {
|
|
sh '''
|
|
rsync -a --exclude=__pycache__ --exclude=.git \
|
|
--exclude=rpa_rules.json \
|
|
. ${APP_DIR}/
|
|
systemctl restart ${SERVICE}
|
|
sleep 4
|
|
systemctl is-active ${SERVICE} || exit 1
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## guardia-manager Jenkinsfile
|
|
|
|
```groovy
|
|
pipeline {
|
|
agent any
|
|
environment {
|
|
SRC_DIR = '/opt/manager'
|
|
STATIC_DIR = '/var/www/manager'
|
|
SERVICE = 'guardia-manager'
|
|
}
|
|
options { buildDiscarder(logRotator(numToKeepStr: '5')); timeout(time: 15, unit: 'MINUTES') }
|
|
stages {
|
|
stage('Checkout') { steps { checkout scm } }
|
|
stage('Frontend Build') {
|
|
steps {
|
|
dir('frontend') {
|
|
sh 'npm ci 2>/dev/null || npm install'
|
|
sh 'npm run build'
|
|
}
|
|
}
|
|
}
|
|
stage('Deploy') {
|
|
when { branch 'main' }
|
|
steps {
|
|
sh '''
|
|
cp -r frontend/dist/. ${STATIC_DIR}/
|
|
systemctl restart ${SERVICE} 2>/dev/null || true
|
|
echo "Manager 배포 완료"
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## guardia-messenger Jenkinsfile
|
|
|
|
```groovy
|
|
pipeline {
|
|
agent any
|
|
options { buildDiscarder(logRotator(numToKeepStr: '3')); timeout(time: 30, unit: 'MINUTES') }
|
|
stages {
|
|
stage('Checkout') { steps { checkout scm } }
|
|
stage('Validate') {
|
|
steps {
|
|
sh 'node --version && npm --version'
|
|
sh 'npx eas --version 2>/dev/null || npm install -g eas-cli -q'
|
|
}
|
|
}
|
|
stage('EAS Build') {
|
|
when { branch 'main' }
|
|
steps {
|
|
withCredentials([string(credentialsId: 'expo-token', variable: 'EXPO_TOKEN')]) {
|
|
sh 'eas build --platform android --profile preview --non-interactive 2>&1 | tail -5'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
post {
|
|
success { echo "📱 Messenger 빌드 완료 — expo.dev에서 확인하세요" }
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## guardia-docs Jenkinsfile
|
|
|
|
```groovy
|
|
pipeline {
|
|
agent any
|
|
environment { DOCS_DIR = '/var/www/docs' }
|
|
options { buildDiscarder(logRotator(numToKeepStr: '3')) }
|
|
stages {
|
|
stage('Checkout') { steps { checkout scm } }
|
|
stage('Deploy') {
|
|
when { branch 'main' }
|
|
steps {
|
|
sh '''
|
|
mkdir -p ${DOCS_DIR}
|
|
cp -r . ${DOCS_DIR}/
|
|
echo "문서 배포 완료"
|
|
'''
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|