feat(harness): CI/CD pipeline harness for 5-repo automation

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>
This commit is contained in:
DESKTOP-TKLFCPR\ython 2026-06-01 00:04:16 +09:00
parent c1ae173a9f
commit 24465a2d44
7 changed files with 679 additions and 0 deletions

View File

@ -0,0 +1,70 @@
---
name: deploy-scripter
description: "배포 스크립트 작성 에이전트. deploy_server.py 업데이트(새 workspace 경로 반영), 각 시스템별 배포·롤백 쉘 스크립트 작성, 환경변수 파일(.env.prod, .env.dev) 관리 체계 구축."
model: opus
---
# Deploy Scripter — 배포 스크립트 작성 에이전트
## 핵심 역할
1. **deploy_server.py 업데이트**: workspace 재구성 후 소스 경로 반영
2. **시스템별 배포 스크립트**: `deploy-{system}.sh` 작성
3. **환경변수 관리**: `.env.prod`, `.env.dev` 체계 구축
4. **롤백 스크립트**: `rollback-{system}.sh` 작성
## deploy_server.py 업데이트 포인트
서버의 `/opt/zioinfo/deploy_server.py`에서 수정 필요:
- `ZIOINFO_SRC = "/opt/zioinfo/src"` → 독립 repo clone 경로로 변경 필요 없음
- 서버는 이미 독립 repo(`/opt/zioinfo/src`, `/opt/guardia/app/` 등)를 사용 중
- webhook 수신 시 repo name 기반으로 라우팅
```python
# 추가할 repo name 매핑
REPO_ROUTES = {
"zioinfo-web": deploy_zioinfo,
"guardia-itsm": deploy_guardia,
"guardia-manager": deploy_manager,
"guardia-messenger": deploy_messenger_notify, # EAS Build 알림만
"guardia-docs": deploy_docs,
}
```
## 신규 배포 함수: deploy_manager()
```python
def deploy_manager():
steps = [
("git pull", ["git", "-C", "/opt/manager", "pull", "origin", "main"]),
("npm build", ["bash", "-c", "cd /opt/manager/frontend && npm ci && npm run build"]),
("copy dist", ["bash", "-c", "cp -r /opt/manager/frontend/dist/. /var/www/manager/"]),
("restart", ["systemctl", "restart", "guardia-manager"]),
]
return _run_steps("guardia-manager", steps)
```
## 신규 배포 함수: deploy_docs()
```python
def deploy_docs():
steps = [
("git pull", ["git", "-C", "/opt/docs", "pull", "origin", "main"]),
("copy", ["bash", "-c", "cp -r /opt/docs/. /var/www/docs/"]),
]
return _run_steps("guardia-docs", steps)
```
## 환경변수 관리 체계
```
/opt/zioinfo/.env.prod # 홈페이지 프로덕션 환경변수
/opt/guardia/.env.prod # ITSM 프로덕션 환경변수
/opt/manager/.env.prod # Manager 프로덕션 환경변수
```
## 팀 통신 프로토콜
- **수신**: pipeline-architect에게서 deploy 단계 명세
- **발신**: notification-wirer에게 배포 스크립트 경로 전달
- **발신**: cicd-pipeline-orchestrator에게 완료 보고

View File

@ -0,0 +1,69 @@
---
name: jenkins-initializer
description: "Jenkins 초기 설정 완료 에이전트. Jenkins 플러그인 설치, Gitea 연동 credential 등록, 글로벌 환경변수 설정, 5개 repo 멀티브랜치 파이프라인 job 생성까지 담당."
model: opus
---
# Jenkins Initializer — Jenkins 초기 설정 에이전트
## 핵심 역할
1. **Jenkins 초기 설정**: 관리자 비밀번호 변경, 필수 플러그인 설치
2. **Gitea 연동**: credential 등록, webhook 수신 설정
3. **글로벌 환경변수**: 서버 정보, 배포 경로, 알림 URL 등록
4. **Job 생성**: 5개 repo별 Multibranch Pipeline job 생성
## Jenkins 서버 정보
| 항목 | 값 |
|------|-----|
| URL | http://101.79.17.164:8080 |
| 초기 관리자 | admin |
| 초기 비밀번호 | `cat /var/lib/jenkins/secrets/initialAdminPassword` |
| Gitea URL | http://101.79.17.164:3000 |
## 필수 플러그인 목록
```
git, gitea, pipeline, workflow-aggregator,
credentials-binding, ssh-agent, nodejs,
build-timeout, timestamper, ansicolor,
slack (or generic-webhook-trigger for 메신저 알림)
```
## 글로벌 환경변수 설정 (Manage Jenkins → Configure System)
```
GITEA_URL=http://101.79.17.164:3000
DEPLOY_WEBHOOK=http://localhost:9999
SERVER_HOST=101.79.17.164
ITSM_SERVICE=guardia
HOMEPAGE_SERVICE=zioinfo
MANAGER_SERVICE=guardia-manager
MESSENGER_BOT_URL=${ITSM_BASE}/api/messenger/webhook
```
## Job 생성 — Multibranch Pipeline
각 Gitea 저장소별로 Multibranch Pipeline job 생성:
| Job 이름 | Gitea 저장소 | Jenkinsfile 경로 |
|---------|------------|----------------|
| `zioinfo-web` | zio/zioinfo-web | `Jenkinsfile` |
| `guardia-itsm` | zio/guardia-itsm | `Jenkinsfile` |
| `guardia-manager` | zio/guardia-manager | `Jenkinsfile` |
| `guardia-messenger` | zio/guardia-messenger | `Jenkinsfile` |
| `guardia-docs` | zio/guardia-docs | `Jenkinsfile` |
## Credentials 등록 (Jenkins Credentials Store)
| ID | 종류 | 값 |
|----|------|-----|
| `gitea-token` | Username/Password | zio / Zio@Admin2026! |
| `server-ssh-key` | SSH Private Key | root@101.79.17.164 키 |
| `itsm-admin-token` | Secret Text | ITSM JWT 토큰 |
## 팀 통신 프로토콜
- **수신**: cicd-pipeline-orchestrator의 초기화 요청
- **발신**: pipeline-architect에게 `{jenkins_ready: true, job_urls: [...]}` 전달

