GitHub Actions가 느려지면 Runner 성능부터 의심하기 쉽지만 실제로는 매 실행마다 의존성을 다시 받고, 같은 브랜치의 오래된 빌드를 끝까지 수행하고, 캐시와 Artifact를 혼동해서 시간이 늘어나는 경우가 많습니다.
최적화는 단계별 실행시간을 측정한 뒤 의존성 캐시 → 중복 실행 취소 → Job 구조 → 테스트 병렬화 순서로 적용하는 편이 좋습니다.
핵심 요약
- Cache는 재생성 가능한 의존성·중간 파일, Artifact는 보존·전달할 결과물에 사용합니다.
- Cache Key에는 OS, 도구 버전, Lockfile Hash를 포함합니다.
- restore-keys는 부분 일치를 허용하므로 오래된 의존성의 안전성을 검토합니다.
- concurrency로 같은 브랜치의 이전 실행을 취소하면 Runner 낭비를 줄일 수 있습니다.
- Cache에는 Token, Credential, 서명되지 않은 민감 파일을 넣지 않습니다.
1. 먼저 실행시간을 분해한다
단계확인대표 개선
| Checkout·Setup | 도구 설치 시간 | Setup Action의 내장 캐시 |
| Dependency | 네트워크 다운로드 | Lockfile 기반 Cache |
| Compile | 증분 빌드 가능성 | 빌드 캐시·Job 재구성 |
| Test | 느린 Suite·Flaky Test | Shard·Matrix·격리 |
| Upload | 과도한 파일 크기 | 필요한 Artifact만 압축 |
2. Lockfile 기반 캐시
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: package-lock.json
- run: npm ci
공식 setup-* Action은 npm, Gradle, Maven, pip 등 대표 패키지 관리자의 캐시를 간단히 구성합니다. 직접 actions/cache를 사용할 때는 다음처럼 키를 설계합니다.
- uses: actions/cache@v4
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
기존 Cache 내용은 수정되지 않으며 새 Key에서 새 Cache가 만들어집니다. 너무 넓은 경로를 저장하면 업로드·복원 시간이 절약 시간보다 길어질 수 있습니다.
3. 중복 실행 취소
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
PR에 연속 Push가 들어오면 이전 Commit의 CI 결과는 대개 필요하지 않습니다. Workflow와 Ref를 함께 Group으로 사용하면 다른 Workflow까지 실수로 취소하는 일을 줄일 수 있습니다. Release Branch나 배포 Workflow는 진행 중 실행을 취소하면 안 될 수 있으므로 정책을 분리합니다.
4. Cache와 Artifact 구분
구분CacheArtifact
| 목적 | 다음 실행 속도 향상 | 결과 보존·Job 간 전달 |
| 없어도 빌드 가능 | 예 | 후속 Job에 필요할 수 있음 |
| 예시 | npm·Gradle 다운로드 | JAR, Coverage, Test Report |
| 보안 | 신뢰하지 않은 입력으로 취급 | 보존 기간과 접근권한 확인 |
5. Matrix와 병렬화
Matrix는 OS·런타임 버전 호환성 검사에 유용하지만 조합이 곱셈으로 늘어납니다. 모든 PR에 전체 Matrix를 실행하기보다 빠른 필수 검사와 Nightly 전체 검사를 분리합니다.
- 단위 테스트는 Shard별 시간이 비슷하도록 과거 실행시간으로 배분합니다.
- 빌드 결과를 Artifact로 한 번 만들고 후속 검사가 재사용하게 합니다.
- needs를 검토해 독립 Job이 불필요하게 직렬화되지 않게 합니다.
- 변경 경로에 따라 문서·프런트·백엔드 Workflow를 분리합니다.
6. 캐시 보안 주의
GitHub 문서는 Cache에 Secret이나 Credential을 저장하지 말라고 안내합니다. PR이나 Fork에서 복원 가능한 Cache는 신뢰할 수 없는 입력으로 봐야 하며, Cache Poisoning 가능성도 고려합니다.
- 실행 파일·스크립트 Cache는 생성 주체와 Trigger를 제한합니다.
- 낮은 신뢰도의 PR에서는 Restore-only 정책을 검토합니다.
- Dependency 설치 후 Lockfile 검증과 무결성 검사를 유지합니다.
- Secret이 들어갈 수 있는 홈 디렉터리 전체를 Cache하지 않습니다.
7. 개선 체크리스트
- 최근 20회 실행의 단계별 중앙값과 P95를 기록합니다.
- Cache Hit·Miss와 복원 시간을 측정합니다.
- PR용 Concurrency로 오래된 실행을 취소합니다.
- 필수 검사와 Nightly Matrix를 분리합니다.
- Artifact 경로·크기·보존 기간을 줄입니다.
- 변경 후 전체 시간과 실패·Flaky 비율을 함께 비교합니다.
공식 자료
정리: 빠른 CI는 큰 Runner보다 반복 작업을 제거하는 설계에서 시작합니다. Lockfile 기반 Cache와 Branch별 Concurrency를 먼저 적용하고, 측정값을 기준으로 Job 병렬화와 Matrix 범위를 조정하세요.
'개발 자동화 & 생산성 도구' 카테고리의 다른 글
| 5편 사내 RAG + 자동화 시스템 운영 전략 — 안정성·정확도·속도를 모두 잡는 실무 운영법 (0) | 2025.12.05 |
|---|---|
| 4편 사내 문서 요약/검색 자동화 시스템 구축기 (RAG·vLLM·FastAPI 기반) (0) | 2025.12.05 |
| 3편 개발자용 AI 워크플로우 추천 — 실제로 효과 본 단계별 흐름 (0) | 2025.12.05 |
| 2편 반복 업무를 자동화한 사례 — 진짜로 시간을 절반으로 줄인 프로젝트들 (0) | 2025.12.05 |
| 1편 Vibe Coding으로 만드는 실용 앱: 사내 비용 정산 자동화 앱 구축기 (0) | 2025.12.05 |