# 파이프라인 설계 표준 > **버전**: 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 ```groovy 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 ```groovy 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 ```groovy 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 ```groovy stage('Archive') { steps { archiveArtifacts artifacts: '**/target/*.jar,**/target/*.war,**/build/libs/*.jar', fingerprint: true, allowEmptyArchive: false } } ``` ### Stage 5: Deploy ```groovy 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 ```groovy 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 ```groovy 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 ```groovy stage('ITSM Callback') { steps { sh """ bash \${WORKSPACE}/cicd/scripts/notify/itsm_callback.sh \ SUCCESS \ "배포 완료 (빌드 #\${env.BUILD_NUMBER})" """ } post { failure { echo 'ITSM 콜백 실패 — 수동 확인 필요' } } } ``` --- ## 5. 공통 post 블록 모든 파이프라인에 반드시 포함해야 하는 공통 후처리: ```groovy 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/*` 브랜치의 운영 배포 시 승인 게이트를 거친다. ```groovy 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분 | 초과 시 강제 중단 | ```groovy 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. 빌드 번호 & 아티팩트 버전 ```groovy environment { // 아티팩트 버전 = 브랜치명 + 빌드번호 + 커밋 해시 앞 8자리 APP_VERSION = "${env.BRANCH_NAME}-${env.BUILD_NUMBER}-${env.GIT_COMMIT[0..7]}" // 배포 대상 파일명 ARTIFACT_NAME = "${env.JOB_NAME}-${APP_VERSION}.jar" } ```