본문 바로가기
Etc2026년 5월 6일6분 읽기

Pre-commit Hook + Git LFS — 모노레포 빌드 30초 단축한 작은 변경

YS
김영삼
조회 926
Pre-commit Hook + Git LFS — 모노레포 빌드 30초 단축한 작은 변경

핵심 요약

50명 규모 TS 모노레포에서 pre-commit hook과 Git LFS 두 가지를 손봤더니 CI 빌드가 30초 단축. 사소해 보이는 변경의 누적 효과를 정리.

1. 진단 — 어디서 시간이 새는가

# GitHub Actions 빌드 트레이스
1. checkout            8s
2. install deps       45s
3. lint               18s
4. typecheck          22s
5. unit tests         34s
6. build              28s
7. e2e                72s
total                227s

린트·타입체크가 전체 작업의 18%. 그런데 이 둘은 대부분 변경되지 않은 파일까지 검사 중이었다.

2. pre-commit hook을 빠르게 — lint-staged + husky

// package.json
{
  "scripts": {
    "prepare": "husky"
  },
  "lint-staged": {
    "*.{ts,tsx}": [
      "biome check --apply",
      "tsc --noEmit --incremental"
    ],
    "*.md": ["prettier --write"]
  }
}

# .husky/pre-commit
bunx lint-staged

핵심: 변경 파일에만 적용. CI에서도 같은 도구를 쓰면 같은 결과 보장.

3. CI 측 변경 — 변경 영향 범위만 빌드

# .github/workflows/ci.yml
- name: Detect changed files
  id: changes
  uses: tj-actions/changed-files@v45

- name: Run only affected tests
  if: steps.changes.outputs.any_changed == 'true'
  run: |
    bunx affected:test --base=origin/main

Nx·Turborepo·moon 같은 모노레포 도구가 의존 그래프 기반 영향 분석을 자동화. Turborepo 사용 시:

turbo run test --filter=...[origin/main]
turbo run build --filter=...[origin/main]

4. Git LFS — 어떤 파일에 적용

파일 유형LFS 도입
스크린샷·디자인 PNGO (모노레포에서 가장 큼)
video·gif (READMEs)O
모델 파일 (.onnx, .gguf)O
아이콘 SVGX (텍스트, 작음)
소스 코드X
git lfs install
git lfs track "*.png" "*.jpg" "*.webm" "*.gguf"
# .gitattributes 자동 생성
git add .gitattributes

5. 실측 — 변경 전후

구간변경 전변경 후
git clone (CI)14s8s
install deps45s45s
lint (변경 파일만)18s3s
typecheck (영향 범위)22s9s
tests (영향 범위)34s11s
build (영향 범위)28s14s
총합227s197s

6. 더 큰 효과 — Turborepo 캐시

리모트 캐시 활성화 시 같은 입력에 대해 빌드 결과를 다른 PR이 재사용한다.

# turbo.json
{
  "remoteCache": { "signature": true },
  "tasks": {
    "build": {
      "outputs": [".next/**", "dist/**"],
      "cache": true
    },
    "test": {
      "dependsOn": ["^build"],
      "cache": true
    }
  }
}

# CI에서 토큰 주입
TURBO_TOKEN=...  TURBO_TEAM=... turbo build

같은 코드를 여러 PR에서 빌드 안 함 → 추가 30~50% 단축.

7. 함정

  • incremental tsc 캐시 위치: .tsbuildinfo.gitignore에 없어 커밋되면 효과 사라짐. --incremental 출력 경로를 워크스페이스 외부로
  • LFS 후 재푸시: 기존 큰 파일을 LFS로 옮기려면 git lfs migrate import + force push 필요. 팀 합의 후 진행
  • 변경 감지 잘못: changed-filesmain base를 잘못 잡으면 모두 변경됨으로 판정 → 빌드 시간 회귀
  • pre-commit hook 너무 느림: 5초 넘으면 개발자가 --no-verify로 우회. 빠른 검사만

8. 추가 권장

  • concurrency 제한: concurrency: { group: ${{ github.ref }}, cancel-in-progress: true }
  • self-hosted runner: 큰 모노레포는 GitHub-hosted runner CPU 부족
  • 의존 그래프 캐시: actions/setup-nodecache: 'pnpm' 사용
  • 매트릭스 분할: 테스트가 4분 이상이면 매트릭스로 4개 병렬

9. 측정 도구

  • GitHub Actions Insights — 워크플로별 시간 분석
  • Buildkite·CircleCI — 단계별 트레이스 시각화
  • Turbo Run Summary — 캐시 적중률 리포트

10. 결론

"3초 단축" 작은 개선이 모이면 PR 1개당 30초, 50개 PR이면 25분, 1년이면 200시간. 인프라보다 자주 효과가 큰 영역.

참고

  • turbo.build/repo/docs/core-concepts/remote-caching
  • git-lfs.com

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록