Files
service-catalog/.claude/skills/catalog-update-pipeline/SKILL.md
T
wbsong111 bfb9419040 차트 버전 갱신 정책을 정정한다 — 트리거는 앱 버전 필요, CHART_DIRS는 교체
catalog/image-map/README.md는 "이미지 하나가 여러 버전 디렉토리에 걸리는 것이
정상"이라 서술했지만, 실측하니 근거가 반대였다. 다버전 동시 매핑은 카탈로그
전체에서 cnpg-postgresql 하나뿐이었고, 그 cnpg-cluster 1.0.0/1.1.0도 "병행 유지"
근거가 없이 같은 태그를 쓰고 있었다 — 매핑 갱신 시 옛 버전을 안 지운 결과에
가까웠다. 반대로 argocd.env는 이미 argo-cd/10.4.0 하나만 가리키고 7.8.11은
빠져 있는데, 이건 사고가 아니라 의도적 정책이었다(MEMORY.md: "직전 버전을
없애는 결정이라 PR #28에서 보류했다" — 동결 자체는 이미 관행이었다).

정정한 정책: CHART_DIRS는 기본적으로 최신 버전 하나만 가리키고, 차트를
올리면 이 값을 교체한다(추가 아님) — 옛 버전은 그 시점 태그로 동결된다.
그리고 차트를 올리는 트리거 자체도 "업스트림에 새 차트가 있다"가 아니라
"지금 쓰는 앱 버전을 유지 못 하는 구체적 이유"(CVE·EOL·필수 기능·호환성)여야
한다 — catalog-update-pipeline SKILL.md에 이 기준이 없었어서 추가했다.

keycloak.env(7.2.2→7.3.0)·cnpg-postgresql.env(1.0.0 제거)를 새 정책에 맞춰
바로잡는다 — keycloakx 7.3.0 업그레이드(#51) 때 빠뜨렸던 매핑 갱신이기도 하다.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-26 13:42:22 +09:00

91 lines
4.9 KiB
Markdown

---
name: catalog-update-pipeline
description: Helm 차트 신규 버전 감지 → diff → breaking change 판정 → 업그레이드 문서 생성 파이프라인(agent/update_catalog)을 실행할 때 사용한다. "차트 새 버전 확인해줘", "업그레이드 문서 생성", "run_flow.sh 돌려줘", "helm diff 내줘", "breaking change 확인" 같은 요청이 해당한다. 개별 Skill(chart_version_detector, helm_diff, breaking_change_check 등) 단독 실행에도 적용된다.
---
# 카탈로그 업데이트 파이프라인 실행
`agent/update_catalog/`의 결정론적 Python Skill 7개를 `run_flow.sh`가 순서대로 체이닝한다.
각 Skill은 stdout으로 JSON을 내고 다음 Skill의 입력이 된다.
```
chart_version_detector → chart_updater → helm_diff → breaking_change_check
→ generate_upgrade_doc → update_docs_file → create_pr
```
## 언제 실행하나 — 트리거는 "새 차트"가 아니라 "앱 버전을 못 지키는 이유"
`chart_version_detector`가 "업스트림에 새 버전이 있다"고 알려주는 건 **버전을 올릴지
말지의 판단 근거가 아니다** — 올리기로 이미 정해진 뒤 diff·breaking 판정을 자동화하는
도구일 뿐이다.
차트 버전을 올리는 진짜 트리거는 **지금 쓰는 앱 버전을 유지할 수 없는 구체적 이유**다:
보안 패치·CVE 대응, 소비 앱이 요구하는 신규 기능, 벤더 EOL, 클러스터·생태계 호환성
(예: argo-cd가 k8s 1.35를 지원 못 해 업그레이드로 이어진 PR #28 사례). **이유가 없으면
업스트림에 새 차트가 나와 있어도 기존 버전을 그대로 쓴다** — "최신 추종" 자체는
목표가 아니다.
**이미지가 자체 빌드(`docker.io/paasup/*`)로 고정된 차트는 특히 주의한다.**
`custom-values.yaml`이 이미지 태그를 명시 고정하므로 차트의 `appVersion`이 올라가도
실제 배포 버전은 안 바뀐다 — 이 경우 트리거는 `appVersion`이 아니라 **그 자체 빌드
이미지**가 CVE 게이트를 못 넘기거나 EOL이 되는 시점이다(keycloakx 7.3.0 사례: 차트
`appVersion`은 26.7.2로 올랐지만 실제 배포는 여전히 자체 빌드 26.7.1).
트리거가 있어 실제로 버전을 올리면, `catalog/image-map/<image>.env``CHART_DIRS`
새 버전으로 **옮긴다**(추가 아님) — 옛 버전은 그 시점 태그로 동결된다. 상세 규칙은
[catalog/image-map/README.md](../../../catalog/image-map/README.md).
## 실행 전 반드시 확인할 것
**`CATALOG_ROOT`를 오버라이드하지 않으면 엉뚱한 경로를 본다.** 기본값이
`/Users/songwonbin/openclaw-workspace/dip-catalog`로 하드코딩돼 있다(개인 로컬 경로).
```sh
CATALOG_ROOT=/path/to/dip-catalog CHART=airflow \
bash agent/update_catalog/scripts/run_flow.sh
```
| 환경변수 | 의미 | 기본값 |
|---|---|---|
| `CATALOG_ROOT` | dip-catalog 절대 경로 | **하드코딩된 개인 경로 — 반드시 오버라이드** |
| `CHART` | 대상 차트명 | `airflow` |
| `OUT_DIR` | 중간 JSON 산출물 | `$(pwd)/update_catalog` (차트별 하위 디렉토리로 격리) |
| `DEFAULT_BRANCH` | 분기 기준 브랜치 | `main` |
| `USE_CLAUDE_CLI=1` | `breaking=true` 시 LLM 상세 가이드 생성 | 미설정 시 템플릿 기반 |
## 알려진 미완 상태
**`create_pr`(6단계)은 `run_flow.sh`에서 통째로 주석 처리돼 있다** — 파이프라인이 끝까지
돌아도 **브랜치·커밋·PR이 생성되지 않는다.** 문서 생성까지가 실제 동작 범위다.
PR이 필요하면 결과물을 보고 직접 만들거나, 주석을 해제하기 전에 `create_pr` Skill의
동작을 먼저 검증한다(CLAUDE.md 기준 "실제 GitHub 연동 테스트 미완료").
`deploy_validate`는 SKILL.md만 있고 구현이 없다(Phase 2 예정).
## 개별 Skill 단독 실행
파이프라인 전체가 아니라 한 단계만 필요할 때가 많다. 입출력 스키마는
`agent/update_catalog/skills/<skill>/SKILL.md`에 있다.
```sh
python3 agent/update_catalog/skills/helm_diff/scripts/run.py \
--chart airflow --repo bitnami \
--chart-path /path/to/dip-catalog/manifests/helm/airflow/1.15.0 \
--from-version 1.15.0 --to-version 1.16.0
```
## 지켜야 할 설계 원칙
CLAUDE.md "설계 원칙"이 이 파이프라인을 직접 구속한다. 특히:
- **helm 실행은 Python Skill이 전담한다** — LLM이 helm CLI를 직접 돌려 diff를 만들지 않는다.
- **LLM 입력은 Structured JSON만** — raw helm output이나 자유 텍스트를 넘기지 않는다.
- **Breaking change는 Rule Engine이 먼저 판단한다**(`custom-values.yaml`의 실제 사용 키 기준).
LLM은 `breaking=true`일 때 Markdown 설명 생성만 담당한다.
## 참고
- CLAUDE.md "자동화 Skills 작업" — 파이프라인 개요·환경변수
- `agent/update_catalog/docs/design/` — 컴포넌트별 상세 설계(00~05)
- `agent/update_catalog/docs/status.md` — 구현 현황