feat: Stage 2 TypeScript 타입 안전성 개선 - any 타입 83개 → 62개 대폭 감소
✨ 주요 개선사항: - any 타입 83개에서 62개로 21개 수정 (25% 감소) - 모든 ESLint 에러 11개 → 0개 완전 해결 - 타입 안전성 대폭 향상으로 런타임 오류 가능성 감소 🔧 수정된 파일들: • PWADebug.tsx - 사용하지 않는 import들에 _ prefix 추가 • categoryUtils.ts - 불필요한 any 캐스트 제거 • TransactionsHeader.tsx - BudgetData 인터페이스 정의 • storageUtils.ts - generic 타입과 unknown 타입 적용 • 각종 error handler들 - Error | {message?: string} 타입 적용 • test 파일들 - 적절한 mock 인터페이스 정의 • 유틸리티 파일들 - any → unknown 또는 적절한 타입으로 교체 🏆 성과: - 코드 품질 크게 향상 (280 → 80 문제로 71% 감소) - TypeScript 컴파일러의 타입 체크 효과성 증대 - 개발자 경험 개선 (IDE 자동완성, 타입 추론 등) 🧹 추가 정리: - ESLint no-console/no-alert 경고 해결 - Prettier 포맷팅 적용으로 코드 스타일 통일 🎯 다음 단계: 남은 62개 any 타입 계속 개선 예정 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
153
docs/android-signing-setup.md
Normal file
153
docs/android-signing-setup.md
Normal file
@@ -0,0 +1,153 @@
|
||||
# Android 코드 서명 설정 가이드
|
||||
|
||||
## 1. Android 키스토어 생성
|
||||
|
||||
### 키스토어 파일 생성
|
||||
```bash
|
||||
# Android 프로젝트 루트에서 실행
|
||||
cd android/app
|
||||
mkdir -p keystore
|
||||
|
||||
# 키스토어 생성 (1회만 실행)
|
||||
keytool -genkey -v -keystore keystore/release.keystore -alias zellyy-finance-key -keyalg RSA -keysize 2048 -validity 10000
|
||||
|
||||
# 입력할 정보:
|
||||
# - 키스토어 비밀번호: [안전한 비밀번호]
|
||||
# - 키 비밀번호: [안전한 비밀번호]
|
||||
# - 이름과 조직: Zellyy Finance Team
|
||||
# - 조직 단위: Development
|
||||
# - 도시: Seoul
|
||||
# - 시/도: Seoul
|
||||
# - 국가 코드: KR
|
||||
```
|
||||
|
||||
### 키스토어 정보 확인
|
||||
```bash
|
||||
keytool -list -v -keystore keystore/release.keystore -alias zellyy-finance-key
|
||||
```
|
||||
|
||||
## 2. Android 빌드 설정
|
||||
|
||||
### key.properties 파일 생성 (로컬 개발용)
|
||||
```bash
|
||||
# android/key.properties
|
||||
storePassword=your_keystore_password
|
||||
keyPassword=your_key_password
|
||||
keyAlias=zellyy-finance-key
|
||||
storeFile=keystore/release.keystore
|
||||
```
|
||||
|
||||
### build.gradle 설정 확인
|
||||
`android/app/build.gradle`에서 릴리즈 서명 설정이 올바른지 확인:
|
||||
|
||||
```gradle
|
||||
android {
|
||||
signingConfigs {
|
||||
release {
|
||||
if (project.hasProperty('storeFile')) {
|
||||
storeFile file(project.property('storeFile'))
|
||||
storePassword project.property('storePassword')
|
||||
keyAlias project.property('keyAlias')
|
||||
keyPassword project.property('keyPassword')
|
||||
}
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. GitHub Secrets 설정
|
||||
|
||||
GitHub 리포지토리 Settings > Secrets and variables > Actions에서 다음 시크릿들을 추가:
|
||||
|
||||
### Android 관련 시크릿
|
||||
- `ANDROID_KEYSTORE_BASE64`: 키스토어 파일을 base64로 인코딩한 값
|
||||
- `ANDROID_KEYSTORE_PASSWORD`: 키스토어 비밀번호
|
||||
- `ANDROID_KEY_PASSWORD`: 키 비밀번호
|
||||
- `ANDROID_KEY_ALIAS`: 키 별칭 (zellyy-finance-key)
|
||||
|
||||
### 키스토어 파일을 base64로 인코딩하는 방법
|
||||
```bash
|
||||
base64 -i android/app/keystore/release.keystore | pbcopy
|
||||
# 결과를 ANDROID_KEYSTORE_BASE64 시크릿에 저장
|
||||
```
|
||||
|
||||
### 환경 변수 시크릿
|
||||
- `VITE_SUPABASE_URL`: Supabase URL
|
||||
- `VITE_SUPABASE_ANON_KEY`: Supabase Anonymous Key
|
||||
- `VITE_CLERK_PUBLISHABLE_KEY`: Clerk Publishable Key
|
||||
- `VITE_SENTRY_DSN`: Sentry DSN
|
||||
|
||||
## 4. Google Play Console 설정
|
||||
|
||||
### 서비스 계정 생성
|
||||
1. Google Cloud Console에서 프로젝트 생성/선택
|
||||
2. APIs & Services > Credentials에서 서비스 계정 생성
|
||||
3. 서비스 계정 키(JSON) 다운로드
|
||||
4. Google Play Console에서 서비스 계정에 앱 권한 부여
|
||||
|
||||
### GitHub 시크릿 추가
|
||||
- `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON`: 서비스 계정 JSON 파일 내용
|
||||
|
||||
## 5. 빌드 테스트
|
||||
|
||||
### 로컬 릴리즈 빌드 테스트
|
||||
```bash
|
||||
# 웹 앱 빌드
|
||||
npm run build:prod
|
||||
|
||||
# Capacitor 동기화
|
||||
npm run mobile:sync
|
||||
|
||||
# Android 릴리즈 번들 빌드
|
||||
cd android
|
||||
./gradlew bundleRelease
|
||||
|
||||
# 생성된 파일 확인
|
||||
ls -la app/build/outputs/bundle/release/
|
||||
```
|
||||
|
||||
### APK 빌드 테스트
|
||||
```bash
|
||||
cd android
|
||||
./gradlew assembleRelease
|
||||
|
||||
# 생성된 파일 확인
|
||||
ls -la app/build/outputs/apk/release/
|
||||
```
|
||||
|
||||
## 6. 보안 고려사항
|
||||
|
||||
### 키스토어 관리
|
||||
- 키스토어 파일은 절대 git에 커밋하지 않음
|
||||
- `.gitignore`에 `*.keystore`, `key.properties` 추가
|
||||
- 키스토어 백업을 안전한 곳에 보관
|
||||
- 비밀번호는 안전한 패스워드 매니저에 저장
|
||||
|
||||
### CI/CD 보안
|
||||
- GitHub Secrets 사용으로 민감 정보 보호
|
||||
- 빌드 로그에 비밀번호 노출 방지
|
||||
- 릴리즈 브랜치에서만 서명된 빌드 생성
|
||||
|
||||
## 7. 문제 해결
|
||||
|
||||
### 일반적인 오류들
|
||||
- `Could not find keystore`: 키스토어 경로 확인
|
||||
- `Keystore password incorrect`: 비밀번호 확인
|
||||
- `Key alias not found`: 별칭 이름 확인
|
||||
- `Build failed`: Gradle 로그 확인
|
||||
|
||||
### 디버깅 명령어
|
||||
```bash
|
||||
# Gradle 빌드 상세 로그
|
||||
./gradlew bundleRelease --info --stacktrace
|
||||
|
||||
# 키스토어 정보 확인
|
||||
keytool -list -v -keystore keystore/release.keystore
|
||||
```
|
||||
413
docs/app-store-deployment-guide.md
Normal file
413
docs/app-store-deployment-guide.md
Normal file
@@ -0,0 +1,413 @@
|
||||
# 앱 스토어 배포 자동화 가이드
|
||||
|
||||
## 개요
|
||||
|
||||
Zellyy Finance 앱의 Google Play Store와 Apple App Store 자동 배포 시스템 설정 가이드입니다. GitHub Actions를 통해 빌드부터 스토어 업로드까지 완전 자동화됩니다.
|
||||
|
||||
## 지원 플랫폼
|
||||
|
||||
### Android - Google Play Store
|
||||
- **트랙**: Internal Testing (내부 테스트)
|
||||
- **파일 형식**: AAB (Android App Bundle)
|
||||
- **자동 업로드**: main 브랜치 빌드 시
|
||||
- **API**: Google Play Console API
|
||||
|
||||
### iOS - App Store Connect
|
||||
- **트랙**: TestFlight (베타 테스트)
|
||||
- **파일 형식**: IPA
|
||||
- **자동 업로드**: main 브랜치 빌드 시
|
||||
- **API**: App Store Connect API
|
||||
|
||||
## 사전 준비 사항
|
||||
|
||||
### 1. Google Play Store 설정
|
||||
|
||||
#### 1.1 Google Cloud Console 설정
|
||||
1. [Google Cloud Console](https://console.cloud.google.com/)에 접속
|
||||
2. 새 프로젝트 생성 또는 기존 프로젝트 선택
|
||||
3. Google Play Developer Reporting API 활성화
|
||||
4. 서비스 계정 생성:
|
||||
- IAM & Admin > 서비스 계정
|
||||
- "서비스 계정 만들기" 클릭
|
||||
- 이름: `zellyy-finance-ci`
|
||||
- 역할: 없음 (Google Play Console에서 설정)
|
||||
|
||||
#### 1.2 Google Play Console 설정
|
||||
1. [Google Play Console](https://play.google.com/console/)에 접속
|
||||
2. 새 앱 생성:
|
||||
- 앱 이름: `Zellyy Finance`
|
||||
- 패키지명: `com.zellyy.finance`
|
||||
- 언어: 한국어
|
||||
3. API 액세스 설정:
|
||||
- 설정 > API 액세스
|
||||
- 서비스 계정 연결
|
||||
- 위에서 생성한 서비스 계정 선택
|
||||
- 권한: 앱 정보 보기 및 편집, 릴리즈 관리
|
||||
|
||||
#### 1.3 서비스 계정 키 생성
|
||||
```bash
|
||||
# Google Cloud Console에서
|
||||
1. IAM & Admin > 서비스 계정
|
||||
2. 생성한 서비스 계정 클릭
|
||||
3. "키" 탭 > "키 추가" > "새 키 만들기"
|
||||
4. JSON 형식 선택
|
||||
5. 다운로드된 JSON 파일 내용을 GitHub Secrets에 저장
|
||||
```
|
||||
|
||||
### 2. Apple App Store 설정
|
||||
|
||||
#### 2.1 Apple Developer Account 준비
|
||||
1. [Apple Developer](https://developer.apple.com/) 계정 필요
|
||||
2. App Store Connect 접근 권한
|
||||
3. 연간 개발자 등록비 $99 납부
|
||||
|
||||
#### 2.2 App Store Connect 앱 생성
|
||||
1. [App Store Connect](https://appstoreconnect.apple.com/)에 접속
|
||||
2. 새 앱 생성:
|
||||
- 이름: `Zellyy Finance`
|
||||
- Bundle ID: `com.zellyy.finance`
|
||||
- SKU: `zellyy-finance`
|
||||
- 언어: 한국어
|
||||
|
||||
#### 2.3 API 키 생성
|
||||
1. App Store Connect > 사용자 및 액세스
|
||||
2. 키 탭 > "+" 버튼
|
||||
3. 키 이름: `Zellyy Finance CI/CD`
|
||||
4. 액세스: Developer (또는 App Manager)
|
||||
5. 생성 후 다음 정보 저장:
|
||||
- Issuer ID
|
||||
- Key ID
|
||||
- Private Key (.p8 파일)
|
||||
|
||||
#### 2.4 인증서 및 프로비저닝 프로파일
|
||||
```bash
|
||||
# iOS 배포 인증서 생성
|
||||
1. Apple Developer > Certificates
|
||||
2. "+" > iOS Distribution (App Store and Ad Hoc)
|
||||
3. CSR 파일 업로드
|
||||
4. 인증서 다운로드 (.cer)
|
||||
|
||||
# 프로비저닝 프로파일 생성
|
||||
1. Apple Developer > Profiles
|
||||
2. "+" > iOS App Store
|
||||
3. App ID 선택: com.zellyy.finance
|
||||
4. 인증서 선택: 위에서 생성한 배포 인증서
|
||||
5. 프로파일 다운로드 (.mobileprovision)
|
||||
```
|
||||
|
||||
## GitHub Secrets 설정
|
||||
|
||||
### 1. Repository Settings
|
||||
```bash
|
||||
GitHub Repository > Settings > Secrets and Variables > Actions
|
||||
```
|
||||
|
||||
### 2. Android 관련 Secrets
|
||||
|
||||
| Secret 이름 | 설명 | 값 |
|
||||
|-------------|------|-----|
|
||||
| `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON` | Google Play API 서비스 계정 JSON | Google Cloud Console에서 다운로드한 JSON 파일 전체 내용 |
|
||||
|
||||
### 3. iOS 관련 Secrets
|
||||
|
||||
| Secret 이름 | 설명 | 값 |
|
||||
|-------------|------|-----|
|
||||
| `APPSTORE_ISSUER_ID` | App Store Connect API Issuer ID | App Store Connect API 키 생성 시 표시된 Issuer ID |
|
||||
| `APPSTORE_KEY_ID` | App Store Connect API Key ID | API 키 생성 시 표시된 Key ID |
|
||||
| `APPSTORE_PRIVATE_KEY` | App Store Connect API Private Key | .p8 파일의 전체 내용 (헤더/푸터 포함) |
|
||||
|
||||
### 4. 코드 서명 Secrets (기존 문서 참조)
|
||||
|
||||
| Secret 이름 | 설명 |
|
||||
|-------------|------|
|
||||
| `ANDROID_KEYSTORE_BASE64` | Android 키스토어 파일 (base64) |
|
||||
| `ANDROID_KEYSTORE_PASSWORD` | 키스토어 비밀번호 |
|
||||
| `ANDROID_KEY_PASSWORD` | 키 비밀번호 |
|
||||
| `ANDROID_KEY_ALIAS` | 키 별칭 |
|
||||
| `IOS_CERTIFICATES_P12_BASE64` | iOS 배포 인증서 P12 (base64) |
|
||||
| `IOS_CERTIFICATES_P12_PASSWORD` | P12 파일 비밀번호 |
|
||||
|
||||
## 배포 트랙 설정
|
||||
|
||||
### 1. Google Play Store 트랙
|
||||
|
||||
#### Internal Testing (내부 테스트)
|
||||
- **목적**: 개발팀 내부 테스트
|
||||
- **승인**: 즉시 (Google 승인 불필요)
|
||||
- **테스터**: 최대 100명
|
||||
- **자동 업로드**: ✅ 활성화됨
|
||||
|
||||
#### Alpha/Beta Testing (미래 계획)
|
||||
```yaml
|
||||
# 향후 Alpha/Beta 트랙 추가 시
|
||||
track: alpha # 또는 beta
|
||||
```
|
||||
|
||||
#### Production (프로덕션)
|
||||
```yaml
|
||||
# 안정성 검증 후 수동으로 프로덕션 배포
|
||||
track: production
|
||||
inAppUpdatePriority: 3
|
||||
userFraction: 1.0
|
||||
```
|
||||
|
||||
### 2. App Store Connect 트랙
|
||||
|
||||
#### TestFlight (베타 테스트)
|
||||
- **목적**: 베타 테스터 배포
|
||||
- **승인**: Apple 자동 승인 (보통 24시간 이내)
|
||||
- **테스터**: 최대 10,000명
|
||||
- **자동 업로드**: ✅ 활성화됨
|
||||
|
||||
#### App Store (프로덕션)
|
||||
- **목적**: 일반 사용자 배포
|
||||
- **승인**: Apple 수동 심사 (2-7일)
|
||||
- **배포**: 수동 릴리즈 필요
|
||||
|
||||
## 자동 배포 워크플로우
|
||||
|
||||
### 1. 트리거 조건
|
||||
```yaml
|
||||
# 자동 배포가 실행되는 조건
|
||||
on:
|
||||
push:
|
||||
branches: [main] # main 브랜치 푸시
|
||||
tags: ['v*'] # 버전 태그 푸시
|
||||
workflow_dispatch: # 수동 실행
|
||||
```
|
||||
|
||||
### 2. 배포 흐름
|
||||
```
|
||||
코드 푸시 → 테스트 → 빌드 → 버전 태그 → 스토어 업로드 → 알림
|
||||
```
|
||||
|
||||
### 3. 배포 단계별 상세
|
||||
|
||||
#### Stage 1: 빌드 및 서명
|
||||
```yaml
|
||||
- Android AAB 생성 (서명 포함)
|
||||
- iOS IPA 생성 (서명 포함)
|
||||
- 아티팩트 저장
|
||||
```
|
||||
|
||||
#### Stage 2: 스토어 업로드
|
||||
```yaml
|
||||
- Google Play: Internal Testing 트랙 업로드
|
||||
- TestFlight: 베타 테스트 업로드
|
||||
```
|
||||
|
||||
#### Stage 3: 결과 알림
|
||||
```yaml
|
||||
- Slack 알림 (성공/실패)
|
||||
- GitHub 이슈 생성 (실패 시)
|
||||
- 이메일 알림 (선택사항)
|
||||
```
|
||||
|
||||
## 릴리즈 노트 자동 생성
|
||||
|
||||
### 1. 커밋 메시지 기반 생성
|
||||
```bash
|
||||
# Conventional Commits 사용
|
||||
feat: 새로운 거래 필터링 기능 추가
|
||||
fix: 로그인 세션 만료 문제 수정
|
||||
perf: 차트 렌더링 성능 50% 개선
|
||||
```
|
||||
|
||||
### 2. 릴리즈 노트 형식
|
||||
```markdown
|
||||
# Zellyy Finance v1.2.0
|
||||
|
||||
## ✨ 새로운 기능
|
||||
- 거래 내역 고급 필터링
|
||||
- 다크 모드 지원
|
||||
|
||||
## 🐛 버그 수정
|
||||
- 로그인 세션 안정성 개선
|
||||
- 차트 데이터 로딩 오류 수정
|
||||
|
||||
## ⚡ 성능 개선
|
||||
- 앱 시작 시간 30% 단축
|
||||
- 메모리 사용량 최적화
|
||||
```
|
||||
|
||||
### 3. 스토어별 릴리즈 노트
|
||||
|
||||
#### Google Play Store
|
||||
- **최대 길이**: 500자
|
||||
- **언어**: 한국어
|
||||
- **자동 적용**: ✅
|
||||
|
||||
#### App Store Connect
|
||||
- **최대 길이**: 4000자
|
||||
- **언어**: 한국어
|
||||
- **자동 적용**: ✅
|
||||
|
||||
## 배포 후 검증
|
||||
|
||||
### 1. 자동 검증
|
||||
```bash
|
||||
# GitHub Actions에서 자동 실행
|
||||
- 스토어 업로드 성공 확인
|
||||
- 버전 번호 일치 확인
|
||||
- 릴리즈 노트 적용 확인
|
||||
```
|
||||
|
||||
### 2. 수동 검증
|
||||
```bash
|
||||
# 개발팀에서 수행
|
||||
1. Google Play Console에서 Internal Testing 트랙 확인
|
||||
2. TestFlight에서 베타 빌드 확인
|
||||
3. 실제 디바이스에서 앱 설치 테스트
|
||||
4. 주요 기능 동작 확인
|
||||
```
|
||||
|
||||
## 트러블슈팅
|
||||
|
||||
### 1. Google Play Store 업로드 실패
|
||||
|
||||
#### 오류: "Package name already exists"
|
||||
```bash
|
||||
해결:
|
||||
1. 기존 앱이 있는지 Google Play Console 확인
|
||||
2. 패키지명 중복 확인 (com.zellyy.finance)
|
||||
3. 다른 개발자 계정에서 사용 중인지 확인
|
||||
```
|
||||
|
||||
#### 오류: "Version code too low"
|
||||
```bash
|
||||
해결:
|
||||
1. android/app/build.gradle의 versionCode 확인
|
||||
2. semantic-release로 자동 증가하는지 확인
|
||||
3. 수동으로 버전 코드 증가
|
||||
```
|
||||
|
||||
#### 오류: "API access denied"
|
||||
```bash
|
||||
해결:
|
||||
1. Google Play Console에서 API 액세스 확인
|
||||
2. 서비스 계정 권한 확인
|
||||
3. JSON 키 파일 재생성
|
||||
```
|
||||
|
||||
### 2. App Store Connect 업로드 실패
|
||||
|
||||
#### 오류: "Invalid provisioning profile"
|
||||
```bash
|
||||
해결:
|
||||
1. Apple Developer에서 프로비저닝 프로파일 재생성
|
||||
2. 인증서 유효성 확인
|
||||
3. Bundle ID 일치 확인 (com.zellyy.finance)
|
||||
```
|
||||
|
||||
#### 오류: "API key invalid"
|
||||
```bash
|
||||
해결:
|
||||
1. App Store Connect에서 API 키 재생성
|
||||
2. Issuer ID, Key ID 재확인
|
||||
3. P8 파일 전체 내용 확인 (헤더/푸터 포함)
|
||||
```
|
||||
|
||||
#### 오류: "Build processing timeout"
|
||||
```bash
|
||||
해결:
|
||||
1. Apple 서버 상태 확인
|
||||
2. 15-30분 후 재시도
|
||||
3. 빌드 크기 최적화
|
||||
```
|
||||
|
||||
### 3. 일반적인 배포 문제
|
||||
|
||||
#### 빌드 아티팩트 누락
|
||||
```bash
|
||||
해결:
|
||||
1. GitHub Actions 아티팩트 저장 확인
|
||||
2. 빌드 단계 성공 여부 확인
|
||||
3. 파일 경로 올바른지 확인
|
||||
```
|
||||
|
||||
#### 버전 동기화 오류
|
||||
```bash
|
||||
해결:
|
||||
1. npm run version:sync 실행
|
||||
2. semantic-release 설정 확인
|
||||
3. package.json 버전 확인
|
||||
```
|
||||
|
||||
## 모니터링 및 알림
|
||||
|
||||
### 1. 배포 상태 모니터링
|
||||
```bash
|
||||
# GitHub Actions에서 제공
|
||||
- 실시간 배포 진행 상황
|
||||
- 각 단계별 성공/실패 상태
|
||||
- 상세 로그 및 오류 메시지
|
||||
```
|
||||
|
||||
### 2. 스토어 상태 확인
|
||||
```bash
|
||||
# Google Play Console
|
||||
- Internal Testing 트랙 상태
|
||||
- 리뷰 진행 상황
|
||||
- 다운로드 통계
|
||||
|
||||
# App Store Connect
|
||||
- TestFlight 베타 상태
|
||||
- 리뷰 진행 상황
|
||||
- 크래시 리포트
|
||||
```
|
||||
|
||||
### 3. 알림 채널
|
||||
```bash
|
||||
# 즉시 알림
|
||||
- Slack #deployments 채널
|
||||
- 이메일 (선택사항)
|
||||
- GitHub 이슈 (실패 시)
|
||||
|
||||
# 정기 리포트
|
||||
- 주간 배포 요약
|
||||
- 월간 스토어 통계
|
||||
- 분기별 성과 분석
|
||||
```
|
||||
|
||||
## 보안 고려사항
|
||||
|
||||
### 1. API 키 관리
|
||||
- GitHub Secrets에 안전하게 저장
|
||||
- 정기적인 키 로테이션 (6개월마다)
|
||||
- 최소 권한 원칙 적용
|
||||
|
||||
### 2. 코드 서명 인증서
|
||||
- P12 파일 안전한 저장
|
||||
- 인증서 만료일 추적 (Apple: 1년, Android: 25년)
|
||||
- 백업 및 복구 계획
|
||||
|
||||
### 3. 접근 권한 관리
|
||||
- 배포 권한은 핵심 개발자만
|
||||
- API 키 접근 로그 모니터링
|
||||
- 의심스러운 활동 알림
|
||||
|
||||
## 확장 계획
|
||||
|
||||
### 1. 추가 트랙 지원
|
||||
```bash
|
||||
# Google Play Store
|
||||
- Alpha Testing 트랙
|
||||
- Beta Testing 트랙
|
||||
- Production 자동 배포
|
||||
|
||||
# App Store
|
||||
- App Store 자동 배포
|
||||
- 단계적 출시 (Phased Release)
|
||||
```
|
||||
|
||||
### 2. 고급 기능
|
||||
```bash
|
||||
- A/B 테스트 자동화
|
||||
- 스토어 메타데이터 관리
|
||||
- 스크린샷 자동 업로드
|
||||
- 다국어 릴리즈 노트
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
이 가이드는 Zellyy Finance 앱의 완전 자동화된 스토어 배포 시스템 구축을 위한 종합 참조 문서입니다.
|
||||
273
docs/ci-cd-setup-guide.md
Normal file
273
docs/ci-cd-setup-guide.md
Normal file
@@ -0,0 +1,273 @@
|
||||
# CI/CD 파이프라인 설정 가이드
|
||||
|
||||
## 개요
|
||||
|
||||
Zellyy Finance 프로젝트는 GitHub Actions를 사용하여 완전히 자동화된 CI/CD 파이프라인을 구축했습니다. 이 가이드는 파이프라인 설정과 사용 방법을 설명합니다.
|
||||
|
||||
## 파이프라인 구조
|
||||
|
||||
### 워크플로우 흐름
|
||||
```
|
||||
코드 푸시 → 테스트 → 웹 빌드 → 모바일 빌드 → 릴리즈 → 앱스토어 배포
|
||||
```
|
||||
|
||||
### 지원 플랫폼
|
||||
- **Web**: Vercel 배포 (별도 워크플로우)
|
||||
- **Android**: Google Play Store (AAB/APK)
|
||||
- **iOS**: App Store Connect / TestFlight (IPA)
|
||||
|
||||
## GitHub Secrets 설정
|
||||
|
||||
### 1. Android 관련 Secrets
|
||||
|
||||
| Secret 이름 | 설명 | 생성 방법 |
|
||||
|-------------|------|-----------|
|
||||
| `ANDROID_KEYSTORE_BASE64` | 키스토어 파일 (base64) | `base64 -i release.keystore \| pbcopy` |
|
||||
| `ANDROID_KEYSTORE_PASSWORD` | 키스토어 비밀번호 | 키스토어 생성 시 설정한 비밀번호 |
|
||||
| `ANDROID_KEY_PASSWORD` | 키 비밀번호 | 키 생성 시 설정한 비밀번호 |
|
||||
| `ANDROID_KEY_ALIAS` | 키 별칭 | 기본값: `zellyy-finance-key` |
|
||||
|
||||
### 2. iOS 관련 Secrets
|
||||
|
||||
| Secret 이름 | 설명 | 생성 방법 |
|
||||
|-------------|------|-----------|
|
||||
| `IOS_CERTIFICATES_P12_BASE64` | 배포 인증서 (base64) | Keychain에서 P12로 내보내기 후 base64 변환 |
|
||||
| `IOS_CERTIFICATES_P12_PASSWORD` | P12 파일 비밀번호 | P12 내보내기 시 설정한 비밀번호 |
|
||||
| `APPSTORE_ISSUER_ID` | App Store Connect API 발급자 ID | App Store Connect > API 키 생성 |
|
||||
| `APPSTORE_KEY_ID` | App Store Connect API 키 ID | API 키 생성 시 표시되는 키 ID |
|
||||
| `APPSTORE_PRIVATE_KEY` | App Store Connect API 개인 키 | .p8 파일 내용 전체 |
|
||||
|
||||
### 3. Google Play Store Secrets
|
||||
|
||||
| Secret 이름 | 설명 | 생성 방법 |
|
||||
|-------------|------|-----------|
|
||||
| `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON` | 서비스 계정 JSON | Google Cloud Console에서 서비스 계정 키 생성 |
|
||||
|
||||
### 4. 앱 환경 변수 Secrets
|
||||
|
||||
| Secret 이름 | 설명 |
|
||||
|-------------|------|
|
||||
| `VITE_SUPABASE_URL` | Supabase 프로젝트 URL |
|
||||
| `VITE_SUPABASE_ANON_KEY` | Supabase Anonymous Key |
|
||||
| `VITE_CLERK_PUBLISHABLE_KEY` | Clerk Publishable Key |
|
||||
| `VITE_SENTRY_DSN` | Sentry DSN |
|
||||
|
||||
## 워크플로우 트리거 조건
|
||||
|
||||
### 자동 트리거
|
||||
- **PR 생성/업데이트**: 테스트 + 디버그 빌드만 실행
|
||||
- **main 브랜치 푸시**: 전체 파이프라인 실행 (릴리즈 빌드 + 배포)
|
||||
- **태그 푸시** (`v*`): 전체 파이프라인 실행
|
||||
|
||||
### 수동 트리거
|
||||
GitHub Actions 탭에서 `workflow_dispatch` 이벤트로 수동 실행 가능
|
||||
|
||||
## 빌드 환경별 설정
|
||||
|
||||
### Development 환경
|
||||
```bash
|
||||
npm run build:dev
|
||||
# - 앱 이름: Zellyy Finance (Dev)
|
||||
# - 앱 ID: com.zellyy.finance.dev
|
||||
# - 배경색: 노란색 톤 (#FEF3C7)
|
||||
```
|
||||
|
||||
### Staging 환경
|
||||
```bash
|
||||
npm run build:staging
|
||||
# - 앱 이름: Zellyy Finance (Beta)
|
||||
# - 앱 ID: com.zellyy.finance.beta
|
||||
# - 배경색: 파란색 톤 (#DBEAFE)
|
||||
```
|
||||
|
||||
### Production 환경
|
||||
```bash
|
||||
npm run build:prod
|
||||
# - 앱 이름: Zellyy Finance
|
||||
# - 앱 ID: com.zellyy.finance
|
||||
# - 배경색: 기본색 (#F8FAFC)
|
||||
```
|
||||
|
||||
## 로컬 테스트
|
||||
|
||||
### 1. 디버그 키스토어 생성
|
||||
```bash
|
||||
npm run keystore:debug
|
||||
```
|
||||
|
||||
### 2. 빌드 파이프라인 테스트
|
||||
```bash
|
||||
npm run pipeline:test
|
||||
```
|
||||
|
||||
### 3. 단계별 테스트
|
||||
```bash
|
||||
# 빌드 검증
|
||||
npm run pipeline:validate
|
||||
|
||||
# 모바일 빌드
|
||||
npm run mobile:build
|
||||
|
||||
# Android 디버그 빌드
|
||||
cd android && ./gradlew assembleDebug
|
||||
|
||||
# iOS 디버그 빌드 (macOS만)
|
||||
npm run ios:open
|
||||
```
|
||||
|
||||
## 버전 관리 자동화
|
||||
|
||||
### Semantic Release 구성
|
||||
- **feat**: Minor 버전 증가 (1.0.0 → 1.1.0)
|
||||
- **fix**: Patch 버전 증가 (1.0.0 → 1.0.1)
|
||||
- **BREAKING CHANGE**: Major 버전 증가 (1.0.0 → 2.0.0)
|
||||
|
||||
### 커밋 메시지 규칙
|
||||
```bash
|
||||
# 새 기능
|
||||
git commit -m "feat: 거래 내역 필터링 기능 추가"
|
||||
|
||||
# 버그 수정
|
||||
git commit -m "fix: 로그인 에러 수정"
|
||||
|
||||
# 중대한 변경
|
||||
git commit -m "feat!: 데이터베이스 스키마 변경
|
||||
|
||||
BREAKING CHANGE: 기존 데이터와 호환되지 않음"
|
||||
```
|
||||
|
||||
### 자동 버전 동기화
|
||||
```bash
|
||||
# package.json → Android/iOS 버전 동기화
|
||||
npm run version:sync
|
||||
```
|
||||
|
||||
## 배포 프로세스
|
||||
|
||||
### 1. 개발 → 배포 흐름
|
||||
```
|
||||
1. 기능 개발 (feature branch)
|
||||
2. PR 생성 → 자동 테스트 실행
|
||||
3. main 브랜치 머지 → 자동 릴리즈 빌드
|
||||
4. Semantic Release → 버전 태그 생성
|
||||
5. 앱스토어 자동 업로드
|
||||
```
|
||||
|
||||
### 2. Google Play Store 배포
|
||||
- **트랙**: Internal Testing (내부 테스트)
|
||||
- **파일 형식**: AAB (Android App Bundle)
|
||||
- **자동 업로드**: main 브랜치 빌드 시
|
||||
|
||||
### 3. App Store / TestFlight 배포
|
||||
- **트랙**: TestFlight (베타 테스트)
|
||||
- **파일 형식**: IPA
|
||||
- **자동 업로드**: main 브랜치 빌드 시
|
||||
|
||||
## 모니터링 및 알림
|
||||
|
||||
### 빌드 상태 확인
|
||||
- GitHub Actions 탭에서 실시간 빌드 상태 확인
|
||||
- 이메일 알림 (빌드 실패 시)
|
||||
- Slack 연동 (선택사항)
|
||||
|
||||
### 아티팩트 관리
|
||||
- **보관 기간**: 90일
|
||||
- **다운로드**: GitHub Actions Artifacts 섹션
|
||||
- **크기 제한**: 2GB per artifact
|
||||
|
||||
## 보안 고려사항
|
||||
|
||||
### Secrets 관리
|
||||
- GitHub Secrets 사용으로 민감 정보 보호
|
||||
- 환경별 Secret 분리
|
||||
- 정기적인 키 로테이션
|
||||
|
||||
### 빌드 보안
|
||||
- 서명된 릴리즈 빌드만 배포
|
||||
- 소스맵 업로드 (Sentry)
|
||||
- 의존성 보안 스캔
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### 일반적인 빌드 오류
|
||||
|
||||
#### Android 빌드 실패
|
||||
```bash
|
||||
# 키스토어 관련 오류
|
||||
Error: Keystore file not found
|
||||
→ Solution: ANDROID_KEYSTORE_BASE64 Secret 확인
|
||||
|
||||
# 버전 충돌
|
||||
Error: Version conflict
|
||||
→ Solution: android/app/build.gradle 버전 확인
|
||||
```
|
||||
|
||||
#### iOS 빌드 실패
|
||||
```bash
|
||||
# 인증서 오류
|
||||
Error: Code signing failed
|
||||
→ Solution: IOS_CERTIFICATES_P12_BASE64 Secret 확인
|
||||
|
||||
# 프로비저닝 프로파일 오류
|
||||
Error: No matching provisioning profile
|
||||
→ Solution: Apple Developer Portal에서 프로파일 확인
|
||||
```
|
||||
|
||||
#### 환경 변수 오류
|
||||
```bash
|
||||
# Undefined environment variable
|
||||
Error: VITE_SUPABASE_URL is not defined
|
||||
→ Solution: GitHub Secrets에 모든 필수 환경 변수 설정
|
||||
```
|
||||
|
||||
### 디버깅 도구
|
||||
|
||||
#### 로컬 디버깅
|
||||
```bash
|
||||
# 빌드 로그 상세 출력
|
||||
npm run android:build -- --info
|
||||
|
||||
# 키스토어 정보 확인
|
||||
npm run keystore:info
|
||||
|
||||
# 의존성 확인
|
||||
npm audit
|
||||
```
|
||||
|
||||
#### CI 디버깅
|
||||
```bash
|
||||
# GitHub Actions 로그 다운로드
|
||||
gh run download [run-id]
|
||||
|
||||
# 특정 job 재실행
|
||||
gh workflow run mobile-build.yml
|
||||
```
|
||||
|
||||
## 성능 최적화
|
||||
|
||||
### 빌드 시간 단축
|
||||
- 의존성 캐싱 활성화
|
||||
- 병렬 빌드 사용
|
||||
- 불필요한 단계 제거
|
||||
|
||||
### 아티팩트 크기 최적화
|
||||
- Tree shaking 활성화
|
||||
- Code splitting 적용
|
||||
- 이미지 압축
|
||||
|
||||
## 확장 계획
|
||||
|
||||
### 추가 예정 기능
|
||||
- Slack 알림 연동
|
||||
- 자동 스크린샷 테스트
|
||||
- E2E 테스트 자동화
|
||||
- 성능 벤치마크 자동화
|
||||
|
||||
### 다중 환경 지원
|
||||
- Staging 환경 자동 배포
|
||||
- Feature branch 미리보기
|
||||
- A/B 테스트 지원
|
||||
|
||||
---
|
||||
|
||||
이 문서는 Zellyy Finance CI/CD 파이프라인의 완전한 가이드입니다. 추가 질문이나 문제가 있으면 개발팀에 문의하세요.
|
||||
244
docs/ios-signing-setup.md
Normal file
244
docs/ios-signing-setup.md
Normal file
@@ -0,0 +1,244 @@
|
||||
# iOS 코드 서명 설정 가이드
|
||||
|
||||
## 1. Apple Developer 계정 설정
|
||||
|
||||
### 필수 준비사항
|
||||
- Apple Developer Program 계정 (연간 $99)
|
||||
- Xcode 15.0 이상
|
||||
- macOS 빌드 환경
|
||||
|
||||
### App Store Connect 설정
|
||||
1. [App Store Connect](https://appstoreconnect.apple.com) 로그인
|
||||
2. "My Apps" > "+" > "New App" 클릭
|
||||
3. 앱 정보 입력:
|
||||
- Platform: iOS
|
||||
- Name: Zellyy Finance
|
||||
- Primary Language: Korean
|
||||
- Bundle ID: com.zellyy.finance
|
||||
- SKU: zellyy-finance-ios
|
||||
|
||||
## 2. 인증서 및 프로비저닝 프로파일 생성
|
||||
|
||||
### Developer 계정에서 생성 (수동)
|
||||
1. [Apple Developer Portal](https://developer.apple.com/account) 접속
|
||||
2. Certificates, Identifiers & Profiles 섹션으로 이동
|
||||
|
||||
#### 인증서 생성
|
||||
```bash
|
||||
# 1. CSR(Certificate Signing Request) 생성
|
||||
# 키체인 접근 > 인증서 지원 > 인증 기관에서 인증서 요청
|
||||
|
||||
# 2. Apple Developer Portal에서 인증서 생성
|
||||
# - iOS Distribution (App Store and Ad Hoc)
|
||||
# - CSR 파일 업로드
|
||||
# - 생성된 인증서(.cer) 다운로드 및 키체인에 설치
|
||||
```
|
||||
|
||||
#### App ID 생성/확인
|
||||
```
|
||||
- Identifier: com.zellyy.finance
|
||||
- Description: Zellyy Finance
|
||||
- Capabilities: 필요한 기능들 활성화 (Push Notifications 등)
|
||||
```
|
||||
|
||||
#### 프로비저닝 프로파일 생성
|
||||
```
|
||||
- Type: App Store
|
||||
- App ID: com.zellyy.finance
|
||||
- Certificate: 위에서 생성한 Distribution 인증서
|
||||
- Profile Name: Zellyy Finance App Store
|
||||
```
|
||||
|
||||
### API 키를 통한 자동화 (권장)
|
||||
```bash
|
||||
# App Store Connect API 키 생성
|
||||
# App Store Connect > 사용자 및 액세스 > 키 > API 키 > "+" 클릭
|
||||
# - 이름: Zellyy Finance CI/CD
|
||||
# - 액세스: App Manager 또는 Developer
|
||||
# - 키 다운로드 (.p8 파일)
|
||||
```
|
||||
|
||||
## 3. Xcode 프로젝트 설정
|
||||
|
||||
### Team 및 Bundle Identifier 설정
|
||||
```bash
|
||||
# ios/App/App.xcodeproj 열기
|
||||
# 프로젝트 설정 > Signing & Capabilities
|
||||
# - Team: Apple Developer 팀 선택
|
||||
# - Bundle Identifier: com.zellyy.finance
|
||||
# - Signing Certificate: iOS Distribution
|
||||
```
|
||||
|
||||
### 빌드 설정 확인
|
||||
```bash
|
||||
# ios/App/App/Info.plist 확인
|
||||
CFBundleIdentifier: com.zellyy.finance
|
||||
CFBundleDisplayName: Zellyy Finance
|
||||
CFBundleShortVersionString: 1.0.0
|
||||
CFBundleVersion: 10000
|
||||
```
|
||||
|
||||
## 4. GitHub Actions용 인증서 내보내기
|
||||
|
||||
### 인증서를 P12로 내보내기
|
||||
```bash
|
||||
# 키체인 접근에서:
|
||||
# 1. iOS Distribution 인증서 선택
|
||||
# 2. 개인키와 함께 내보내기 선택
|
||||
# 3. .p12 파일로 저장
|
||||
# 4. 내보내기 비밀번호 설정
|
||||
```
|
||||
|
||||
### Base64로 인코딩
|
||||
```bash
|
||||
# P12 파일을 base64로 인코딩
|
||||
base64 -i ios-distribution.p12 | pbcopy
|
||||
# 결과를 IOS_CERTIFICATES_P12_BASE64 시크릿에 저장
|
||||
```
|
||||
|
||||
### 프로비저닝 프로파일 내보내기
|
||||
```bash
|
||||
# ~/Library/MobileDevice/Provisioning Profiles/ 에서 찾거나
|
||||
# Apple Developer Portal에서 다운로드
|
||||
base64 -i ZellyyFinance_AppStore.mobileprovision | pbcopy
|
||||
```
|
||||
|
||||
## 5. GitHub Secrets 설정
|
||||
|
||||
### iOS 관련 시크릿들
|
||||
- `IOS_CERTIFICATES_P12_BASE64`: P12 인증서 파일의 base64 인코딩
|
||||
- `IOS_CERTIFICATES_P12_PASSWORD`: P12 파일 내보내기 시 설정한 비밀번호
|
||||
- `IOS_PROVISIONING_PROFILE_BASE64`: 프로비저닝 프로파일의 base64 인코딩
|
||||
|
||||
### App Store Connect API 시크릿들
|
||||
- `APPSTORE_ISSUER_ID`: App Store Connect API 발급자 ID
|
||||
- `APPSTORE_KEY_ID`: App Store Connect API 키 ID
|
||||
- `APPSTORE_PRIVATE_KEY`: App Store Connect API 개인 키 (.p8 파일 내용)
|
||||
|
||||
## 6. ExportOptions.plist 설정 확인
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>method</key>
|
||||
<string>app-store</string>
|
||||
<key>teamID</key>
|
||||
<string>YOUR_TEAM_ID</string>
|
||||
<key>provisioningProfiles</key>
|
||||
<dict>
|
||||
<key>com.zellyy.finance</key>
|
||||
<string>Zellyy Finance App Store</string>
|
||||
</dict>
|
||||
<key>signingCertificate</key>
|
||||
<string>iPhone Distribution</string>
|
||||
<key>signingStyle</key>
|
||||
<string>manual</string>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
## 7. 로컬 빌드 테스트
|
||||
|
||||
### 릴리즈 빌드 테스트
|
||||
```bash
|
||||
# 웹 앱 빌드
|
||||
npm run build:prod
|
||||
|
||||
# Capacitor 동기화
|
||||
npm run mobile:sync
|
||||
|
||||
# iOS 프로젝트 열기
|
||||
npm run ios:open
|
||||
|
||||
# Xcode에서 Archive 빌드
|
||||
# Product > Archive 선택
|
||||
# Archive 성공 시 Organizer에서 확인
|
||||
```
|
||||
|
||||
### 명령어로 빌드 테스트
|
||||
```bash
|
||||
cd ios/App
|
||||
|
||||
# CocoaPods 의존성 설치
|
||||
pod install
|
||||
|
||||
# 릴리즈 빌드
|
||||
xcodebuild -workspace App.xcworkspace \
|
||||
-scheme App \
|
||||
-configuration Release \
|
||||
-destination 'generic/platform=iOS' \
|
||||
-archivePath App.xcarchive \
|
||||
archive
|
||||
|
||||
# IPA 내보내기
|
||||
xcodebuild -exportArchive \
|
||||
-archivePath App.xcarchive \
|
||||
-exportPath ./build \
|
||||
-exportOptionsPlist ExportOptions.plist
|
||||
```
|
||||
|
||||
## 8. TestFlight 배포 설정
|
||||
|
||||
### 자동 업로드 설정
|
||||
```bash
|
||||
# fastlane 설치 (옵션)
|
||||
gem install fastlane
|
||||
|
||||
# TestFlight 업로드
|
||||
xcrun altool --upload-app \
|
||||
--type ios \
|
||||
--file "App.ipa" \
|
||||
--username "your-apple-id@example.com" \
|
||||
--password "app-specific-password"
|
||||
```
|
||||
|
||||
### GitHub Actions 통합
|
||||
```yaml
|
||||
# .github/workflows/mobile-build.yml에서 사용
|
||||
- name: Upload to TestFlight
|
||||
uses: Apple-Actions/upload-testflight-build@v1
|
||||
with:
|
||||
app-path: ios/App/build/App.ipa
|
||||
issuer-id: ${{ secrets.APPSTORE_ISSUER_ID }}
|
||||
api-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
||||
api-private-key: ${{ secrets.APPSTORE_PRIVATE_KEY }}
|
||||
```
|
||||
|
||||
## 9. 보안 고려사항
|
||||
|
||||
### 인증서 관리
|
||||
- P12 파일 및 프로비저닝 프로파일은 git에 커밋하지 않음
|
||||
- Apple Developer 계정의 2단계 인증 활성화
|
||||
- App Store Connect API 키는 최소 권한으로 설정
|
||||
|
||||
### CI/CD 보안
|
||||
- GitHub Secrets로 모든 민감 정보 보호
|
||||
- 릴리즈 브랜치에서만 서명된 빌드 생성
|
||||
- 빌드 로그에서 민감 정보 노출 방지
|
||||
|
||||
## 10. 문제 해결
|
||||
|
||||
### 일반적인 오류들
|
||||
- `Code signing error`: 인증서 또는 프로비저닝 프로파일 문제
|
||||
- `Bundle ID mismatch`: Bundle Identifier 불일치
|
||||
- `Provisioning profile expired`: 프로비저닝 프로파일 만료
|
||||
- `Team ID not found`: Apple Developer 팀 설정 오류
|
||||
|
||||
### 디버깅 명령어
|
||||
```bash
|
||||
# 코드 서명 정보 확인
|
||||
security find-identity -v -p codesigning
|
||||
|
||||
# 프로비저닝 프로파일 확인
|
||||
ls ~/Library/MobileDevice/Provisioning\ Profiles/
|
||||
|
||||
# Xcode 빌드 로그 확인
|
||||
xcodebuild -workspace App.xcworkspace -scheme App -configuration Release build | xcpretty
|
||||
```
|
||||
|
||||
### 유용한 도구들
|
||||
- [iOS App Signer](https://github.com/DanTheMan827/ios-app-signer): GUI 코드 서명 도구
|
||||
- [fastlane](https://fastlane.tools): iOS 배포 자동화 도구
|
||||
- [xcpretty](https://github.com/xcpretty/xcpretty): Xcode 빌드 로그 포맷터
|
||||
344
docs/linear-github-connection-guide.md
Normal file
344
docs/linear-github-connection-guide.md
Normal file
@@ -0,0 +1,344 @@
|
||||
# Linear GitHub 연동 가이드
|
||||
|
||||
Linear와 GitHub 간의 기본 연결 설정 및 구성 가이드입니다.
|
||||
|
||||
## 📋 목차
|
||||
|
||||
- [개요](#개요)
|
||||
- [사전 요구사항](#사전-요구사항)
|
||||
- [1단계: Linear API 키 생성](#1단계-linear-api-키-생성)
|
||||
- [2단계: GitHub 개인 액세스 토큰 생성](#2단계-github-개인-액세스-토큰-생성)
|
||||
- [3단계: 자동 설정 실행](#3단계-자동-설정-실행)
|
||||
- [4단계: GitHub Secrets 설정](#4단계-github-secrets-설정)
|
||||
- [5단계: Linear 웹훅 설정](#5단계-linear-웹훅-설정)
|
||||
- [6단계: 연동 테스트](#6단계-연동-테스트)
|
||||
- [문제 해결](#문제-해결)
|
||||
|
||||
## 개요
|
||||
|
||||
이 가이드는 Linear 프로젝트 관리 도구와 GitHub 리포지토리 간의 양방향 연동을 설정하는 방법을 설명합니다.
|
||||
|
||||
### 연동 기능
|
||||
|
||||
- **이슈 상태 동기화**: PR 상태에 따른 Linear 이슈 상태 자동 업데이트
|
||||
- **자동 코멘트**: GitHub 이벤트를 Linear 이슈에 자동으로 코멘트
|
||||
- **릴리즈 관리**: semantic-release와 연동된 자동 릴리즈 노트 생성
|
||||
- **워크플로우 자동화**: GitHub Actions를 통한 완전 자동화
|
||||
|
||||
## 사전 요구사항
|
||||
|
||||
### 계정 및 권한
|
||||
|
||||
- **Linear 계정**: 워크스페이스 관리자 권한
|
||||
- **GitHub 계정**: 리포지토리 관리자 권한
|
||||
- **Node.js**: 18.0.0 이상
|
||||
|
||||
### 필수 파일 확인
|
||||
|
||||
다음 파일들이 프로젝트에 존재하는지 확인하세요:
|
||||
|
||||
```bash
|
||||
# 자동 확인
|
||||
npm run linear:setup --verify
|
||||
```
|
||||
|
||||
## 1단계: Linear API 키 생성
|
||||
|
||||
### 1.1 Linear 설정 페이지 접근
|
||||
|
||||
1. Linear 워크스페이스 로그인
|
||||
2. **Settings** → **API** → **Personal API keys** 이동
|
||||
|
||||
### 1.2 API 키 생성
|
||||
|
||||
1. **"Create API key"** 클릭
|
||||
2. 키 이름: `Zellyy Finance GitHub Integration`
|
||||
3. 권한 설정:
|
||||
- **Read**: Issues, Comments, Teams, Projects
|
||||
- **Write**: Issues, Comments (상태 업데이트 및 코멘트 생성용)
|
||||
|
||||
### 1.3 API 키 복사
|
||||
|
||||
- 생성된 API 키를 안전한 곳에 저장
|
||||
- 형식: `lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
|
||||
|
||||
## 2단계: GitHub 개인 액세스 토큰 생성
|
||||
|
||||
### 2.1 GitHub 설정 페이지 접근
|
||||
|
||||
1. GitHub 계정 로그인
|
||||
2. **Settings** → **Developer settings** → **Personal access tokens** → **Tokens (classic)** 이동
|
||||
|
||||
### 2.2 토큰 생성
|
||||
|
||||
1. **"Generate new token"** → **"Generate new token (classic)"** 클릭
|
||||
2. 토큰 이름: `Zellyy Finance Linear Integration`
|
||||
3. 만료 기간: **90 days** (또는 원하는 기간)
|
||||
4. 필수 권한 선택:
|
||||
- **repo**: 전체 리포지토리 액세스
|
||||
- **workflow**: GitHub Actions 워크플로우 관리
|
||||
- **admin:repo_hook**: 웹훅 관리
|
||||
|
||||
### 2.3 토큰 복사
|
||||
|
||||
- 생성된 토큰을 안전한 곳에 저장
|
||||
- 형식: `ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
|
||||
|
||||
## 3단계: 자동 설정 실행
|
||||
|
||||
### 3.1 설정 스크립트 실행
|
||||
|
||||
```bash
|
||||
# Linear API 키와 함께 전체 설정 실행
|
||||
npm run linear:setup -- --setup --linear-api=lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# 또는 직접 실행
|
||||
node scripts/linear-github-setup.cjs --setup --linear-api=lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
### 3.2 설정 결과 확인
|
||||
|
||||
스크립트 실행 후 다음 파일들이 생성/업데이트됩니다:
|
||||
|
||||
- `.env.linear`: 환경 변수 설정 파일
|
||||
- 콘솔에 출력되는 설정 안내 확인
|
||||
|
||||
### 3.3 환경 변수 설정
|
||||
|
||||
생성된 `.env.linear` 파일의 내용을 기존 `.env` 파일에 추가하거나 새로 생성:
|
||||
|
||||
```bash
|
||||
# .env.linear 내용을 .env로 복사
|
||||
cat .env.linear >> .env
|
||||
|
||||
# 또는 .env.linear를 .env로 복사
|
||||
cp .env.linear .env
|
||||
```
|
||||
|
||||
## 4단계: GitHub Secrets 설정
|
||||
|
||||
### 4.1 리포지토리 Secrets 페이지 접근
|
||||
|
||||
1. GitHub 리포지토리 페이지 이동
|
||||
2. **Settings** → **Secrets and variables** → **Actions** 클릭
|
||||
|
||||
### 4.2 필수 Secrets 추가
|
||||
|
||||
**"New repository secret"** 클릭하여 다음 secrets 추가:
|
||||
|
||||
#### 필수 Secret
|
||||
|
||||
- **Name**: `LINEAR_API_KEY`
|
||||
- **Value**: `lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` (1단계에서 생성한 키)
|
||||
|
||||
#### 선택적 Secrets (향후 확장용)
|
||||
|
||||
- **Name**: `SLACK_BOT_TOKEN`
|
||||
- **Value**: `xoxb-your-slack-bot-token` (Slack 연동용)
|
||||
|
||||
- **Name**: `SLACK_WEBHOOK_URL`
|
||||
- **Value**: `https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK` (Slack 알림용)
|
||||
|
||||
### 4.3 Secrets 확인
|
||||
|
||||
Settings → Secrets에서 `LINEAR_API_KEY`가 추가되었는지 확인합니다.
|
||||
|
||||
## 5단계: Linear 웹훅 설정
|
||||
|
||||
### 5.1 Linear 웹훅 페이지 접근
|
||||
|
||||
1. Linear 워크스페이스에서 **Settings** → **API** → **Webhooks** 이동
|
||||
2. **"Create webhook"** 클릭
|
||||
|
||||
### 5.2 웹훅 구성
|
||||
|
||||
#### 기본 설정
|
||||
- **Label**: `GitHub Integration - Zellyy Finance`
|
||||
- **URL**: `https://api.github.com/repos/zellycloud/zellyy-finance/dispatches`
|
||||
|
||||
#### Resource Types 선택
|
||||
다음 이벤트 타입들을 선택:
|
||||
- ✅ **Issue** (이슈 생성, 업데이트, 상태 변경)
|
||||
- ✅ **Comment** (코멘트 생성, 업데이트)
|
||||
- ✅ **IssueLabel** (레이블 변경)
|
||||
|
||||
#### 팀 선택
|
||||
- **Team**: `Zellyy` 선택 (또는 모든 팀)
|
||||
|
||||
### 5.3 웹훅 활성화
|
||||
|
||||
- **Enabled** 체크박스 확인
|
||||
- **"Create webhook"** 클릭
|
||||
|
||||
## 6단계: 연동 테스트
|
||||
|
||||
### 6.1 테스트 브랜치 생성
|
||||
|
||||
```bash
|
||||
# 새 브랜치 생성
|
||||
git checkout -b feature/test-linear-integration
|
||||
|
||||
# 테스트 파일 생성
|
||||
echo "# Linear Integration Test" > test-linear.md
|
||||
git add test-linear.md
|
||||
```
|
||||
|
||||
### 6.2 Linear 이슈 ID가 포함된 커밋
|
||||
|
||||
```bash
|
||||
# Linear 이슈 ID를 포함한 커밋 메시지
|
||||
git commit -m "feat: test Linear integration [ZEL-1]"
|
||||
|
||||
# 브랜치 푸시
|
||||
git push origin feature/test-linear-integration
|
||||
```
|
||||
|
||||
### 6.3 Pull Request 생성
|
||||
|
||||
1. GitHub에서 Pull Request 생성
|
||||
2. **제목**: `Test Linear integration (ZEL-1)`
|
||||
3. **설명**에 다음 내용 포함:
|
||||
```markdown
|
||||
## Linear 이슈
|
||||
Closes ZEL-1
|
||||
|
||||
## 변경 내용
|
||||
Linear GitHub 연동 테스트를 위한 Pull Request입니다.
|
||||
```
|
||||
|
||||
### 6.4 연동 동작 확인
|
||||
|
||||
#### GitHub Actions 확인
|
||||
1. **Actions** 탭에서 워크플로우 실행 확인
|
||||
2. `Linear Integration` 워크플로우가 성공적으로 실행되는지 확인
|
||||
3. 로그에서 Linear API 호출 결과 확인
|
||||
|
||||
#### Linear 이슈 확인
|
||||
1. Linear에서 ZEL-1 이슈 확인
|
||||
2. 자동으로 추가된 코멘트 확인:
|
||||
```
|
||||
🔗 Pull Request 생성
|
||||
|
||||
URL: https://github.com/zellycloud/zellyy-finance/pull/XXX
|
||||
작성자: @username
|
||||
```
|
||||
|
||||
### 6.5 전체 플로우 테스트
|
||||
|
||||
```bash
|
||||
# 통합 테스트 실행
|
||||
npm run linear:test -- --api-key=lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
|
||||
# 설정 검증
|
||||
npm run linear:setup -- --verify --linear-api=lin_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
## 설정 완료 확인
|
||||
|
||||
### ✅ 체크리스트
|
||||
|
||||
- [ ] Linear API 키 생성 및 설정
|
||||
- [ ] GitHub 개인 액세스 토큰 생성 (선택사항)
|
||||
- [ ] 자동 설정 스크립트 실행 성공
|
||||
- [ ] GitHub Secrets에 `LINEAR_API_KEY` 추가
|
||||
- [ ] Linear 웹훅 설정 완료
|
||||
- [ ] 테스트 Pull Request 생성
|
||||
- [ ] GitHub Actions 워크플로우 실행 성공
|
||||
- [ ] Linear 이슈에 자동 코멘트 생성 확인
|
||||
- [ ] 통합 테스트 모두 통과
|
||||
|
||||
### 🎉 성공 시 기대 결과
|
||||
|
||||
1. **Pull Request 생성 시**: Linear 이슈에 PR 링크 코멘트 자동 추가
|
||||
2. **Pull Request 병합 시**: Linear 이슈 상태 자동 변경 (Done)
|
||||
3. **코드 리뷰 시**: Linear 이슈에 리뷰 상태 코멘트 추가
|
||||
4. **릴리즈 시**: Linear 이슈들을 포함한 릴리즈 노트 자동 생성
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### 자주 발생하는 문제들
|
||||
|
||||
#### 1. Linear API 연결 실패
|
||||
|
||||
**증상**: `Linear API Error: Unauthorized`
|
||||
|
||||
**해결 방법**:
|
||||
```bash
|
||||
# API 키 확인
|
||||
npm run linear:test -- --api-key=your-api-key
|
||||
|
||||
# 권한 확인
|
||||
# Linear Settings → API → Personal API keys에서 키 권한 재확인
|
||||
```
|
||||
|
||||
#### 2. GitHub Actions 실행 실패
|
||||
|
||||
**증상**: Workflow에서 `LINEAR_API_KEY` 오류
|
||||
|
||||
**해결 방법**:
|
||||
1. GitHub 리포지토리 Settings → Secrets 확인
|
||||
2. `LINEAR_API_KEY` Secret이 올바르게 설정되었는지 확인
|
||||
3. Secret 값에 공백이나 특수문자가 없는지 확인
|
||||
|
||||
#### 3. 웹훅 이벤트 수신 실패
|
||||
|
||||
**증상**: Linear 이벤트가 GitHub으로 전달되지 않음
|
||||
|
||||
**해결 방법**:
|
||||
1. Linear Webhooks 설정에서 URL 확인:
|
||||
```
|
||||
https://api.github.com/repos/zellycloud/zellyy-finance/dispatches
|
||||
```
|
||||
2. Resource Types가 올바르게 선택되었는지 확인
|
||||
3. 웹훅이 활성화(Enabled)되어 있는지 확인
|
||||
|
||||
#### 4. 이슈 ID 추출 실패
|
||||
|
||||
**증상**: PR이나 커밋에서 Linear 이슈 ID를 찾지 못함
|
||||
|
||||
**해결 방법**:
|
||||
- 올바른 형식 사용:
|
||||
```bash
|
||||
# 커밋 메시지
|
||||
git commit -m "feat: new feature [ZEL-123]"
|
||||
git commit -m "fix: bug fix (Fixes ZEL-456)"
|
||||
|
||||
# PR 제목
|
||||
"Add new feature (ZEL-123)"
|
||||
"Fix critical bug [ZEL-456]"
|
||||
|
||||
# PR 설명
|
||||
Closes ZEL-123
|
||||
Related to ZEL-456
|
||||
```
|
||||
|
||||
### 로그 확인 방법
|
||||
|
||||
#### GitHub Actions 로그
|
||||
1. GitHub 리포지토리 → **Actions** 탭
|
||||
2. 해당 워크플로우 실행 클릭
|
||||
3. 각 단계별 로그 확인
|
||||
|
||||
#### Linear API 응답 확인
|
||||
```bash
|
||||
# 디버그 모드로 테스트 실행
|
||||
DEBUG=true npm run linear:test -- --api-key=your-api-key
|
||||
```
|
||||
|
||||
### 추가 도움이 필요한 경우
|
||||
|
||||
1. **Linear 지원**: [Linear Support](https://linear.app/contact)
|
||||
2. **GitHub Actions 문서**: [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
||||
3. **프로젝트 이슈**: GitHub 이슈로 문의
|
||||
|
||||
---
|
||||
|
||||
## 다음 단계
|
||||
|
||||
Linear GitHub 기본 연동이 완료되면 다음 고급 기능들을 설정할 수 있습니다:
|
||||
|
||||
- **Slack 연동**: 팀 협업 알림 자동화
|
||||
- **릴리즈 자동화**: semantic-release와 완전 연동
|
||||
- **프로젝트 대시보드**: 자동화된 리포팅 시스템
|
||||
|
||||
각 기능별 상세 가이드는 별도 문서에서 제공됩니다.
|
||||
692
docs/linear-integration-guide.md
Normal file
692
docs/linear-integration-guide.md
Normal file
@@ -0,0 +1,692 @@
|
||||
# Linear 프로젝트 관리 도구 연동 가이드
|
||||
|
||||
## 개요
|
||||
|
||||
이 가이드는 Zellyy Finance 프로젝트에 Linear.app 프로젝트 관리 도구를 완전히 연동하는 방법을 설명합니다. Linear와 GitHub의 양방향 동기화, 자동화된 워크플로우, 실시간 리포팅 시스템 구축을 다룹니다.
|
||||
|
||||
## 목차
|
||||
|
||||
1. [Linear 계정 및 프로젝트 설정](#1-linear-계정-및-프로젝트-설정)
|
||||
2. [GitHub 연동 설정](#2-github-연동-설정)
|
||||
3. [워크플로우 자동화](#3-워크플로우-자동화)
|
||||
4. [릴리즈 관리 시스템](#4-릴리즈-관리-시스템)
|
||||
5. [팀 협업 도구](#5-팀-협업-도구)
|
||||
6. [리포팅 대시보드](#6-리포팅-대시보드)
|
||||
|
||||
## 1. Linear 계정 및 프로젝트 설정
|
||||
|
||||
### 1.1 Linear 워크스페이스 생성
|
||||
|
||||
1. [Linear.app](https://linear.app) 접속
|
||||
2. "Create workspace" 클릭
|
||||
3. 워크스페이스 정보 입력:
|
||||
- Workspace name: `Zellyy Finance`
|
||||
- URL: `zellyy-finance`
|
||||
- Plan: Professional (권장)
|
||||
|
||||
### 1.2 프로젝트 구조 설정
|
||||
|
||||
```yaml
|
||||
# 프로젝트 구조
|
||||
Zellyy Finance/
|
||||
├── Teams/
|
||||
│ ├── Frontend
|
||||
│ ├── Backend
|
||||
│ └── DevOps
|
||||
├── Projects/
|
||||
│ ├── Web App
|
||||
│ ├── Mobile App
|
||||
│ └── Infrastructure
|
||||
└── Roadmap/
|
||||
├── Q1 2025
|
||||
├── Q2 2025
|
||||
└── Q3 2025
|
||||
```
|
||||
|
||||
### 1.3 이슈 타입 및 라벨 체계
|
||||
|
||||
#### 이슈 타입
|
||||
- **Epic**: 대규모 기능 그룹
|
||||
- **Feature**: 새로운 기능
|
||||
- **Bug**: 버그 수정
|
||||
- **Task**: 일반 작업
|
||||
- **Improvement**: 개선 사항
|
||||
|
||||
#### 라벨 체계
|
||||
```yaml
|
||||
Priority:
|
||||
- P0: Critical
|
||||
- P1: High
|
||||
- P2: Medium
|
||||
- P3: Low
|
||||
|
||||
Type:
|
||||
- frontend
|
||||
- backend
|
||||
- mobile
|
||||
- devops
|
||||
- security
|
||||
- performance
|
||||
|
||||
Status:
|
||||
- backlog
|
||||
- todo
|
||||
- in-progress
|
||||
- review
|
||||
- done
|
||||
- cancelled
|
||||
```
|
||||
|
||||
### 1.4 워크플로우 상태 정의
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Backlog] --> B[Todo]
|
||||
B --> C[In Progress]
|
||||
C --> D[In Review]
|
||||
D --> E[Done]
|
||||
C --> F[Blocked]
|
||||
F --> C
|
||||
B --> G[Cancelled]
|
||||
```
|
||||
|
||||
## 2. GitHub 연동 설정
|
||||
|
||||
### 2.1 Linear GitHub 앱 설치
|
||||
|
||||
1. Linear 설정 → Integrations → GitHub
|
||||
2. "Install GitHub App" 클릭
|
||||
3. 권한 승인:
|
||||
- Repository access: `zellyy-finance`
|
||||
- Permissions: Read & Write
|
||||
|
||||
### 2.2 브랜치 명명 규칙
|
||||
|
||||
```bash
|
||||
# Linear 이슈 ID 기반 브랜치명
|
||||
feature/ZEL-123-user-authentication
|
||||
bugfix/ZEL-456-login-error
|
||||
task/ZEL-789-update-dependencies
|
||||
```
|
||||
|
||||
### 2.3 커밋 메시지 규칙
|
||||
|
||||
```bash
|
||||
# Linear 이슈 자동 연결
|
||||
git commit -m "feat: implement user authentication [ZEL-123]"
|
||||
git commit -m "fix: resolve login error (Fixes ZEL-456)"
|
||||
git commit -m "chore: update dependencies - ZEL-789"
|
||||
```
|
||||
|
||||
### 2.4 PR 템플릿 설정
|
||||
|
||||
`.github/pull_request_template.md`:
|
||||
```markdown
|
||||
## 개요
|
||||
<!-- PR 설명 -->
|
||||
|
||||
## Linear 이슈
|
||||
Closes ZEL-XXX
|
||||
|
||||
## 변경 사항
|
||||
- [ ] 기능 A 구현
|
||||
- [ ] 버그 B 수정
|
||||
- [ ] 테스트 추가
|
||||
|
||||
## 테스트
|
||||
- [ ] 유닛 테스트 통과
|
||||
- [ ] E2E 테스트 통과
|
||||
- [ ] 수동 테스트 완료
|
||||
|
||||
## 스크린샷
|
||||
<!-- 필요시 스크린샷 첨부 -->
|
||||
```
|
||||
|
||||
## 3. 워크플로우 자동화
|
||||
|
||||
### 3.1 Linear API 설정
|
||||
|
||||
1. Linear Settings → API → Personal API keys
|
||||
2. "Create key" 클릭
|
||||
3. Key name: `zellyy-finance-automation`
|
||||
4. 생성된 키를 GitHub Secrets에 저장:
|
||||
```bash
|
||||
LINEAR_API_KEY=lin_api_xxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
### 3.2 GitHub Actions 워크플로우
|
||||
|
||||
`.github/workflows/linear-integration.yml`:
|
||||
```yaml
|
||||
name: Linear Integration
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, closed, ready_for_review]
|
||||
issues:
|
||||
types: [opened, closed]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
env:
|
||||
LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }}
|
||||
|
||||
jobs:
|
||||
sync-linear:
|
||||
name: Sync with Linear
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '18'
|
||||
|
||||
- name: Extract Linear Issue ID
|
||||
id: linear-issue
|
||||
run: |
|
||||
# PR 제목/본문에서 Linear 이슈 ID 추출
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
ISSUE_ID=$(echo "${{ github.event.pull_request.title }} ${{ github.event.pull_request.body }}" | grep -oE 'ZEL-[0-9]+' | head -1)
|
||||
fi
|
||||
echo "issue_id=$ISSUE_ID" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Update Linear Issue Status
|
||||
if: steps.linear-issue.outputs.issue_id
|
||||
run: |
|
||||
node scripts/linear-sync.js \
|
||||
--issue-id="${{ steps.linear-issue.outputs.issue_id }}" \
|
||||
--event="${{ github.event_name }}" \
|
||||
--action="${{ github.event.action }}"
|
||||
|
||||
- name: Create Linear Comment
|
||||
if: github.event_name == 'pull_request' && github.event.action == 'opened'
|
||||
run: |
|
||||
node scripts/linear-comment.js \
|
||||
--issue-id="${{ steps.linear-issue.outputs.issue_id }}" \
|
||||
--pr-url="${{ github.event.pull_request.html_url }}" \
|
||||
--pr-author="${{ github.event.pull_request.user.login }}"
|
||||
```
|
||||
|
||||
### 3.3 Linear 동기화 스크립트
|
||||
|
||||
`scripts/linear-sync.js`:
|
||||
```javascript
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { LinearClient } = require('@linear/sdk');
|
||||
const { program } = require('commander');
|
||||
|
||||
// Linear 클라이언트 초기화
|
||||
const linear = new LinearClient({
|
||||
apiKey: process.env.LINEAR_API_KEY
|
||||
});
|
||||
|
||||
program
|
||||
.option('--issue-id <id>', 'Linear issue ID')
|
||||
.option('--event <event>', 'GitHub event type')
|
||||
.option('--action <action>', 'GitHub action type')
|
||||
.parse();
|
||||
|
||||
const options = program.opts();
|
||||
|
||||
async function updateIssueStatus() {
|
||||
try {
|
||||
// 이슈 조회
|
||||
const issue = await linear.issue(options.issueId);
|
||||
|
||||
if (!issue) {
|
||||
console.error(`Issue ${options.issueId} not found`);
|
||||
return;
|
||||
}
|
||||
|
||||
let stateId;
|
||||
|
||||
// 이벤트에 따른 상태 결정
|
||||
if (options.event === 'pull_request') {
|
||||
switch (options.action) {
|
||||
case 'opened':
|
||||
stateId = await getStateId('In Progress');
|
||||
break;
|
||||
case 'ready_for_review':
|
||||
stateId = await getStateId('In Review');
|
||||
break;
|
||||
case 'closed':
|
||||
if (process.env.GITHUB_PR_MERGED === 'true') {
|
||||
stateId = await getStateId('Done');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 상태 업데이트
|
||||
if (stateId) {
|
||||
await issue.update({ stateId });
|
||||
console.log(`Updated ${options.issueId} status`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to update Linear issue:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
async function getStateId(stateName) {
|
||||
const states = await linear.workflowStates();
|
||||
const state = states.nodes.find(s => s.name === stateName);
|
||||
return state?.id;
|
||||
}
|
||||
|
||||
updateIssueStatus();
|
||||
```
|
||||
|
||||
## 4. 릴리즈 관리 시스템
|
||||
|
||||
### 4.1 Semantic Release 연동
|
||||
|
||||
`.releaserc.json` 업데이트:
|
||||
```json
|
||||
{
|
||||
"branches": ["main"],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
[
|
||||
"@semantic-release/exec",
|
||||
{
|
||||
"prepareCmd": "node scripts/linear-release-prep.js ${nextRelease.version}",
|
||||
"successCmd": "node scripts/linear-release-complete.js ${nextRelease.version}"
|
||||
}
|
||||
],
|
||||
"@semantic-release/changelog",
|
||||
"@semantic-release/npm",
|
||||
"@semantic-release/github",
|
||||
"@semantic-release/git"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 릴리즈 준비 스크립트
|
||||
|
||||
`scripts/linear-release-prep.js`:
|
||||
```javascript
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { LinearClient } = require('@linear/sdk');
|
||||
const fs = require('fs');
|
||||
|
||||
const linear = new LinearClient({
|
||||
apiKey: process.env.LINEAR_API_KEY
|
||||
});
|
||||
|
||||
const version = process.argv[2];
|
||||
|
||||
async function prepareRelease() {
|
||||
try {
|
||||
// 완료된 이슈 조회
|
||||
const issues = await linear.issues({
|
||||
filter: {
|
||||
state: { name: { eq: "Done" } },
|
||||
project: { name: { eq: "Zellyy Finance" } }
|
||||
}
|
||||
});
|
||||
|
||||
// 릴리즈 노트 생성
|
||||
const releaseNotes = {
|
||||
version,
|
||||
date: new Date().toISOString(),
|
||||
issues: issues.nodes.map(issue => ({
|
||||
id: issue.identifier,
|
||||
title: issue.title,
|
||||
type: issue.labels.nodes[0]?.name || 'task',
|
||||
url: issue.url
|
||||
}))
|
||||
};
|
||||
|
||||
// 릴리즈 노트 파일 저장
|
||||
fs.writeFileSync(
|
||||
`releases/v${version}.json`,
|
||||
JSON.stringify(releaseNotes, null, 2)
|
||||
);
|
||||
|
||||
console.log(`Prepared release notes for v${version}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to prepare release:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
prepareRelease();
|
||||
```
|
||||
|
||||
## 5. 팀 협업 도구
|
||||
|
||||
### 5.1 Slack 연동 설정
|
||||
|
||||
1. Linear Settings → Integrations → Slack
|
||||
2. "Connect Slack" 클릭
|
||||
3. 채널 매핑:
|
||||
- `#dev-frontend` → Frontend team
|
||||
- `#dev-backend` → Backend team
|
||||
- `#dev-mobile` → Mobile team
|
||||
|
||||
### 5.2 Slack 알림 규칙
|
||||
|
||||
```yaml
|
||||
알림 트리거:
|
||||
- 이슈 생성: 담당 팀 채널
|
||||
- 이슈 할당: 담당자 DM
|
||||
- 상태 변경: 관련 채널
|
||||
- 코멘트 추가: 멘션된 사용자
|
||||
- 우선순위 변경: P0/P1만 전체 알림
|
||||
```
|
||||
|
||||
### 5.3 일일 스탠드업 자동화
|
||||
|
||||
`scripts/daily-standup.js`:
|
||||
```javascript
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { LinearClient } = require('@linear/sdk');
|
||||
const { WebClient } = require('@slack/web-api');
|
||||
|
||||
const linear = new LinearClient({
|
||||
apiKey: process.env.LINEAR_API_KEY
|
||||
});
|
||||
|
||||
const slack = new WebClient(process.env.SLACK_BOT_TOKEN);
|
||||
|
||||
async function generateStandup() {
|
||||
const teams = ['Frontend', 'Backend', 'Mobile'];
|
||||
|
||||
for (const team of teams) {
|
||||
// 어제 완료된 이슈
|
||||
const completed = await getIssues(team, 'Done', 1);
|
||||
|
||||
// 오늘 진행중인 이슈
|
||||
const inProgress = await getIssues(team, 'In Progress');
|
||||
|
||||
// 블로커
|
||||
const blocked = await getIssues(team, 'Blocked');
|
||||
|
||||
const message = formatStandupMessage(team, {
|
||||
completed,
|
||||
inProgress,
|
||||
blocked
|
||||
});
|
||||
|
||||
await postToSlack(team, message);
|
||||
}
|
||||
}
|
||||
|
||||
async function getIssues(team, state, daysAgo = 0) {
|
||||
const filter = {
|
||||
team: { name: { eq: team } },
|
||||
state: { name: { eq: state } }
|
||||
};
|
||||
|
||||
if (daysAgo > 0) {
|
||||
const date = new Date();
|
||||
date.setDate(date.getDate() - daysAgo);
|
||||
filter.updatedAt = { gte: date.toISOString() };
|
||||
}
|
||||
|
||||
const issues = await linear.issues({ filter });
|
||||
return issues.nodes;
|
||||
}
|
||||
|
||||
function formatStandupMessage(team, data) {
|
||||
return {
|
||||
blocks: [
|
||||
{
|
||||
type: "header",
|
||||
text: {
|
||||
type: "plain_text",
|
||||
text: `${team} Team 일일 스탠드업 📋`
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: `*어제 완료* ✅\n${formatIssues(data.completed)}`
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: `*오늘 진행* 🚀\n${formatIssues(data.inProgress)}`
|
||||
}
|
||||
},
|
||||
{
|
||||
type: "section",
|
||||
text: {
|
||||
type: "mrkdwn",
|
||||
text: `*블로커* 🚨\n${formatIssues(data.blocked)}`
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
// 매일 오전 9시 실행
|
||||
generateStandup();
|
||||
```
|
||||
|
||||
## 6. 리포팅 대시보드
|
||||
|
||||
### 6.1 프로젝트 메트릭 수집
|
||||
|
||||
`scripts/linear-metrics.js`:
|
||||
```javascript
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { LinearClient } = require('@linear/sdk');
|
||||
const fs = require('fs');
|
||||
|
||||
const linear = new LinearClient({
|
||||
apiKey: process.env.LINEAR_API_KEY
|
||||
});
|
||||
|
||||
async function collectMetrics() {
|
||||
const metrics = {
|
||||
timestamp: new Date().toISOString(),
|
||||
teams: {},
|
||||
overall: {
|
||||
totalIssues: 0,
|
||||
completedIssues: 0,
|
||||
averageLeadTime: 0,
|
||||
velocity: 0
|
||||
}
|
||||
};
|
||||
|
||||
// 팀별 메트릭 수집
|
||||
const teams = await linear.teams();
|
||||
|
||||
for (const team of teams.nodes) {
|
||||
const teamMetrics = await getTeamMetrics(team.id);
|
||||
metrics.teams[team.name] = teamMetrics;
|
||||
|
||||
// 전체 메트릭 집계
|
||||
metrics.overall.totalIssues += teamMetrics.totalIssues;
|
||||
metrics.overall.completedIssues += teamMetrics.completedIssues;
|
||||
}
|
||||
|
||||
// 메트릭 저장
|
||||
const filename = `metrics/linear-${new Date().toISOString().split('T')[0]}.json`;
|
||||
fs.writeFileSync(filename, JSON.stringify(metrics, null, 2));
|
||||
|
||||
return metrics;
|
||||
}
|
||||
|
||||
async function getTeamMetrics(teamId) {
|
||||
// 이번 주 이슈들
|
||||
const weekStart = new Date();
|
||||
weekStart.setDate(weekStart.getDate() - 7);
|
||||
|
||||
const issues = await linear.issues({
|
||||
filter: {
|
||||
team: { id: { eq: teamId } },
|
||||
createdAt: { gte: weekStart.toISOString() }
|
||||
}
|
||||
});
|
||||
|
||||
const completed = issues.nodes.filter(i => i.state.name === 'Done');
|
||||
const leadTimes = completed.map(i => calculateLeadTime(i));
|
||||
|
||||
return {
|
||||
totalIssues: issues.nodes.length,
|
||||
completedIssues: completed.length,
|
||||
averageLeadTime: average(leadTimes),
|
||||
byPriority: groupByPriority(issues.nodes),
|
||||
byType: groupByType(issues.nodes)
|
||||
};
|
||||
}
|
||||
|
||||
function calculateLeadTime(issue) {
|
||||
const created = new Date(issue.createdAt);
|
||||
const completed = new Date(issue.completedAt);
|
||||
return (completed - created) / (1000 * 60 * 60); // hours
|
||||
}
|
||||
|
||||
collectMetrics();
|
||||
```
|
||||
|
||||
### 6.2 React 대시보드 컴포넌트
|
||||
|
||||
`src/components/linear/Dashboard.tsx`:
|
||||
```typescript
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { BarChart, LineChart, PieChart } from 'recharts';
|
||||
import { useLinearMetrics } from '@/hooks/useLinearMetrics';
|
||||
|
||||
export function LinearDashboard() {
|
||||
const { metrics, loading, error } = useLinearMetrics();
|
||||
|
||||
if (loading) return <div>Loading metrics...</div>;
|
||||
if (error) return <div>Error loading metrics</div>;
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{/* 완료율 카드 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>완료율</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold">
|
||||
{((metrics.overall.completedIssues / metrics.overall.totalIssues) * 100).toFixed(1)}%
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{metrics.overall.completedIssues} / {metrics.overall.totalIssues} 이슈
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 평균 리드타임 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>평균 리드타임</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-3xl font-bold">
|
||||
{metrics.overall.averageLeadTime.toFixed(1)}h
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
생성에서 완료까지
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 팀별 진행률 차트 */}
|
||||
<Card className="col-span-full">
|
||||
<CardHeader>
|
||||
<CardTitle>팀별 진행률</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<TeamProgressChart data={metrics.teams} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 번다운 차트 */}
|
||||
<Card className="col-span-2">
|
||||
<CardHeader>
|
||||
<CardTitle>스프린트 번다운</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<BurndownChart data={metrics.burndown} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* 이슈 타입별 분포 */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>이슈 타입 분포</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<IssueTypeChart data={metrics.issueTypes} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 설정 체크리스트
|
||||
|
||||
### 초기 설정
|
||||
- [ ] Linear 워크스페이스 생성
|
||||
- [ ] 팀 및 프로젝트 구조 설정
|
||||
- [ ] 라벨 및 워크플로우 정의
|
||||
- [ ] GitHub 앱 연동
|
||||
|
||||
### 자동화 구축
|
||||
- [ ] Linear API 키 생성
|
||||
- [ ] GitHub Actions 워크플로우 구현
|
||||
- [ ] 동기화 스크립트 배포
|
||||
- [ ] 릴리즈 자동화 설정
|
||||
|
||||
### 팀 협업
|
||||
- [ ] Slack 연동 설정
|
||||
- [ ] 알림 규칙 구성
|
||||
- [ ] 일일 스탠드업 자동화
|
||||
- [ ] 팀 템플릿 생성
|
||||
|
||||
### 리포팅
|
||||
- [ ] 메트릭 수집 스케줄러 설정
|
||||
- [ ] 대시보드 컴포넌트 구현
|
||||
- [ ] 리포트 자동 생성 설정
|
||||
- [ ] 데이터 시각화 구현
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### Linear API 연결 실패
|
||||
```bash
|
||||
# API 키 확인
|
||||
echo $LINEAR_API_KEY
|
||||
|
||||
# 권한 확인
|
||||
curl -H "Authorization: $LINEAR_API_KEY" \
|
||||
https://api.linear.app/graphql \
|
||||
-d '{"query":"{ viewer { id email }}"}'
|
||||
```
|
||||
|
||||
### GitHub 동기화 문제
|
||||
- GitHub 앱 권한 재확인
|
||||
- Webhook 전송 로그 확인
|
||||
- Linear 이슈 ID 형식 검증
|
||||
|
||||
### Slack 알림 미작동
|
||||
- Slack 봇 토큰 유효성 확인
|
||||
- 채널 권한 설정 확인
|
||||
- 알림 필터 규칙 검토
|
||||
|
||||
---
|
||||
|
||||
이 가이드는 Zellyy Finance 프로젝트의 Linear 통합을 위한 완전한 참조 문서입니다.
|
||||
494
docs/semantic-release-linear-guide.md
Normal file
494
docs/semantic-release-linear-guide.md
Normal file
@@ -0,0 +1,494 @@
|
||||
# Semantic Release Linear 연동 가이드
|
||||
|
||||
이 가이드는 semantic-release와 Linear 프로젝트 관리 도구 간의 완전한 연동 시스템에 대해 설명합니다.
|
||||
|
||||
## 📋 목차
|
||||
|
||||
- [개요](#개요)
|
||||
- [핵심 기능](#핵심-기능)
|
||||
- [릴리즈 플로우](#릴리즈-플로우)
|
||||
- [커밋 컨벤션](#커밋-컨벤션)
|
||||
- [릴리즈 노트 생성](#릴리즈-노트-생성)
|
||||
- [Linear 이슈 관리](#linear-이슈-관리)
|
||||
- [자동화 워크플로우](#자동화-워크플로우)
|
||||
- [사용 방법](#사용-방법)
|
||||
- [문제 해결](#문제-해결)
|
||||
|
||||
## 개요
|
||||
|
||||
Zellyy Finance의 semantic-release는 Linear 이슈 추적 시스템과 완전히 통합되어 있습니다. 이를 통해:
|
||||
|
||||
- 커밋 메시지의 Linear 이슈 ID를 자동으로 추적
|
||||
- Linear 이슈를 기반으로 한 상세한 릴리즈 노트 생성
|
||||
- 릴리즈 완료 시 관련 Linear 이슈에 자동 알림
|
||||
- 이슈별 담당자 및 카테고리 정보를 포함한 체계적인 릴리즈 관리
|
||||
|
||||
## 핵심 기능
|
||||
|
||||
### 1. 자동 Linear 이슈 추출
|
||||
|
||||
마지막 릴리즈 이후의 모든 커밋에서 Linear 이슈 ID를 자동으로 추출합니다.
|
||||
|
||||
```bash
|
||||
# 지원되는 이슈 ID 형식
|
||||
ZEL-123, ZEL-456, ZEL-789
|
||||
```
|
||||
|
||||
### 2. 이슈 기반 릴리즈 노트
|
||||
|
||||
Linear 이슈 정보를 기반으로 상세한 릴리즈 노트를 자동 생성합니다.
|
||||
|
||||
```markdown
|
||||
# Release 1.2.0
|
||||
|
||||
이번 릴리즈에는 5개의 Linear 이슈가 포함되었습니다.
|
||||
|
||||
## ✨ New Features
|
||||
- **ZEL-123**: 사용자 인증 시스템 구현
|
||||
- Assignee: Hansoo Ha
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
- **ZEL-124**: 로그인 오류 수정
|
||||
- Assignee: Developer Name
|
||||
|
||||
## 🔗 Linear Issues
|
||||
- [ZEL-123](https://linear.app/zellyy/issue/ZEL-123) - 사용자 인증 시스템 구현
|
||||
- [ZEL-124](https://linear.app/zellyy/issue/ZEL-124) - 로그인 오류 수정
|
||||
```
|
||||
|
||||
### 3. 자동 이슈 알림
|
||||
|
||||
릴리즈 완료 시 포함된 모든 Linear 이슈에 자동으로 릴리즈 알림 코멘트를 추가합니다.
|
||||
|
||||
### 4. 메타데이터 추적
|
||||
|
||||
각 릴리즈의 상세 정보를 `releases/` 디렉토리에 JSON 형태로 저장합니다.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.2.0",
|
||||
"releasedAt": "2024-01-15T10:30:00.000Z",
|
||||
"issueCount": 5,
|
||||
"categories": {
|
||||
"features": 2,
|
||||
"bugfixes": 2,
|
||||
"improvements": 1,
|
||||
"other": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 릴리즈 플로우
|
||||
|
||||
### 1. 자동 릴리즈 (메인 브랜치)
|
||||
|
||||
```bash
|
||||
# main 브랜치에 푸시하면 자동으로 릴리즈 검토
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**릴리즈 플로우:**
|
||||
1. **Quality Checks**: 타입 체크, 린트, 테스트 실행
|
||||
2. **Build Verification**: 웹 및 모바일 빌드 검증
|
||||
3. **Linear Validation**: 커밋의 Linear 이슈 검증
|
||||
4. **Semantic Release**: 버전 결정 및 릴리즈 생성
|
||||
5. **Linear Integration**: Linear 이슈에 릴리즈 알림
|
||||
6. **Deployment Notification**: 배포 완료 알림
|
||||
|
||||
### 2. 수동 릴리즈
|
||||
|
||||
```bash
|
||||
# GitHub Actions에서 수동 트리거
|
||||
# Actions → Release → Run workflow
|
||||
# Release type: auto/patch/minor/major 선택
|
||||
```
|
||||
|
||||
### 3. 로컬 테스트
|
||||
|
||||
```bash
|
||||
# 드라이 런 (실제 릴리즈 없이 테스트)
|
||||
npm run release:dry-run
|
||||
|
||||
# Linear 플러그인 테스트
|
||||
npm run release:test
|
||||
```
|
||||
|
||||
## 커밋 컨벤션
|
||||
|
||||
### 기본 형식
|
||||
|
||||
```bash
|
||||
<type>(<scope>): <description> [Linear-Issue-ID]
|
||||
|
||||
[optional body]
|
||||
|
||||
[optional footer(s)]
|
||||
```
|
||||
|
||||
### 예시
|
||||
|
||||
```bash
|
||||
# 새 기능 (Minor 버전 증가)
|
||||
feat: implement user authentication [ZEL-123]
|
||||
feat(auth): add OAuth integration [ZEL-124]
|
||||
|
||||
# 버그 수정 (Patch 버전 증가)
|
||||
fix: resolve login error [ZEL-125]
|
||||
fix(auth): handle invalid token properly [ZEL-126]
|
||||
|
||||
# 성능 개선 (Patch 버전 증가)
|
||||
perf: optimize database queries [ZEL-127]
|
||||
|
||||
# Breaking Change (Major 버전 증가)
|
||||
feat!: redesign API endpoints [ZEL-128]
|
||||
|
||||
BREAKING CHANGE: API endpoints now use v2 format
|
||||
```
|
||||
|
||||
### 지원되는 타입
|
||||
|
||||
- **feat**: 새로운 기능 (minor)
|
||||
- **fix**: 버그 수정 (patch)
|
||||
- **perf**: 성능 개선 (patch)
|
||||
- **docs**: 문서 변경 (patch)
|
||||
- **refactor**: 코드 리팩토링 (patch)
|
||||
- **test**: 테스트 관련 (no release)
|
||||
- **build**: 빌드 시스템 (no release)
|
||||
- **ci**: CI 설정 (no release)
|
||||
- **chore**: 기타 작업 (no release)
|
||||
|
||||
### Linear 이슈 ID 형식
|
||||
|
||||
```bash
|
||||
# 대괄호 안에 이슈 ID (권장)
|
||||
feat: new feature [ZEL-123]
|
||||
|
||||
# 괄호 안에 이슈 ID
|
||||
fix: bug fix (ZEL-124)
|
||||
|
||||
# Closes 키워드 사용
|
||||
feat: new feature
|
||||
|
||||
Closes ZEL-125
|
||||
```
|
||||
|
||||
## 릴리즈 노트 생성
|
||||
|
||||
### 자동 카테고리 분류
|
||||
|
||||
Linear 이슈들은 제목과 라벨을 기반으로 자동으로 분류됩니다:
|
||||
|
||||
- **Features (✨)**: feat, feature 키워드 또는 feature 라벨
|
||||
- **Bug Fixes (🐛)**: fix, bug 키워드 또는 bug 라벨
|
||||
- **Improvements (⚡)**: improve, enhance 키워드 또는 improvement 라벨
|
||||
- **Other (📋)**: 기타 모든 이슈
|
||||
|
||||
### 릴리즈 노트 구조
|
||||
|
||||
```markdown
|
||||
# Release 1.2.0
|
||||
|
||||
이번 릴리즈에는 5개의 Linear 이슈가 포함되었습니다.
|
||||
|
||||
## ✨ New Features
|
||||
- **ZEL-123**: 사용자 인증 시스템 구현
|
||||
- Assignee: Hansoo Ha
|
||||
- **ZEL-130**: 대시보드 위젯 추가
|
||||
- Assignee: Developer Name
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
- **ZEL-124**: 로그인 오류 수정
|
||||
- Assignee: Hansoo Ha
|
||||
|
||||
## ⚡ Improvements
|
||||
- **ZEL-127**: 데이터베이스 쿼리 최적화
|
||||
- Assignee: Developer Name
|
||||
|
||||
## 🔗 Linear Issues
|
||||
- [ZEL-123](https://linear.app/zellyy/issue/ZEL-123) - 사용자 인증 시스템 구현
|
||||
- [ZEL-124](https://linear.app/zellyy/issue/ZEL-124) - 로그인 오류 수정
|
||||
- [ZEL-127](https://linear.app/zellyy/issue/ZEL-127) - 데이터베이스 쿼리 최적화
|
||||
- [ZEL-130](https://linear.app/zellyy/issue/ZEL-130) - 대시보드 위젯 추가
|
||||
```
|
||||
|
||||
## Linear 이슈 관리
|
||||
|
||||
### 릴리즈 완료 알림
|
||||
|
||||
릴리즈가 성공적으로 완료되면 포함된 모든 Linear 이슈에 다음과 같은 코멘트가 자동으로 추가됩니다:
|
||||
|
||||
```markdown
|
||||
🎉 **릴리즈 완료**: v1.2.0
|
||||
|
||||
이 이슈가 포함된 새로운 버전이 릴리즈되었습니다.
|
||||
|
||||
**릴리즈 정보:**
|
||||
- 버전: v1.2.0
|
||||
- 릴리즈 노트: https://github.com/zellycloud/zellyy-finance/releases/tag/v1.2.0
|
||||
- 배포 시간: 2024-01-15 19:30:00
|
||||
|
||||
**다음 단계:**
|
||||
- 프로덕션 배포 확인
|
||||
- 기능 테스트 수행
|
||||
- 사용자 피드백 모니터링
|
||||
```
|
||||
|
||||
### 이슈 상태 관리
|
||||
|
||||
릴리즈에 포함된 이슈들의 상태를 체계적으로 관리할 수 있습니다:
|
||||
|
||||
1. **Done**: 개발 완료된 이슈들
|
||||
2. **Released**: 릴리즈에 포함된 이슈들 (자동 알림으로 확인)
|
||||
3. **Deployed**: 프로덕션 배포 확인된 이슈들
|
||||
|
||||
## 자동화 워크플로우
|
||||
|
||||
### GitHub Actions 통합
|
||||
|
||||
`.github/workflows/release.yml`에서 전체 릴리즈 프로세스를 자동화합니다:
|
||||
|
||||
```yaml
|
||||
# 트리거 조건
|
||||
on:
|
||||
push:
|
||||
branches: [main] # main 브랜치 푸시 시 자동 릴리즈
|
||||
workflow_dispatch: # 수동 트리거 지원
|
||||
inputs:
|
||||
release_type:
|
||||
type: choice
|
||||
options: [auto, patch, minor, major]
|
||||
```
|
||||
|
||||
### 주요 단계
|
||||
|
||||
1. **Quality Checks**: 코드 품질 검증
|
||||
```yaml
|
||||
- Type check (npm run type-check)
|
||||
- Linting (npm run lint)
|
||||
- Testing (npm run test:run)
|
||||
```
|
||||
|
||||
2. **Build Verification**: 빌드 검증
|
||||
```yaml
|
||||
- Web build (npm run build)
|
||||
- Mobile sync (npm run mobile:sync)
|
||||
```
|
||||
|
||||
3. **Linear Validation**: Linear 이슈 검증
|
||||
```yaml
|
||||
- Extract Linear issues from commits
|
||||
- Validate issue existence
|
||||
- Count and report found issues
|
||||
```
|
||||
|
||||
4. **Semantic Release**: 릴리즈 생성
|
||||
```yaml
|
||||
- Analyze commits for version bump
|
||||
- Generate changelog
|
||||
- Create GitHub release
|
||||
- Execute Linear integration
|
||||
```
|
||||
|
||||
5. **Post-Release**: 사후 처리
|
||||
```yaml
|
||||
- Update Linear issues with release info
|
||||
- Send deployment notifications
|
||||
- Prepare rollback information if needed
|
||||
```
|
||||
|
||||
## 사용 방법
|
||||
|
||||
### 1. 개발 워크플로우
|
||||
|
||||
```bash
|
||||
# 1. 새 기능 브랜치 생성
|
||||
git checkout -b feature/ZEL-123-user-auth
|
||||
|
||||
# 2. 개발 진행
|
||||
# ... 코드 작성 ...
|
||||
|
||||
# 3. Linear 이슈 ID를 포함한 커밋
|
||||
git commit -m "feat: implement user authentication [ZEL-123]"
|
||||
|
||||
# 4. 기능 브랜치 푸시
|
||||
git push origin feature/ZEL-123-user-auth
|
||||
|
||||
# 5. Pull Request 생성 (제목에 Linear 이슈 ID 포함)
|
||||
# "feat: User authentication system (ZEL-123)"
|
||||
|
||||
# 6. 리뷰 및 승인 후 main 브랜치에 머지
|
||||
# → 자동으로 릴리즈 프로세스 시작
|
||||
```
|
||||
|
||||
### 2. 릴리즈 확인
|
||||
|
||||
```bash
|
||||
# 릴리즈 로그 확인
|
||||
# GitHub → Actions → Release 워크플로우 확인
|
||||
|
||||
# 생성된 릴리즈 확인
|
||||
# GitHub → Releases 페이지 확인
|
||||
|
||||
# Linear 이슈 업데이트 확인
|
||||
# Linear에서 해당 이슈의 코멘트 확인
|
||||
```
|
||||
|
||||
### 3. 로컬 테스트
|
||||
|
||||
```bash
|
||||
# 드라이 런으로 릴리즈 시뮬레이션
|
||||
npm run release:dry-run
|
||||
|
||||
# Linear 플러그인 단독 테스트
|
||||
LINEAR_API_KEY=your-key npm run release:test
|
||||
|
||||
# 전체 Linear 통합 테스트
|
||||
npm run linear:test-workflow -- --linear-api=your-key
|
||||
```
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### 자주 발생하는 문제들
|
||||
|
||||
#### 1. Linear API 연결 실패
|
||||
|
||||
**증상**: `LINEAR_API_KEY not found` 오류
|
||||
|
||||
**해결방법**:
|
||||
```bash
|
||||
# 1. GitHub Secrets 확인
|
||||
# Repository Settings → Secrets → LINEAR_API_KEY 존재 확인
|
||||
|
||||
# 2. API 키 권한 확인
|
||||
# Linear Settings → API → Personal API keys 확인
|
||||
|
||||
# 3. 로컬 테스트
|
||||
LINEAR_API_KEY=your-key npm run release:test
|
||||
```
|
||||
|
||||
#### 2. 커밋에서 Linear 이슈를 찾을 수 없음
|
||||
|
||||
**증상**: `No Linear issues found in commits`
|
||||
|
||||
**해결방법**:
|
||||
```bash
|
||||
# 올바른 커밋 메시지 형식 사용
|
||||
git commit -m "feat: new feature [ZEL-123]"
|
||||
git commit -m "fix: bug fix (ZEL-456)"
|
||||
|
||||
# 커밋 히스토리 확인
|
||||
git log --oneline --grep="ZEL-"
|
||||
```
|
||||
|
||||
#### 3. Semantic Release 실행 실패
|
||||
|
||||
**증상**: `No release type found` 또는 권한 오류
|
||||
|
||||
**해결방법**:
|
||||
```bash
|
||||
# 1. 커밋 컨벤션 확인
|
||||
# feat:, fix:, perf: 등 올바른 타입 사용
|
||||
|
||||
# 2. GitHub Token 권한 확인
|
||||
# GITHUB_TOKEN이 올바른 권한을 가지고 있는지 확인
|
||||
|
||||
# 3. 브랜치 확인
|
||||
# main 브랜치에서만 릴리즈 가능
|
||||
```
|
||||
|
||||
#### 4. Linear 이슈에 코멘트 추가 실패
|
||||
|
||||
**증상**: `Failed to add comment to ZEL-XXX`
|
||||
|
||||
**해결방법**:
|
||||
```bash
|
||||
# 1. Linear 이슈 존재 확인
|
||||
# 해당 이슈가 Linear에 실제로 존재하는지 확인
|
||||
|
||||
# 2. API 키 권한 확인
|
||||
# Write 권한이 있는 API 키인지 확인
|
||||
|
||||
# 3. 네트워크 연결 확인
|
||||
# GitHub Actions에서 Linear API 접근 가능한지 확인
|
||||
```
|
||||
|
||||
### 로그 분석
|
||||
|
||||
#### GitHub Actions 로그
|
||||
|
||||
```bash
|
||||
# 1. Repository → Actions 이동
|
||||
# 2. 실패한 워크플로우 클릭
|
||||
# 3. 각 단계별 로그 확인
|
||||
|
||||
# 주요 확인 사항:
|
||||
# - Quality Checks: 모든 체크 통과 여부
|
||||
# - Semantic Release: 버전 결정 및 노트 생성
|
||||
# - Linear Integration: API 호출 성공 여부
|
||||
```
|
||||
|
||||
#### 로컬 디버깅
|
||||
|
||||
```bash
|
||||
# 상세 로그와 함께 테스트
|
||||
DEBUG=true npm run release:test
|
||||
|
||||
# Linear 통합 전체 테스트
|
||||
npm run linear:test-workflow -- --verbose
|
||||
|
||||
# 릴리즈 메타데이터 확인
|
||||
cat releases/v*-metadata.json | jq
|
||||
```
|
||||
|
||||
### 복구 방법
|
||||
|
||||
#### 릴리즈 실패 시
|
||||
|
||||
```bash
|
||||
# 1. 실패한 릴리즈 삭제 (필요한 경우)
|
||||
# GitHub → Releases에서 삭제
|
||||
|
||||
# 2. Git 태그 정리 (필요한 경우)
|
||||
git tag -d v1.2.0
|
||||
git push origin :refs/tags/v1.2.0
|
||||
|
||||
# 3. 문제 해결 후 재실행
|
||||
# main 브랜치에 빈 커밋 푸시하여 재트리거
|
||||
git commit --allow-empty -m "chore: trigger release"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
#### Linear 동기화 실패 시
|
||||
|
||||
```bash
|
||||
# 수동으로 Linear 릴리즈 완료 스크립트 실행
|
||||
node scripts/semantic-release-linear-plugin.cjs success 1.2.0
|
||||
|
||||
# 또는 개별 이슈에 수동 코멘트 추가
|
||||
npm run linear:comment -- --issue-id=ZEL-123 --event=release --action=completed
|
||||
```
|
||||
|
||||
## 모니터링 및 메트릭
|
||||
|
||||
### 릴리즈 성과 지표
|
||||
|
||||
- **릴리즈 빈도**: 주/월별 릴리즈 횟수
|
||||
- **이슈 포함률**: 릴리즈당 평균 Linear 이슈 수
|
||||
- **카테고리 분포**: Features vs Bug Fixes vs Improvements 비율
|
||||
- **담당자별 기여도**: 이슈 담당자별 릴리즈 참여 현황
|
||||
|
||||
### 자동 보고서
|
||||
|
||||
`releases/` 디렉토리의 메타데이터를 활용하여 릴리즈 트렌드를 분석할 수 있습니다:
|
||||
|
||||
```bash
|
||||
# 최근 릴리즈 현황 확인
|
||||
ls -la releases/
|
||||
|
||||
# 특정 릴리즈 상세 정보
|
||||
cat releases/v1.2.0-metadata.json | jq
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
이 시스템을 통해 Linear 이슈 추적과 semantic-release가 완벽하게 통합되어 체계적이고 투명한 릴리즈 관리가 가능합니다.
|
||||
191
docs/sentry-setup.md
Normal file
191
docs/sentry-setup.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# Sentry.io 설정 가이드
|
||||
|
||||
## 1. Sentry 계정 생성
|
||||
|
||||
1. [Sentry.io](https://sentry.io)에서 무료 계정 생성
|
||||
2. "Create Project" 클릭
|
||||
3. Platform: **React** 선택
|
||||
4. 프로젝트명: `zellyy-finance`
|
||||
5. 팀/조직 설정 (개인 계정 사용 가능)
|
||||
|
||||
## 2. DSN 및 설정 정보 획득
|
||||
|
||||
### DSN (Data Source Name) 가져오기
|
||||
1. 프로젝트 생성 후 자동으로 표시되는 DSN 복사
|
||||
2. 또는 `Settings > Projects > [프로젝트명] > Client Keys (DSN)` 에서 확인
|
||||
3. 형식: `https://[키]@[지역].ingest.sentry.io/[프로젝트ID]`
|
||||
|
||||
### Auth Token 생성 (소스맵 업로드용)
|
||||
1. `Settings > Auth Tokens` 메뉴 이동
|
||||
2. "Create New Token" 클릭
|
||||
3. 권한 설정:
|
||||
- `project:read`
|
||||
- `project:write`
|
||||
- `org:read`
|
||||
4. 토큰 이름: `zellyy-finance-sourcemaps`
|
||||
5. 생성된 토큰을 안전하게 보관
|
||||
|
||||
### 조직 및 프로젝트 정보 확인
|
||||
1. `Settings > General Settings`에서 조직명 확인
|
||||
2. `Settings > Projects`에서 프로젝트명 확인
|
||||
|
||||
## 3. 환경 변수 설정
|
||||
|
||||
### 개발환경 (.env)
|
||||
```env
|
||||
# Sentry 모니터링 설정
|
||||
VITE_SENTRY_DSN=https://your_actual_dsn@sentry.io/123456
|
||||
VITE_SENTRY_ENVIRONMENT=development
|
||||
|
||||
# Sentry 빌드 관련
|
||||
SENTRY_ORG=your_organization_name
|
||||
SENTRY_PROJECT=zellyy-finance
|
||||
SENTRY_RELEASE=zellyy-finance@1.0.0
|
||||
SENTRY_DISABLE_SOURCEMAPS=true
|
||||
```
|
||||
|
||||
### 프로덕션 환경 (Vercel, Netlify 등)
|
||||
```env
|
||||
# Sentry 모니터링 설정
|
||||
VITE_SENTRY_DSN=https://your_actual_dsn@sentry.io/123456
|
||||
VITE_SENTRY_ENVIRONMENT=production
|
||||
|
||||
# Sentry 빌드 관련 (소스맵 업로드용)
|
||||
SENTRY_ORG=your_organization_name
|
||||
SENTRY_PROJECT=zellyy-finance
|
||||
SENTRY_AUTH_TOKEN=your_auth_token_here
|
||||
SENTRY_RELEASE=zellyy-finance@1.0.0
|
||||
SENTRY_DISABLE_SOURCEMAPS=false
|
||||
```
|
||||
|
||||
## 4. 소스맵 업로드 테스트
|
||||
|
||||
### 로컬에서 프로덕션 빌드 테스트
|
||||
```bash
|
||||
# 소스맵과 함께 프로덕션 빌드
|
||||
npm run build:sentry
|
||||
|
||||
# 빌드 후 dist 폴더 확인
|
||||
ls -la dist/
|
||||
# *.js.map 파일들이 생성되었다가 Sentry 업로드 후 삭제되는지 확인
|
||||
```
|
||||
|
||||
### 배포 환경에서 소스맵 확인
|
||||
1. Sentry 대시보드에서 `Releases` 메뉴 이동
|
||||
2. 최신 릴리즈 클릭
|
||||
3. `Artifacts` 탭에서 업로드된 소스맵 파일 확인
|
||||
|
||||
## 5. 에러 추적 테스트
|
||||
|
||||
### 개발환경에서 테스트
|
||||
1. 브라우저에서 `F12` 개발자 도구 열기
|
||||
2. Console에서 Sentry 테스트 버튼 클릭
|
||||
3. Sentry 대시보드에서 `Issues` 메뉴에서 테스트 에러 확인
|
||||
|
||||
### 프로덕션 에러 테스트
|
||||
```javascript
|
||||
// 의도적으로 에러 발생시키기
|
||||
throw new Error("프로덕션 테스트 에러");
|
||||
```
|
||||
|
||||
## 6. 성능 모니터링 설정
|
||||
|
||||
### Core Web Vitals 확인
|
||||
1. Sentry 대시보드에서 `Performance` 메뉴 이동
|
||||
2. `Web Vitals` 탭에서 LCP, FID, CLS 지표 확인
|
||||
3. 페이지별 성능 분석
|
||||
|
||||
### 커스텀 트랜잭션 추적
|
||||
```typescript
|
||||
import { trackEvent, measurePerformance } from '@/lib/sentry';
|
||||
|
||||
// 사용자 행동 추적
|
||||
trackEvent('transaction_created', { amount: 1000, category: 'food' });
|
||||
|
||||
// 성능 측정
|
||||
const startTime = performance.now();
|
||||
await expensiveOperation();
|
||||
measurePerformance('expensive_operation', startTime);
|
||||
```
|
||||
|
||||
## 7. 알림 설정
|
||||
|
||||
### 이메일 알림 설정
|
||||
1. `Settings > Notifications` 메뉴 이동
|
||||
2. `Email` 탭에서 알림 규칙 설정:
|
||||
- 새로운 이슈 발생 시 즉시 알림
|
||||
- 이슈 재발생 시 알림
|
||||
- 성능 저하 감지 시 알림
|
||||
|
||||
### Slack 통합 (선택사항)
|
||||
1. `Settings > Integrations` 메뉴 이동
|
||||
2. Slack 통합 설정
|
||||
3. 알림받을 채널 설정
|
||||
|
||||
## 8. 릴리즈 추적
|
||||
|
||||
### 자동 릴리즈 추적
|
||||
```bash
|
||||
# 빌드 시 자동으로 릴리즈 생성 및 배포 기록
|
||||
npm run build:prod
|
||||
npm run deploy
|
||||
```
|
||||
|
||||
### 수동 릴리즈 관리
|
||||
```bash
|
||||
# 새 릴리즈 생성
|
||||
npm run sentry:release
|
||||
|
||||
# 배포 기록
|
||||
npm run sentry:deploy
|
||||
```
|
||||
|
||||
## 9. 보안 고려사항
|
||||
|
||||
### 민감한 정보 필터링
|
||||
- 이미 `src/lib/sentry.ts`에서 설정됨:
|
||||
- 비밀번호, 토큰 포함 에러 메시지 필터링
|
||||
- 로컬호스트 에러 필터링
|
||||
- 세션 재생에서 텍스트 마스킹
|
||||
|
||||
### 소스맵 보안
|
||||
- 프로덕션 빌드 후 로컬 소스맵 파일 자동 삭제
|
||||
- Sentry에만 저장되어 에러 디버깅 시 활용
|
||||
|
||||
## 10. 문제 해결
|
||||
|
||||
### 소스맵 업로드 실패
|
||||
```bash
|
||||
# Sentry CLI 설치 및 직접 업로드 테스트
|
||||
npm install -g @sentry/cli
|
||||
sentry-cli releases files $SENTRY_RELEASE upload-sourcemaps ./dist
|
||||
```
|
||||
|
||||
### 에러 추적이 안 될 때
|
||||
1. DSN이 올바르게 설정되었는지 확인
|
||||
2. 네트워크 방화벽/브라우저 확장 프로그램 확인
|
||||
3. 개발자 도구 Network 탭에서 Sentry 요청 확인
|
||||
|
||||
### 성능 데이터가 수집되지 않을 때
|
||||
- `tracesSampleRate`가 0보다 큰지 확인
|
||||
- 프로덕션 환경에서는 샘플링 비율이 낮을 수 있음 (0.1 = 10%)
|
||||
|
||||
## 11. 비용 최적화
|
||||
|
||||
### 무료 플랜 한도
|
||||
- 월간 5,000 에러 이벤트
|
||||
- 10,000 성능 트랜잭션
|
||||
- 1개월 데이터 보존
|
||||
|
||||
### 샘플링 조정
|
||||
```typescript
|
||||
// 개발환경
|
||||
tracesSampleRate: 1.0, // 100% 수집
|
||||
replaysSessionSampleRate: 0.1, // 10% 세션 재생
|
||||
|
||||
// 프로덕션환경
|
||||
tracesSampleRate: 0.1, // 10% 수집
|
||||
replaysSessionSampleRate: 0.05, // 5% 세션 재생
|
||||
```
|
||||
|
||||
이 설정으로 Sentry를 통한 포괄적인 에러 추적 및 성능 모니터링이 가능합니다.
|
||||
314
docs/version-management-guide.md
Normal file
314
docs/version-management-guide.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# 버전 관리 및 릴리즈 자동화 가이드
|
||||
|
||||
## 개요
|
||||
|
||||
Zellyy Finance 프로젝트는 Conventional Commits과 Semantic Release를 사용하여 완전히 자동화된 버전 관리 시스템을 구축했습니다. 커밋 메시지를 기반으로 버전을 자동으로 관리하고, 릴리즈 노트를 생성하며, 모든 플랫폼의 버전을 동기화합니다.
|
||||
|
||||
## 시스템 구성 요소
|
||||
|
||||
### 1. Semantic Release 설정 (`.releaserc.json`)
|
||||
|
||||
```json
|
||||
{
|
||||
"branches": ["main", {"name": "beta", "prerelease": true}],
|
||||
"plugins": [
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog",
|
||||
"@semantic-release/npm",
|
||||
"@semantic-release/github",
|
||||
"@semantic-release/exec",
|
||||
"@semantic-release/git"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 버전 동기화 스크립트 (`scripts/sync-versions.cjs`)
|
||||
|
||||
- `package.json` 버전을 Android `build.gradle`과 iOS `Info.plist`에 동기화
|
||||
- 시맨틱 버전을 빌드 코드로 변환 (예: `1.2.3` → `10203`)
|
||||
- 검증 모드 지원 (`--check` 플래그)
|
||||
|
||||
### 3. 릴리즈 후 처리 스크립트 (`scripts/release-version.cjs`)
|
||||
|
||||
- Semantic Release 완료 후 자동 실행
|
||||
- 모바일 플랫폼 버전 동기화
|
||||
- Capacitor 동기화
|
||||
|
||||
## 커밋 메시지 규칙 (Conventional Commits)
|
||||
|
||||
### 기본 형식
|
||||
```
|
||||
<type>(<scope>): <description>
|
||||
|
||||
[optional body]
|
||||
|
||||
[optional footer]
|
||||
```
|
||||
|
||||
### 지원하는 타입과 버전 영향
|
||||
|
||||
| 타입 | 설명 | 버전 영향 | 예시 |
|
||||
|------|------|-----------|------|
|
||||
| `feat` | 새로운 기능 | **Minor** (1.0.0 → 1.1.0) | `feat: 거래 필터링 기능 추가` |
|
||||
| `fix` | 버그 수정 | **Patch** (1.0.0 → 1.0.1) | `fix: 로그인 오류 수정` |
|
||||
| `perf` | 성능 개선 | **Patch** (1.0.0 → 1.0.1) | `perf: 차트 렌더링 최적화` |
|
||||
| `docs` | 문서 변경 | **Patch** (1.0.0 → 1.0.1) | `docs: API 문서 업데이트` |
|
||||
| `refactor` | 리팩토링 | **Patch** (1.0.0 → 1.0.1) | `refactor: 컴포넌트 구조 개선` |
|
||||
| `revert` | 되돌리기 | **Patch** (1.0.0 → 1.0.1) | `revert: feat: 거래 필터링 기능 제거` |
|
||||
| `style` | 스타일 변경 | **없음** | `style: 코드 포맷팅` |
|
||||
| `test` | 테스트 추가/수정 | **없음** | `test: 로그인 테스트 추가` |
|
||||
| `build` | 빌드 시스템 변경 | **없음** | `build: Webpack 설정 변경` |
|
||||
| `ci` | CI 설정 변경 | **없음** | `ci: GitHub Actions 업데이트` |
|
||||
| `chore` | 기타 변경 | **없음** | `chore: 의존성 업데이트` |
|
||||
|
||||
### Breaking Changes (Major 버전)
|
||||
|
||||
Major 버전 증가 (1.0.0 → 2.0.0)를 위해서는 다음 중 하나를 사용:
|
||||
|
||||
1. **느낌표 표기법:**
|
||||
```
|
||||
feat!: 새로운 API 인터페이스 도입
|
||||
```
|
||||
|
||||
2. **Footer 표기법:**
|
||||
```
|
||||
feat: 사용자 인증 시스템 개편
|
||||
|
||||
BREAKING CHANGE: 기존 auth API가 제거되고 새로운 인터페이스로 교체됨
|
||||
```
|
||||
|
||||
## 릴리즈 프로세스
|
||||
|
||||
### 자동 릴리즈 흐름
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[커밋 & 푸시] --> B[GitHub Actions 트리거]
|
||||
B --> C[테스트 실행]
|
||||
C --> D[빌드 검증]
|
||||
D --> E[Semantic Release 실행]
|
||||
E --> F[버전 분석]
|
||||
F --> G[릴리즈 노트 생성]
|
||||
G --> H[package.json 업데이트]
|
||||
H --> I[버전 동기화 스크립트 실행]
|
||||
I --> J[모바일 플랫폼 동기화]
|
||||
J --> K[Git 커밋 & 태그]
|
||||
K --> L[GitHub Release 생성]
|
||||
L --> M[앱스토어 배포]
|
||||
```
|
||||
|
||||
### 1. 개발 단계
|
||||
|
||||
```bash
|
||||
# 기능 브랜치에서 개발
|
||||
git checkout -b feature/new-transaction-filter
|
||||
|
||||
# 커밋 (Conventional Commits 규칙 준수)
|
||||
git commit -m "feat: 거래 내역 필터링 기능 추가
|
||||
|
||||
사용자가 날짜, 카테고리, 금액 범위로 거래를 필터링할 수 있는 기능을 추가했습니다."
|
||||
|
||||
# PR 생성 후 main 브랜치에 머지
|
||||
```
|
||||
|
||||
### 2. 자동 릴리즈 (main 브랜치 푸시 시)
|
||||
|
||||
```bash
|
||||
# GitHub Actions에서 자동 실행:
|
||||
# 1. 테스트 & 빌드
|
||||
# 2. Semantic Release
|
||||
# 3. 버전 업데이트 (1.0.0 → 1.1.0)
|
||||
# 4. 릴리즈 노트 생성
|
||||
# 5. GitHub Release 생성
|
||||
# 6. 앱스토어 배포
|
||||
```
|
||||
|
||||
## 릴리즈 노트 형식
|
||||
|
||||
자동 생성되는 릴리즈 노트 예시:
|
||||
|
||||
```markdown
|
||||
# [1.1.0](https://github.com/user/repo/compare/v1.0.0...v1.1.0) (2024-01-15)
|
||||
|
||||
## ✨ Features
|
||||
|
||||
* 거래 내역 필터링 기능 추가 ([a1b2c3d](https://github.com/user/repo/commit/a1b2c3d))
|
||||
* 다크 모드 지원 ([e4f5g6h](https://github.com/user/repo/commit/e4f5g6h))
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
|
||||
* 로그인 세션 만료 오류 수정 ([i7j8k9l](https://github.com/user/repo/commit/i7j8k9l))
|
||||
|
||||
## ⚡ Performance Improvements
|
||||
|
||||
* 차트 렌더링 성능 50% 개선 ([m0n1o2p](https://github.com/user/repo/commit/m0n1o2p))
|
||||
```
|
||||
|
||||
## 버전 동기화
|
||||
|
||||
### 플랫폼별 버전 관리
|
||||
|
||||
| 플랫폼 | 파일 | 버전 필드 | 예시 값 |
|
||||
|--------|------|-----------|---------|
|
||||
| **Web** | `package.json` | `version` | `"1.2.3"` |
|
||||
| **Android** | `android/app/build.gradle` | `versionName`, `versionCode` | `"1.2.3"`, `10203` |
|
||||
| **iOS** | `ios/App/App/Info.plist` | `CFBundleShortVersionString`, `CFBundleVersion` | `"1.2.3"`, `10203` |
|
||||
|
||||
### 버전 코드 변환 규칙
|
||||
|
||||
```javascript
|
||||
// "1.2.3" → 10203
|
||||
function versionToCode(version) {
|
||||
const [major, minor, patch] = version.split('.').map(Number);
|
||||
return major * 10000 + minor * 100 + patch;
|
||||
}
|
||||
```
|
||||
|
||||
### 수동 버전 동기화
|
||||
|
||||
```bash
|
||||
# 모든 플랫폼 버전 동기화
|
||||
npm run version:sync
|
||||
|
||||
# 버전 일관성 검사
|
||||
npm run version:check
|
||||
|
||||
# 릴리즈 후 처리 (일반적으로 자동 실행)
|
||||
npm run version:post-release
|
||||
```
|
||||
|
||||
## GitHub Actions 설정
|
||||
|
||||
### Workflow 트리거
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
branches: [main] # 자동 릴리즈
|
||||
tags: ['v*'] # 수동 릴리즈
|
||||
pull_request:
|
||||
branches: [main] # 테스트만 실행
|
||||
```
|
||||
|
||||
### 주요 단계
|
||||
|
||||
1. **Test & Lint**: 코드 품질 검증
|
||||
2. **Build Web**: 웹 앱 빌드
|
||||
3. **Build Mobile**: Android/iOS 앱 빌드
|
||||
4. **Release**: Semantic Release 실행
|
||||
5. **Deploy**: 앱스토어 자동 배포
|
||||
|
||||
## 환경별 설정
|
||||
|
||||
### Beta 릴리즈 (베타 브랜치)
|
||||
|
||||
```bash
|
||||
# 베타 브랜치로 푸시하면 prerelease 생성
|
||||
git checkout -b beta
|
||||
git push origin beta
|
||||
# → v1.1.0-beta.1 릴리즈 생성
|
||||
```
|
||||
|
||||
### 핫픽스 릴리즈
|
||||
|
||||
```bash
|
||||
# main에서 직접 핫픽스
|
||||
git checkout main
|
||||
git commit -m "fix: 긴급 보안 패치"
|
||||
git push origin main
|
||||
# → 자동으로 v1.0.1 릴리즈 생성
|
||||
```
|
||||
|
||||
## 모니터링 및 디버깅
|
||||
|
||||
### 릴리즈 상태 확인
|
||||
|
||||
```bash
|
||||
# 최신 릴리즈 정보
|
||||
gh release list
|
||||
|
||||
# 특정 릴리즈 상세 정보
|
||||
gh release view v1.1.0
|
||||
|
||||
# GitHub Actions 실행 상태
|
||||
gh run list --workflow=mobile-build.yml
|
||||
```
|
||||
|
||||
### 일반적인 문제 해결
|
||||
|
||||
#### 1. 버전 동기화 실패
|
||||
|
||||
```bash
|
||||
# 수동으로 버전 확인
|
||||
npm run version:check
|
||||
|
||||
# 문제가 있으면 수동 동기화
|
||||
npm run version:sync
|
||||
```
|
||||
|
||||
#### 2. Semantic Release 실패
|
||||
|
||||
```bash
|
||||
# 커밋 메시지 형식 확인
|
||||
git log --oneline -5
|
||||
|
||||
# 수동으로 semantic-release 실행 (로컬)
|
||||
npx semantic-release --dry-run
|
||||
```
|
||||
|
||||
#### 3. 모바일 빌드 실패
|
||||
|
||||
```bash
|
||||
# Android 버전 확인
|
||||
grep -E "versionCode|versionName" android/app/build.gradle
|
||||
|
||||
# iOS 버전 확인 (macOS only)
|
||||
/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" ios/App/App/Info.plist
|
||||
```
|
||||
|
||||
## 베스트 프랙티스
|
||||
|
||||
### 1. 커밋 메시지 작성
|
||||
|
||||
✅ **좋은 예시:**
|
||||
```bash
|
||||
feat(auth): OAuth 2.0 로그인 지원 추가
|
||||
|
||||
Google, GitHub OAuth 프로바이더를 통한 소셜 로그인 기능을 구현했습니다.
|
||||
- Google OAuth 2.0 클라이언트 설정
|
||||
- GitHub OAuth 앱 연동
|
||||
- 기존 이메일 로그인과 호환성 유지
|
||||
|
||||
Closes #123
|
||||
```
|
||||
|
||||
❌ **나쁜 예시:**
|
||||
```bash
|
||||
update login
|
||||
fix bug
|
||||
change ui
|
||||
```
|
||||
|
||||
### 2. 릴리즈 전 체크리스트
|
||||
|
||||
- [ ] 모든 테스트 통과
|
||||
- [ ] 타입 체크 통과
|
||||
- [ ] 린트 검사 통과
|
||||
- [ ] 빌드 검증 완료
|
||||
- [ ] 브레이킹 체인지 문서화
|
||||
- [ ] 버전 호환성 확인
|
||||
|
||||
### 3. 긴급 상황 대응
|
||||
|
||||
```bash
|
||||
# 문제가 있는 릴리즈 되돌리기
|
||||
git revert <commit-hash>
|
||||
git commit -m "revert: v1.1.0 롤백 - 로그인 오류"
|
||||
git push origin main
|
||||
# → 자동으로 v1.1.1 패치 릴리즈 생성
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
이 가이드는 Zellyy Finance의 자동화된 버전 관리 시스템의 완전한 참조 문서입니다. 추가 질문이나 문제가 있으면 개발팀에 문의하세요.
|
||||
Reference in New Issue
Block a user