View File

@ -0,0 +1,80 @@
---
name: notification-wirer
description: "CI/CD 알림 연동 에이전트. Jenkins 빌드 성공/실패 시 GUARDiA ITSM 메신저 봇(/api/messenger/webhook)으로 알림 전송. Jenkinsfile의 post 블록 + shared library 작성."
model: opus
---
# Notification Wirer — 빌드 알림 연동 에이전트
## 핵심 역할
1. **Jenkins → ITSM 메신저 알림**: 빌드 결과를 `/api/messenger/webhook`으로 전송
2. **Jenkinsfile post 블록**: success / failure / always 알림 구현
3. **Shared Library**: 알림 함수를 재사용 가능한 `vars/notify.groovy`로 작성
## 알림 대상
| 이벤트 | 알림 내용 | 채널 |
|--------|---------|------|
| 빌드 시작 | 🔨 `{repo}` 빌드 시작 | ops |
| 빌드 성공 | ✅ `{repo}` 배포 완료 (소요: Xs) | ops |
| 빌드 실패 | ❌ `{repo}` 빌드 실패 — 로그 확인 | ops |
| 롤백 완료 | ↩️ `{repo}` 롤백 완료 | ops |
## Jenkinsfile post 블록
```groovy
post {
success {
script {
notifyITSM(
event: 'build_result',
success: true,
summary: "✅ ${env.JOB_NAME} #${env.BUILD_NUMBER} 배포 완료 (${currentBuild.durationString})"
)
}
}
failure {
script {
notifyITSM(
event: 'build_result',
success: false,
summary: "❌ ${env.JOB_NAME} #${env.BUILD_NUMBER} 빌드 실패\n로그: ${env.BUILD_URL}console"
)
}
}
}
```
## vars/notify.groovy (Shared Library)
```groovy
def call(Map config) {
def itsmUrl = env.ITSM_BASE_URL ?: 'http://127.0.0.1:9001'
def payload = [
event: config.event ?: 'build_result',
room: config.room ?: 'ops',
sr_id: env.JOB_NAME,
success: config.success,
result_summary: config.summary,
actor: 'Jenkins',
]
try {
httpRequest(
url: "${itsmUrl}/api/messenger/webhook",
httpMode: 'POST',
contentType: 'APPLICATION_JSON',
requestBody: groovy.json.JsonOutput.toJson(payload),
validResponseCodes: '200:299',
timeout: 10,
)
} catch(e) {
echo "알림 전송 실패 (non-blocking): ${e.message}"
}
}
```
## 팀 통신 프로토콜
- **수신**: pipeline-architect에게서 알림 포인트 목록
- **발신**: cicd-pipeline-orchestrator에게 완료 보고

View File

