G-1: 메신저 Webhook Relay + _send_to_room 실제 httpx 호출 구현 G-2: POST /api/tasks/bulk SR 대량작업 엔드포인트 (최대 100건) G-3: 라이선스 만료 알림 스케줄러 (매일 09:00 KST) G-4: 체험판 upgrade_banner 필드 + license.py 배너 로직 G-5: core/auto_rca.py + incidents/problem auto-rca 엔드포인트 G-6: core/deploy_impact.py + vibe impact-analysis 엔드포인트 G-7: core/ticket_classifier.py + SR 생성 시 AI 분류 + ai-suggestion API G-8: VulnPatchRecord 모델 + vuln_scan 패치추적 4개 엔드포인트 G-9: core/jira_sync.py + gateway Jira/Confluence 연동 엔드포인트 G-10: core/push_notify.py + routers/push.py + PushSubscription 모델 G-11: approvals 다중승인 (위임/서명/기한초과/마감연장) G-12: alembic.ini + migrations/ + cicd/migrate_to_postgres.sh 하네스: guardia-orchestrator 확장기능 Phase 반영 봇명령어: /sr /status /license /bulk 슬래시 명령어 추가 설치스크립트: setup/ (Ubuntu, CentOS, RHEL, Windows) --test 옵션 포함 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
10 KiB
10 KiB
파이프라인 설계 표준
버전: 1.0.0
최종 수정: 2026-05-25
1. 개요
GUARDiA ITSM의 모든 CI/CD 파이프라인은 아래 8단계를 표준으로 한다.
각 단계는 독립 스크립트로 분리되어 있으며, 실패 시 즉시 중단하고 ITSM에 결과를 통보한다.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Stage 1 │───▶│ Stage 2 │───▶│ Stage 3 │───▶│ Stage 4 │
│ Checkout │ │ Build │ │ Test │ │ Archive │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
│
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Stage 8 │◀───│ Stage 7 │◀───│ Stage 6 │◀───│ Stage 5 │
│ ITSM │ │ Health Check│ │ WAS Restart │ │ Deploy │
│ Callback │ │ │ │ │ │ │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
2. 파이프라인 파라미터 표준
모든 파이프라인은 다음 파라미터를 공통으로 사용한다:
| 파라미터 | 타입 | 기본값 | 설명 |
|---|---|---|---|
ITSM_SESSION_ID |
String | — | GUARDiA 바이브 세션 ID |
ITSM_SR_ID |
String | — | 연결된 SR ID |
DEPLOY_ENV |
Choice | dev |
배포 환경 (dev/stg/prd) |
TARGET_SERVER |
String | — | 배포 대상 서버명 |
SKIP_TEST |
Boolean | false |
테스트 건너뜀 |
ROLLBACK_VERSION |
String | — | 롤백 버전 (빌드 번호) |
3. 환경별 파이프라인 정책
| 브랜치 | 환경 | 필수 단계 | 승인 게이트 | SonarQube |
|---|---|---|---|---|
feature/* |
dev | Build + Test | 불필요 | 선택 |
develop |
dev/stg | Build + Test + Deploy | 불필요 | 선택 |
release/* |
stg | Full Pipeline | 불필요 | 필수 |
main |
prd | Full Pipeline | 필수 | 필수 |
hotfix/* |
prd | Full Pipeline (Fast) | 필수 | 선택 |
4. 단계별 표준 정의
Stage 1: Checkout
stage('Checkout') {
steps {
checkout([
$class: 'GitSCM',
branches: [[name: env.BRANCH_NAME ?: 'main']],
extensions: [
[$class: 'CleanBeforeCheckout'],
[$class: 'CloneOption', depth: 1, shallow: true]
],
userRemoteConfigs: [[
url: env.GIT_REPO_URL,
credentialsId: 'git-credentials'
]]
])
}
}
Stage 2: Build
stage('Build') {
steps {
script {
sh "bash ${WORKSPACE}/cicd/scripts/pipeline/build.sh"
}
}
post {
failure {
sh "bash ${WORKSPACE}/cicd/scripts/notify/itsm_callback.sh FAILED '빌드 실패'"
}
}
}
빌드 산출물 위치:
- Java Maven:
target/*.jar,target/*.war - Java Gradle:
build/libs/*.jar,build/libs/*.war - Node.js:
dist/,build/
Stage 3: Test
stage('Test') {
when {
expression { params.SKIP_TEST == false }
}
parallel {
stage('Unit Test') {
steps {
sh "bash ${WORKSPACE}/cicd/scripts/pipeline/test.sh unit"
}
}
stage('SonarQube') {
when {
anyOf {
branch 'release/*'
branch 'main'
}
}
steps {
withSonarQubeEnv('sonarqube') {
sh "bash ${WORKSPACE}/cicd/scripts/pipeline/test.sh sonar"
}
timeout(time: 10, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
}
Stage 4: Archive
stage('Archive') {
steps {
archiveArtifacts artifacts: '**/target/*.jar,**/target/*.war,**/build/libs/*.jar',
fingerprint: true,
allowEmptyArchive: false
}
}
Stage 5: Deploy
stage('Deploy') {
steps {
withCredentials([sshUserPrivateKey(
credentialsId: "ssh-${params.TARGET_SERVER}",
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
sh """
bash \${WORKSPACE}/cicd/scripts/pipeline/deploy.sh \
--server \${params.TARGET_SERVER} \
--env \${params.DEPLOY_ENV}
"""
}
}
}
Stage 6: WAS Restart
stage('WAS Restart') {
steps {
withCredentials([sshUserPrivateKey(
credentialsId: "ssh-${params.TARGET_SERVER}",
keyFileVariable: 'SSH_KEY',
usernameVariable: 'SSH_USER'
)]) {
sh """
bash \${WORKSPACE}/cicd/scripts/pipeline/was_restart.sh \
--server \${params.TARGET_SERVER} \
--was-type \${env.WAS_TYPE ?: 'tomcat'}
"""
}
}
post {
failure {
sh "bash ${WORKSPACE}/cicd/scripts/pipeline/rollback.sh --reason 'WAS 재기동 실패'"
}
}
}
Stage 7: Health Check
stage('Health Check') {
steps {
retry(3) {
sh """
bash \${WORKSPACE}/cicd/scripts/pipeline/health_check.sh \
--url \${env.HEALTH_CHECK_URL} \
--timeout 60
"""
}
}
post {
failure {
sh "bash ${WORKSPACE}/cicd/scripts/pipeline/rollback.sh --reason '헬스체크 실패'"
}
}
}
Stage 8: ITSM Callback
stage('ITSM Callback') {
steps {
sh """
bash \${WORKSPACE}/cicd/scripts/notify/itsm_callback.sh \
SUCCESS \
"배포 완료 (빌드 #\${env.BUILD_NUMBER})"
"""
}
post {
failure {
echo 'ITSM 콜백 실패 — 수동 확인 필요'
}
}
}
5. 공통 post 블록
모든 파이프라인에 반드시 포함해야 하는 공통 후처리:
post {
always {
// 워크스페이스 정리
cleanWs(
cleanWhenAborted: true,
cleanWhenFailure: true,
cleanWhenSuccess: true
)
}
success {
echo "파이프라인 성공: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
}
failure {
sh """
bash \${WORKSPACE}/cicd/scripts/notify/itsm_callback.sh \
FAILED "파이프라인 실패: \${env.STAGE_NAME}"
"""
}
unstable {
sh """
bash \${WORKSPACE}/cicd/scripts/notify/itsm_callback.sh \
UNSTABLE "테스트 불안정: \${env.STAGE_NAME}"
"""
}
}
6. 승인 게이트 (운영 배포)
main, hotfix/* 브랜치의 운영 배포 시 승인 게이트를 거친다.
stage('Production Approval') {
when {
anyOf {
branch 'main'
branch 'hotfix/*'
}
}
steps {
script {
// ITSM에 승인 요청 발송
sh "bash ${WORKSPACE}/cicd/scripts/notify/itsm_callback.sh PENDING_APPROVAL '운영 배포 승인 요청'"
// 승인 대기 (30분 타임아웃)
timeout(time: 30, unit: 'MINUTES') {
input message: "운영 배포를 승인하시겠습니까?",
ok: "배포 승인",
submitterParameter: "APPROVER"
}
}
}
}
7. 롤백 정책
| 단계 | 자동 롤백 | 조건 |
|---|---|---|
| WAS Restart | ✓ | WAS 기동 후 60초 내 응답 없음 |
| Health Check | ✓ | HTTP 상태코드 != 200 (3회 재시도 후) |
| 수동 롤백 | — | !rollback 봇 명령 또는 Jenkins 수동 트리거 |
롤백 파이프라인 파라미터:
ROLLBACK_VERSION: 이전 빌드 번호 (빌드 번호 = 아티팩트 버전)ROLLBACK_REASON: 롤백 사유 (ITSM 등록용)
8. 파이프라인 타임아웃 표준
| 단계 | 타임아웃 | 비고 |
|---|---|---|
| Checkout | 5분 | |
| Build | 30분 | 대형 프로젝트 60분 허용 |
| Test | 20분 | 단위 테스트 기준 |
| SonarQube | 10분 | Quality Gate 대기 포함 |
| Archive | 5분 | |
| Deploy | 10분 | rsync/SCP 전송 |
| WAS Restart | 5분 | |
| Health Check | 5분 | 3회 재시도 포함 |
| 전체 파이프라인 | 90분 | 초과 시 강제 중단 |
options {
timeout(time: 90, unit: 'MINUTES')
buildDiscarder(logRotator(numToKeepStr: '30'))
disableConcurrentBuilds()
}
9. 환경변수 표준
파이프라인에서 사용하는 환경변수는 Jenkins → Manage Jenkins → System → Global properties 에 등록한다.
| 변수명 | 용도 | 예시 |
|---|---|---|
ITSM_URL |
GUARDiA ITSM API URL | http://itsm.agency.go.kr:8000 |
ITSM_CALLBACK_URL |
파이프라인 결과 콜백 URL | ${ITSM_URL}/api/vibe/callback |
SONAR_HOST_URL |
SonarQube 서버 URL | http://sonar.agency.go.kr:9000 |
ARTIFACT_REPO |
아티팩트 저장소 | /opt/artifacts |
SCRIPTS_ROOT |
파이프라인 스크립트 루트 | /var/lib/jenkins/scripts |
10. 빌드 번호 & 아티팩트 버전
environment {
// 아티팩트 버전 = 브랜치명 + 빌드번호 + 커밋 해시 앞 8자리
APP_VERSION = "${env.BRANCH_NAME}-${env.BUILD_NUMBER}-${env.GIT_COMMIT[0..7]}"
// 배포 대상 파일명
ARTIFACT_NAME = "${env.JOB_NAME}-${APP_VERSION}.jar"
}