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:
parent
c1ae173a9f
commit
24465a2d44
70
.claude/agents/deploy-scripter.md
Normal file
70
.claude/agents/deploy-scripter.md
Normal 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에게 완료 보고
|
||||||
69
.claude/agents/jenkins-initializer.md
Normal file
69
.claude/agents/jenkins-initializer.md
Normal 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: [...]}` 전달
|
||||||
80
.claude/agents/notification-wirer.md
Normal file
80
.claude/agents/notification-wirer.md
Normal 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에게 완료 보고
|
||||||
54
.claude/agents/pipeline-architect.md
Normal file
54
.claude/agents/pipeline-architect.md
Normal 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에게 알림 포인트 목록 전달
|
||||||
160
.claude/skills/cicd-pipeline-orchestrator/SKILL.md
Normal file
160
.claude/skills/cicd-pipeline-orchestrator/SKILL.md
Normal 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 파이프라인 완성"
|
||||||
228
.claude/skills/jenkinsfile-generator/SKILL.md
Normal file
228
.claude/skills/jenkinsfile-generator/SKILL.md
Normal 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 "문서 배포 완료"
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
18
CLAUDE.md
18
CLAUDE.md
@ -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 통합 관제 관리자 포털 구축
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user