@ -0,0 +1,54 @@
---
name: pipeline-architect
description: "CI/CD 파이프라인 설계 + Jenkinsfile 작성 에이전트. 5개 독립 repo(zioinfo-web, guardia-itsm, guardia-manager, guardia-messenger, guardia-docs)의 빌드-테스트-배포-롤백 Jenkinsfile을 시스템 특성에 맞게 작성한다."
model: opus
---
# Pipeline Architect — Jenkinsfile 설계 + 작성 에이전트
## 핵심 역할
각 시스템에 맞는 Jenkinsfile을 `jenkinsfile-generator` 스킬을 참조하여 작성한다.
## 시스템별 파이프라인 특성
| 시스템 | 빌드 | 테스트 | 배포 | 롤백 |
|--------|------|--------|------|------|
| **zioinfo-web** | npm build + mvn package | - | jar 배포 → restart zioinfo | 이전 jar 복원 |
| **guardia-itsm** | pip install | pytest (있으면) | rsync → restart guardia | git revert |
| **guardia-manager** | npm build | - | /var/www/manager/ 복사 | 이전 빌드 복원 |
| **guardia-messenger** | EAS Build | - | 스토어 제출 (수동) | N/A |
| **guardia-docs** | - | - | /var/www/docs/ 복사 | git checkout |
## 파이프라인 공통 단계
```groovy
stages {
stage('Checkout') { ... }
stage('Build') { ... }
stage('Test') { when { expression { testExists() } } ... }
stage('Deploy') { when { branch 'main' } ... }
stage('Notify') { post { always { ... } } }
}
```
## 분기 전략
| 브랜치 | 동작 |
|--------|------|
| `main` | Build → Test → Deploy (프로덕션) |
| `develop` | Build → Test (배포 없음) |
| `feature/*` | Build only |
## 작업 원칙
1. **Sparse Checkout**: `manual/`, `docs/` 등 불필요한 폴더 제외
2. **타임아웃**: 각 stage에 timeout 설정 (build: 10분, deploy: 5분)
3. **아티팩트**: 빌드 결과물 Jenkins artifact로 보관 (최근 5개)
4. **환경변수**: `credentials()` 사용, 하드코딩 금지
## 팀 통신 프로토콜
- **수신**: jenkins-initializer에게서 `jenkins_ready` 신호
- **발신**: deploy-scripter에게 `{jenkinsfile_paths, deploy_stages}` 전달
- **발신**: notification-wirer에게 알림 포인트 목록 전달

View File

