mk-release-cli
v1.0.0
Published
Universal CLI tools for release management
Downloads
5
Maintainers
Readme
@hiconsy/cli-tools
하이컨시 모노레포를 위한 CLI 도구 모음입니다.
📦 패키지 구성
release-branch
앱 릴리스 브랜치를 자동으로 생성하는 인터랙티브 CLI 도구입니다.
🚀 사용법
릴리스 브랜치 생성
프로젝트 루트에서 다음 명령어를 실행하세요:
pnpm release:branch실행 화면
🚀 Release Branch Creator
📦 앱을 선택하세요
❯ demo-csr
demo-ssr
legacy-contentsvod
legacy-offline-my-class
mass-online
🔢 버전 타입을 선택하세요
❯ patch (1.0.0 → 1.0.1)
minor (1.0.0 → 1.1.0)
major (1.0.0 → 2.0.0)
◆ demo-csr: 0.0.1 → 0.0.2 릴리스 브랜치를 생성하시겠습니까? (y/N)조작 방법
- ↑/↓ 화살표 키: 선택 이동
- Enter: 선택 확인
- Ctrl+C: 언제든지 취소
🏗️ 아키텍처
디렉토리 구조
packages/cli-tools/
├── src/
│ ├── release-branch/
│ │ ├── index.ts # 메인 진입점 (절차형 플로우)
│ │ ├── apps.ts # 앱 디렉토리 스캔
│ │ ├── version.ts # 버전 계산 로직
│ │ ├── git.ts # Git 작업
│ │ ├── prompts.ts # UI 프롬프트
│ │ └── logger.ts # 로깅 유틸리티
│ └── types.ts # 공통 타입 정의
└── tests/
├── release-branch/
│ ├── apps.test.ts
│ ├── version.test.ts
│ └── git.test.ts
└── setup.ts주요 기능
1. 앱 자동 감지 (apps.ts)
apps/ 디렉토리를 스캔하여 package.json이 있는 모든 앱을 자동으로 감지합니다.
const apps = await getAvailableApps()
// ['demo-csr', 'demo-ssr', 'legacy-contentsvod', ...]- ✅ 새 앱 추가 시 자동 반영
- ✅ 앱 제거 시 자동 제외
- ✅ 알파벳 순 정렬
2. 버전 계산 (version.ts)
Semantic Versioning에 따라 버전을 계산합니다.
calculateNewVersion('1.2.3', 'major') // '2.0.0'
calculateNewVersion('1.2.3', 'minor') // '1.3.0'
calculateNewVersion('1.2.3', 'patch') // '1.2.4'- ✅ 버전 형식 검증
- ✅ 숫자 파싱 검증
- ✅ 명확한 에러 메시지
3. Git 작업 (git.ts)
Git 명령어를 순차적으로 실행합니다.
await createReleaseBranch({ app: 'demo-csr', version: '1.0.1' })실행 순서:
- 브랜치 생성 (
git checkout -b demo-csr/v1.0.1) - package.json 버전 업데이트
- 변경사항 커밋
- 원격 저장소에 푸시
4. 인터랙티브 UI (prompts.ts)
@clack/prompts를 사용한 아름다운 CLI UI
- ✅ 화살표 키 네비게이션
- ✅ 취소 감지 (Ctrl+C)
- ✅ 명확한 시각적 피드백
- ✅ 스피너 애니메이션
🧪 테스트
테스트 실행
# 단일 실행
pnpm --filter @hiconsy/cli-tools test
# Watch 모드
pnpm --filter @hiconsy/cli-tools test:watch
# 커버리지 리포트
pnpm --filter @hiconsy/cli-tools test:coverage테스트 구조
단위 테스트
apps.test.ts
- ✅ package.json이 있는 디렉토리만 반환
- ✅ apps 디렉토리 없을 때 에러
- ✅ 알파벳 순 정렬
- ✅ 빈 디렉토리 처리
version.test.ts
- ✅ patch/minor/major 버전 계산
- ✅ 유효하지 않은 버전 형식 에러
- ✅ 숫자가 아닌 버전 에러
git.test.ts
- ✅ 현재 브랜치명 가져오기
- ✅ Git 상태 확인
- ✅ 브랜치 존재 여부 확인
- ✅ 릴리스 브랜치 생성 플로우
통합 테스트
모든 함수는 모킹을 통해 실제 Git 작업 없이 테스트됩니다.
테스트 커버리지 목표
- 라인 커버리지: 90% 이상
- 함수 커버리지: 95% 이상
- 브랜치 커버리지: 85% 이상
🛠️ 개발
패키지 설치
pnpm install개발 모드 실행
# 전체 프로젝트에서 실행
pnpm release:branch
# 또는 패키지 내에서 직접 실행
cd packages/cli-tools
pnpm dev타입 체크
pnpm --filter @hiconsy/cli-tools check-types빌드
pnpm --filter @hiconsy/cli-tools build📚 기술 스택
- TypeScript 5.8 - 타입 안전성
- @clack/prompts - 인터랙티브 CLI UI
- execa - Git 명령어 실행
- chalk - 터미널 색상
- fs-extra - 파일 시스템 유틸
- zod - 런타임 타입 검증 (향후 사용)
- Vitest - 테스트 프레임워크
🔄 워크플로우
전체 실행 순서
1. 사용 가능한 앱 목록 가져오기
↓
2. 사용자가 앱 선택 (화살표 키)
↓
3. 사용자가 버전 타입 선택 (patch/minor/major)
↓
4. 현재 버전 확인 및 새 버전 계산
↓
5. Git 상태 확인
- main 브랜치가 아니면 자동 이동
- 변경사항 있으면 stash 저장
- main 브랜치를 최신 상태로 업데이트
↓
6. 브랜치 중복 확인 (로컬/원격)
↓
7. 사용자 최종 확인
↓
8. 릴리스 브랜치 생성
- 브랜치 생성
- package.json 버전 업데이트
- 커밋
- 푸시
↓
9. 완료 메시지 및 다음 단계 안내🎯 설계 원칙
1. 절차형 프로그래밍
메인 함수(index.ts)는 순차적인 단계로 구성되어 읽기 쉽습니다.
async function main() {
// 1단계
const apps = await getAvailableApps()
// 2단계
const selectedApp = await selectApp(apps)
// 3단계
const versionType = await selectVersionType()
// ...
}2. 함수 단위 분리
각 기능은 독립적인 순수 함수로 분리되어 테스트와 유지보수가 용이합니다.
// 순수 함수 - 부작용 없음
export function calculateNewVersion(current: string, type: VersionType): string
// 비동기 함수 - 명확한 입출력
export async function getAvailableApps(): Promise<string[]>3. 타입 안전성
TypeScript의 엄격한 타입 체크를 활용합니다.
// 타입 정의가 명확
type VersionType = 'major' | 'minor' | 'patch'
// 런타임 검증
if (!['major', 'minor', 'patch'].includes(type)) {
throw new Error('Invalid version type')
}4. 에러 처리
모든 함수는 명확한 에러 메시지를 제공합니다.
if (!await fs.pathExists(pkgPath)) {
throw new Error(`${appName}/package.json 파일을 찾을 수 없습니다.`)
}📖 API 문서
getAvailableApps()
앱 목록을 가져옵니다.
Returns: Promise<string[]>
Throws: apps 디렉토리가 없는 경우
calculateNewVersion(currentVersion, type)
새 버전을 계산합니다.
Parameters:
currentVersion: string- 현재 버전 (예: "1.2.3")type: VersionType- 버전 타입
Returns: string - 새 버전
Throws: 유효하지 않은 버전 형식
createReleaseBranch(options)
릴리스 브랜치를 생성합니다.
Parameters:
options.app: string- 앱 이름options.version: string- 새 버전
Returns: Promise<void>
Throws: Git 작업 실패 시
🤝 기여 가이드
- 기능 추가 시 반드시 테스트 코드 작성
- 함수에 JSDoc 주석 추가
- 타입을 명확히 정의
- 에러 메시지는 한국어로, 사용자 친화적으로
📝 변경 이력
v0.1.0 (2025-10-02)
- ✅ 초기 릴리스
- ✅ release-branch CLI 도구 추가
- ✅ TypeScript 기반 구현
- ✅ @clack/prompts 통합
- ✅ Vitest 테스트 추가
- ✅ 앱 자동 감지 기능
