Local Test and CI Optimization
📋 목표
섹션 제목: “📋 목표”- 로컬에서 완전한 검증 완료 → CI는 배포만 집중
- 로컬 테스트 실행 방법 가이드 제공
- 신뢰성 보장: 로컬 검증과 CI 검증의 일관성 유지
🔍 현재 상황 분석
섹션 제목: “🔍 현재 상황 분석”현재 CI 구조
섹션 제목: “현재 CI 구조”validate (TypeScript + 테스트 + 빌드 검증) ↓provision (리소스 프로비저닝 + 검증) ↓deploy (실제 배포)문제점
섹션 제목: “문제점”- CI에서 모든 검증을 반복 실행 (시간 소모)
- 로컬에서 이미 검증했는데 CI에서도 동일한 검증 반복
- 개발자 경험 저하 (빠른 피드백 부족)
✅ 최적화 방안
섹션 제목: “✅ 최적화 방안”🎯 방안 1: “Trust Local, Verify in CI” 전략 (권장)
섹션 제목: “🎯 방안 1: “Trust Local, Verify in CI” 전략 (권장)”핵심 원칙
섹션 제목: “핵심 원칙”“로컬에서 검증 완료 → CI는 최소 검증 + 배포 집중”
로컬 개발자 ↓[로컬 검증 완료] ← TypeScript, 테스트, 빌드 검증 ↓[Git Push] ↓CI (간소화) ↓[빠른 검증] ← TypeScript만 (빠른 실패 감지) ↓[리소스 프로비저닝] ↓[배포]구현 전략
섹션 제목: “구현 전략”1. 로컬 검증 스크립트 통합
# package.json에 추가"precommit": "pnpm run validate:local""validate:local": "pnpm run typecheck && pnpm run test && pnpm run build:check"2. CI 간소화
- TypeScript 검증: 빠른 실패 감지용 (30초)
- 테스트: 스킵 또는 선택적 실행
- 빌드 검증: 배포 전 최종 확인만
3. 검증 신뢰성 보장
- Git hooks로 로컬 검증 강제
- CI에서도 최소한의 검증 유지 (안전망)
🎯 방안 2: “Pre-commit Hook + CI Skip” 전략
섹션 제목: “🎯 방안 2: “Pre-commit Hook + CI Skip” 전략”핵심 원칙
섹션 제목: “핵심 원칙”“Pre-commit hook에서 검증 → CI는 스킵 플래그로 제어”
로컬 개발자 ↓[Git Commit 시도] ↓[Pre-commit Hook] ← 자동 검증 실행 ↓[검증 실패] → Commit 차단 ↓[검증 성공] → Commit 허용 ↓[Git Push] ↓CI (검증 스킵) ↓[배포만 실행]구현 전략
섹션 제목: “구현 전략”1. Pre-commit Hook 설정
#!/bin/sh. "$(dirname "$0")/_/husky.sh"
echo "🔍 Running pre-commit validation..."pnpm run validate:local || { echo "❌ Validation failed. Please fix errors before committing." exit 1}2. CI에서 검증 스킵 옵션
- name: TypeScript Type Check run: | if [ "${{ github.event.head_commit.message }}" =~ "\[skip-ci-validation\]" ]; then echo "⏭️ Skipping validation (pre-commit verified)" else pnpm exec tsc --noEmit --skipLibCheck fi🎯 방안 3: “Local CI Script” 전략 (가장 추천)
섹션 제목: “🎯 방안 3: “Local CI Script” 전략 (가장 추천)”핵심 원칙
섹션 제목: “핵심 원칙”“로컬에서 CI와 동일한 검증 실행 → CI는 배포만”
로컬 개발자 ↓[로컬 CI 스크립트 실행] ← CI와 동일한 검증 ↓[검증 성공] ↓[Git Push] ↓CI (검증 최소화) ↓[빠른 TypeScript 체크] ← 30초 ↓[배포]구현 전략
섹션 제목: “구현 전략”1. 로컬 CI 스크립트
#!/bin/bashset -euxo pipefail
echo "🧪 Running local CI validation..."
# TypeScript 검증echo "🔍 TypeScript type check..."pnpm exec tsc --noEmit --skipLibCheck
# 테스트 실행echo "🧪 Running tests..."pnpm test
# 빌드 검증echo "🔨 Build validation..."pnpm exec wrangler deploy --dry-run --env staging
echo "✅ Local CI validation passed!"2. CI 간소화
validate: steps: # 빠른 TypeScript 체크만 (안전망) - name: Quick TypeScript Check run: pnpm exec tsc --noEmit --skipLibCheck timeout-minutes: 2 # 빠른 실패
# 테스트는 스킵 (로컬에서 이미 실행) - name: Run Tests run: echo "⏭️ Tests skipped (run locally before push)" continue-on-error: true📝 로컬 테스트 실행 가이드
섹션 제목: “📝 로컬 테스트 실행 가이드”1. 기본 테스트 실행
섹션 제목: “1. 기본 테스트 실행”단위 테스트
섹션 제목: “단위 테스트”# 모든 테스트 실행pnpm test
# Watch 모드 (파일 변경 시 자동 재실행)pnpm test --watch
# 특정 테스트 파일만 실행pnpm test src/lib/domain.test.ts
# Cloudflare Workers 환경에서 테스트pnpm test:localTypeScript 검증
섹션 제목: “TypeScript 검증”# 타입 체크만 실행pnpm exec tsc --noEmit --skipLibCheck
# 또는 package.json에 스크립트 추가# "typecheck": "tsc --noEmit --skipLibCheck"pnpm run typecheck2. 통합 테스트 (로컬 Workers)
섹션 제목: “2. 통합 테스트 (로컬 Workers)”로컬 개발 서버 시작
섹션 제목: “로컬 개발 서버 시작”# 로컬 모드 (로컬 D1/KV 사용)pnpm dev:local
# 원격 모드 (Cloudflare 리소스 사용)pnpm dev:remote
# 특정 환경wrangler dev --local --env stagingAPI 테스트
섹션 제목: “API 테스트”# Health checkcurl http://localhost:8787/health
# API 엔드포인트 테스트curl http://localhost:8787/api/v1/researchcurl http://localhost:8787/api/v1/seeds
# Orchestrator 테스트curl -X POST http://localhost:8787/api/v1/seeds/orchestrate \ -H "Content-Type: application/json" \ -d '{"country": "sg", "category": "news", "date": "2026-01-28"}'3. 빌드 검증
섹션 제목: “3. 빌드 검증”Dry-run 배포
섹션 제목: “Dry-run 배포”# Staging 환경 dry-runpnpm exec wrangler deploy --dry-run --env staging
# Production 환경 dry-runpnpm exec wrangler deploy --dry-run --env production
# Bundle 정보 확인pnpm exec wrangler deploy --dry-run --env staging > bundle-info.txtcat bundle-info.txt4. 통합 검증 스크립트
섹션 제목: “4. 통합 검증 스크립트”전체 검증 실행
섹션 제목: “전체 검증 실행”# scripts/validate-local.sh 생성 필요#!/bin/bashset -euxo pipefail
echo "🔍 Running complete local validation..."
# 1. TypeScript 검증echo "📝 TypeScript type check..."pnpm exec tsc --noEmit --skipLibCheck || { echo "❌ TypeScript errors found" exit 1}
# 2. 테스트 실행echo "🧪 Running tests..."pnpm test || { echo "❌ Tests failed" exit 1}
# 3. 빌드 검증echo "🔨 Build validation..."pnpm exec wrangler deploy --dry-run --env staging || { echo "❌ Build validation failed" exit 1}
echo "✅ All validations passed!"package.json에 추가
섹션 제목: “package.json에 추가”{ "scripts": { "validate:local": "bash scripts/validate-local.sh", "precommit": "pnpm run validate:local" }}🔧 CI/CD 최적화 구현 방안
섹션 제목: “🔧 CI/CD 최적화 구현 방안”방안 A: CI 검증 최소화 (권장)
섹션 제목: “방안 A: CI 검증 최소화 (권장)”변경 전 (현재)
섹션 제목: “변경 전 (현재)”validate: steps: - name: TypeScript Type Check run: pnpm exec tsc --noEmit --skipLibCheck # 2-3분
- name: Run Tests run: pnpm test # 5-10분
- name: Build Validation run: pnpm exec wrangler deploy --dry-run # 1-2분변경 후 (최적화)
섹션 제목: “변경 후 (최적화)”validate: steps: # 빠른 TypeScript 체크만 (안전망) - name: Quick TypeScript Check run: pnpm exec tsc --noEmit --skipLibCheck timeout-minutes: 2
# 테스트는 스킵 (로컬에서 실행 가정) - name: Run Tests run: | echo "⏭️ Tests skipped" echo "💡 Run 'pnpm test' locally before pushing" continue-on-error: true
# 빌드 검증은 유지 (배포 전 최종 확인) - name: Build Validation run: pnpm exec wrangler deploy --dry-run --env "$ENV" timeout-minutes: 3예상 시간 절약: 5-10분 → 2-3분
방안 B: 조건부 검증
섹션 제목: “방안 B: 조건부 검증”Git commit message 기반 스킵
섹션 제목: “Git commit message 기반 스킵”validate: steps: - name: Check Skip Flag id: check_skip run: | if echo "${{ github.event.head_commit.message }}" | grep -q "\[skip-validation\]"; then echo "skip=true" >> $GITHUB_OUTPUT else echo "skip=false" >> $GITHUB_OUTPUT fi
- name: TypeScript Type Check if: steps.check_skip.outputs.skip != 'true' run: pnpm exec tsc --noEmit --skipLibCheck
- name: Run Tests if: steps.check_skip.outputs.skip != 'true' run: pnpm test사용법:
git commit -m "feat: add new feature [skip-validation]"방안 C: 병렬 검증 (시간 단축)
섹션 제목: “방안 C: 병렬 검증 (시간 단축)”검증과 프로비저닝 병렬 실행
섹션 제목: “검증과 프로비저닝 병렬 실행”jobs: validate: # 빠른 검증만 steps: - name: TypeScript Check run: pnpm exec tsc --noEmit --skipLibCheck
provision: # validate와 병렬 실행 가능 needs: [] # 의존성 제거
deploy: needs: [validate, provision] # 둘 다 완료 후 배포📊 비교 분석
섹션 제목: “📊 비교 분석”현재 방식 vs 최적화 방식
섹션 제목: “현재 방식 vs 최적화 방식”| 항목 | 현재 | 최적화 (방안 A) | 최적화 (방안 C) |
|---|---|---|---|
| TypeScript 검증 | ✅ CI (2-3분) | ✅ CI (2분) | ✅ CI (2분) |
| 테스트 실행 | ✅ CI (5-10분) | ⏭️ 로컬만 | ⏭️ 로컬만 |
| 빌드 검증 | ✅ CI (1-2분) | ✅ CI (1-2분) | ✅ CI (1-2분) |
| 프로비저닝 | ✅ CI (2-3분) | ✅ CI (2-3분) | ✅ 병렬 (2-3분) |
| 총 소요 시간 | 10-18분 | 5-7분 | 5-7분 |
| 시간 절약 | - | 50-60% | 50-60% |
🎯 권장 구현 방안
섹션 제목: “🎯 권장 구현 방안”Phase 1: 로컬 검증 스크립트 추가 (즉시 적용)
섹션 제목: “Phase 1: 로컬 검증 스크립트 추가 (즉시 적용)”-
scripts/validate-local.sh생성- TypeScript 검증
- 테스트 실행
- 빌드 검증
-
package.json스크립트 추가{"scripts": {"validate:local": "bash scripts/validate-local.sh","typecheck": "tsc --noEmit --skipLibCheck"}} -
README에 로컬 검증 가이드 추가
Phase 2: CI 최적화 (검증 후 적용)
섹션 제목: “Phase 2: CI 최적화 (검증 후 적용)”-
CI 검증 최소화
- TypeScript만 유지 (빠른 실패 감지)
- 테스트는 스킵 또는 선택적
- 빌드 검증은 유지
-
시간 단축 확인
- CI 실행 시간 모니터링
- 필요 시 추가 최적화
Phase 3: Pre-commit Hook (선택사항)
섹션 제목: “Phase 3: Pre-commit Hook (선택사항)”-
Husky 설정
- Pre-commit hook으로 자동 검증
- 검증 실패 시 commit 차단
-
개발자 경험 향상
- 빠른 피드백
- CI 실패 감소
📝 로컬 테스트 체크리스트
섹션 제목: “📝 로컬 테스트 체크리스트”배포 전 필수 검증
섹션 제목: “배포 전 필수 검증”-
TypeScript 검증
Terminal window pnpm exec tsc --noEmit --skipLibCheck -
테스트 실행
Terminal window pnpm test -
빌드 검증
Terminal window pnpm exec wrangler deploy --dry-run --env staging -
로컬 서버 테스트 (선택사항)
Terminal window pnpm dev:local# 다른 터미널에서curl http://localhost:8787/health
통합 검증 (한 번에 실행)
섹션 제목: “통합 검증 (한 번에 실행)”# scripts/validate-local.sh 실행pnpm run validate:local🔍 검증 신뢰성 보장
섹션 제목: “🔍 검증 신뢰성 보장”문제: 로컬과 CI 환경 차이
섹션 제목: “문제: 로컬과 CI 환경 차이”해결 방안
섹션 제목: “해결 방안”1. 환경 일관성 유지
# 로컬에서 CI와 동일한 Node.js 버전 사용nvm use 20 # 또는 .nvmrc 파일 사용
# 로컬에서 CI와 동일한 pnpm 버전 사용pnpm --version # 9.x 확인2. Docker로 로컬 CI 재현 (고급)
FROM node:20RUN npm install -g pnpm@9WORKDIR /appCOPY . .RUN pnpm install --frozen-lockfileRUN pnpm test3. CI에서 최소 검증 유지 (안전망)
- TypeScript 검증은 항상 실행
- 빠른 실패로 잘못된 코드 배포 방지
📈 예상 효과
섹션 제목: “📈 예상 효과”개발자 경험
섹션 제목: “개발자 경험”- ✅ 빠른 피드백: 로컬에서 즉시 검증
- ✅ CI 시간 단축: 50-60% 시간 절약
- ✅ 신뢰성 향상: 로컬 검증 후 배포
CI/CD 효율
섹션 제목: “CI/CD 효율”- ✅ 리소스 절약: CI 실행 시간 감소
- ✅ 비용 절감: GitHub Actions 시간 단축
- ✅ 배포 속도: 빠른 배포 사이클
🎯 결론 및 권장 사항
섹션 제목: “🎯 결론 및 권장 사항”가장 추천하는 방식: 방안 A (CI 검증 최소화)
섹션 제목: “가장 추천하는 방식: 방안 A (CI 검증 최소화)”이유:
- ✅ 구현 간단: 기존 CI 구조 최소 변경
- ✅ 신뢰성 유지: TypeScript 검증으로 안전망 제공
- ✅ 시간 절약: 50-60% CI 실행 시간 단축
- ✅ 개발자 경험: 로컬 검증 후 안심하고 배포
구현 순서:
scripts/validate-local.sh생성package.json에validate:local스크립트 추가- CI에서 테스트 단계 스킵 또는 선택적 실행
- 모니터링 및 조정
예상 소요 시간: 1-2시간
작성 일시: 2026-01-28
우선순위: High
구현 난이도: Low-Medium