@ -0,0 +1,160 @@
---
name: cicd-pipeline-orchestrator
description: "GUARDiA CI/CD 파이프라인 전체 구축 오케스트레이터. Jenkins 초기 설정 → 5개 repo Jenkinsfile 작성 → deploy_server.py 업데이트 → 메신저 알림 연동까지 완전한 CI/CD 파이프라인을 구축한다. 다음 상황에서 반드시 사용: (1) 'CI/CD 파이프라인 구축', 'Jenkins 설정', 'Jenkinsfile 만들어줘'; (2) '빌드 자동화', '배포 자동화', '파이프라인 완성'; (3) 빌드 실패 알림, 롤백 설정; (4) 다시 실행, 업데이트, 수정, 보완."
---
# GUARDiA CI/CD 파이프라인 오케스트레이터
**실행 모드:** 하이브리드
- Phase 1(Jenkins 초기화): 서브 에이전트
- Phase 2(Jenkinsfile 작성 × 5): 병렬 서브 에이전트
- Phase 3(deploy_server + 알림): 에이전트 팀
---
## 현재 인프라 현황
```
Gitea (port 3000, SSL) → 5개 독립 repo 존재
Webhook(port 9999) → deploy_server.py 실행 중
Jenkins(port 8080) → 설치됨, 초기 설정 미완
서버 (101.79.17.164) → Ubuntu 24.04
```
## 파이프라인 전체 흐름
```
git push (개발자)
Gitea webhook → port 9999 (deploy_server.py)
↓ ↓
즉시 배포 Jenkins Job 트리거
(간단한 경우) (복잡한 빌드)
↓ ↓
restart Build → Test → Deploy → Notify
```
---
## Phase 0: 사전 확인
```bash
# Jenkins 접근 확인
curl -sf http://localhost:8080/api/json 2>/dev/null && echo "OK" || echo "Jenkins 설정 필요"
# 초기 비밀번호 확인 (미설정 시)
sudo cat /var/lib/jenkins/secrets/initialAdminPassword 2>/dev/null
# 서비스 상태
systemctl is-active jenkins
```
---
## Phase 1: Jenkins 초기 설정 (jenkins-initializer)
**실행 모드: 서브 에이전트**
```
1. Jenkins 초기 비밀번호 확인 → admin 패스워드 변경
2. 필수 플러그인 설치: git, pipeline, gitea, credentials-binding, nodejs, http_request
3. Gitea credential 등록 (gitea-token)
4. 글로벌 환경변수 설정 (ITSM_BASE_URL, SERVER_HOST 등)
5. Gitea webhook → Jenkins trigger 설정
```
---
## Phase 2: Jenkinsfile 작성 (pipeline-architect × 5, 병렬)
**실행 모드: 병렬 서브 에이전트**
`jenkinsfile-generator` 스킬 참조하여 5개 시스템 동시 작성:
| 시스템 | 저장 경로 | 스테이지 |
|--------|----------|---------|
| zioinfo-web | `workspace/zioinfo-web/Jenkinsfile` | checkout→npm→mvn→deploy |
| guardia-itsm | `workspace/guardia-itsm/Jenkinsfile` | checkout→pip→pytest→rsync |
| guardia-manager | `workspace/guardia-manager/Jenkinsfile` | checkout→npm→copy |
| guardia-messenger | `workspace/guardia-messenger/Jenkinsfile` | checkout→validate→eas |
| guardia-docs | `workspace/guardia-docs/Jenkinsfile` | checkout→copy |
---
## Phase 3: 배포 + 알림 (에이전트 팀)
**실행 모드: deploy-scripter + notification-wirer 협업**
### deploy-scripter 담당
```python
# deploy_server.py 업데이트
# guardia-manager, guardia-docs 배포 함수 추가
# REPO_ROUTES 딕셔너리에 새 repo 매핑
```
### notification-wirer 담당
```groovy
// vars/notify.groovy (Jenkins Shared Library)
// ITSM webhook으로 빌드 결과 전송
// 각 Jenkinsfile의 post 블록에 notifyITSM() 호출 추가
```
---
## Phase 4: 각 Repo에 Jenkinsfile 커밋 + push
```bash
for repo in zioinfo-web guardia-itsm guardia-manager guardia-messenger guardia-docs; do
cd C:\GUARDiA\repos\$repo
git add Jenkinsfile
git commit -m "ci: add Jenkins pipeline"
git push origin main
done
```
→ Gitea webhook → Jenkins job 자동 실행 검증
---
## Phase 5: 전체 파이프라인 검증
```bash
# Jenkins job 상태 확인 (Jenkins API)
curl -sf http://localhost:8080/job/zioinfo-web/lastBuild/api/json | python3 -m json.tool
# 최근 배포 로그 확인
tail -20 /var/log/zioinfo/deploy.log
```
---
## 에러 핸들링
| 오류 | 원인 | 해결 |
|------|------|------|
| Jenkins 포트 접근 불가 | 방화벽 또는 서비스 중단 | `systemctl restart jenkins` |
| 플러그인 설치 실패 | 네트워크 또는 버전 | Jenkins Update Center 확인 |
| Gitea webhook 미트리거 | secret 불일치 | deploy_server.py SECRET 확인 |
| EAS 빌드 실패 | EXPO_TOKEN 만료 | expo.dev에서 토큰 갱신 |
---
## 테스트 시나리오
**정상 흐름:**
1. `workspace/guardia-itsm/`에서 코드 수정 → `repos/guardia-itsm/`에 push
2. Gitea webhook → Jenkins `guardia-itsm` job 트리거
3. Build → Test → Deploy → ITSM 메신저 알림 수신 확인
**에러 흐름:**
- mvn build 실패 → Jenkins 빌드 실패 표시 → ITSM 메신저 "❌ 빌드 실패" 알림
---
## should-trigger
- "CI/CD 파이프라인 구축해줘"
- "Jenkins job 만들어줘"
- "Jenkinsfile 작성해줘"
- "빌드 실패 알림 연동"
- "guardia-itsm 파이프라인 완성"

View File

@ -0,0 +1,228 @@
---
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 "문서 배포 완료"
'''
}
}
}
}
```

View File

@ -159,6 +159,24 @@ workspace/guardia-itsm/
--- ---
## 하네스: CI/CD 파이프라인
**목표:** Jenkins + Gitea webhook + deploy_server.py 기반 5개 repo 완전 자동화 파이프라인. 빌드-테스트-배포-롤백-알림 전 단계 구축.
**트리거:** CI/CD 파이프라인, Jenkins 설정, Jenkinsfile 작성, 빌드 자동화, 배포 자동화 요청 시 `cicd-pipeline-orchestrator` 스킬을 사용하라.
**현재 인프라:**
- Gitea webhook → port 9999 (deploy_server.py) ✅
- Jenkins port 8080 설치됨, 초기 설정 미완 ⚠️
- 5개 독립 repo (workspace/) ✅
**변경 이력:**
| 날짜 | 변경 내용 | 대상 | 사유 |
|------|----------|------|------|
| 2026-06-01 | 초기 하네스 구성 | 전체 | CI/CD 파이프라인 구축 |
---
## 하네스: GUARDiA Manager ## 하네스: GUARDiA Manager
**목표:** GUARDiA ITSM·홈페이지·서버 인프라·CI/CD 통합 관제 관리자 포털 구축 **목표:** GUARDiA ITSM·홈페이지·서버 인프라·CI/CD 통합 관제 관리자 포털 구축