의존성 캐싱 (Dependency Caching)

의존성 캐싱 (Dependency Caching)

매번 CI를 돌릴 때마다 패키지 매니저가 의존성을 처음부터 다시 내려받으면, 빌드가 훨씬 느려져요. GitHub Actions는 actions/cache 액션으로 의존성 캐시를 저장하고 재사용해 워크플로를 크게 가속할 수 있어요. 이 페이지에서는 캐시 액션의 동작 원리, 키 매칭 규칙, 용량 제한과 퇴출 정책까지 정리해요.

상위 문서: GitHub Actions · 워크플로 문법 · 표현식

출처: https://docs.github.com/actions/using-workflows/caching-dependencies-to-speed-up-workflows

cache 액션 사용법

actions/cache@v4는 복원 시 다음 순서로 캐시를 찾아요.

  1. 제공한 key정확히 일치(exact match)하는지 먼저 검색.
  2. 없으면 key부분 일치(prefix match)를 검색.
  3. 그래도 없고 restore-keys를 줬다면, 그 목록을 순서대로 부분 일치 검색.

key에 정확히 일치하는 캐시가 있으면 캐시 히트(cache hit), 없으면 **캐시 미스(cache miss)**예요. 미스일 때는 잡이 성공적으로 끝나면 자동으로 새 캐시가 생성돼요.

입력 파라미터

  • key필수. 캐시를 저장할 때 만들고 찾을 때 쓰는 키. 변수·컨텍스트·문자열·함수를 조합할 수 있어요. 최대 512자.
  • path필수. 캐시하거나 복원할 러너의 경로. 디렉터리·단일 파일·글로브 패턴을 지원해요. 여러 경로는 줄을 나눠 적어요.
  • restore-keyskey로 미스났을 때 대안으로 시도할 키 목록(구체적인 것 → 포괄적인 것 순서).

출력 파라미터

  • cache-hitkey가 정확히 일치했는지를 나타내는 부울.

키 만들기 — 컨텍스트·표현식 조합

캐시 키에 컨텍스트나 함수를 넣으면, 의존성이 바뀔 때마다 키가 달라져 자동으로 새 캐시가 만들어져요. 대표적인 예가 hashFiles()로 잠금 파일 해시를 키에 넣는 방식이에요.

key: npm-${{ hashFiles('package-lock.json') }}

package-lock.json이 바뀌면 해시가 달라지고(예: npm-d5ea0750) 새 캐시가 생성돼요. npm 예시 전체로 보면 이렇게 써요.

steps:
  - uses: actions/checkout@v5
  - name: Cache node modules
    id: cache-npm
    uses: actions/cache@v4
    env:
      cache-name: cache-node-modules
    with:
      # npm 캐시 파일은 Linux/macOS에서 ~/.npm
      path: ~/.npm
      key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-build-${{ env.cache-name }}-
        ${{ runner.os }}-build-
        ${{ runner.os }}-

restore-keys는 구체적 → 포괄적 순서로 나열해요. 정확히 맞는 키가 없어도, restore-keys에 부분 일치하면 가장 최근 캐시를 복원해줘요.

캐시 히트·미스 활용

steps.<id>.outputs.cache-hit로 히트 여부를 확인해, 히트 시 설치 step을 건너뛰는 식으로 최적화할 수 있어요.

- if: ${{ steps.cache-npm.outputs.cache-hit != 'true' }}
  name: List the state of node modules
  continue-on-error: true
  run: npm list
- name: Install dependencies
  run: npm install

패키지 매니저별 setup-* 액션

npm·Yarn·pnpm·pip·pipenv·Poetry·RubyGems·Go·NuGet 등 주요 패키지 매니저는 각자의 setup-* 액션(예: setup-node, setup-python, setup-go)을 쓰면 캐시 생성·복원을 최소 설정으로 자동 처리해줘요. 단순히 패키지 매니저 버전을 맞추는 용도로 그 액션을 쓰면 거의 대부분 캐시까지 덤으로 챙겨져요.

캐시 접근 제한

PR에서 트리거된 워크플로가 만든 캐시는 머지 ref(refs/pull/.../merge)를 기준으로 생성돼, 범위가 제한돼요. 따라서 PR의 캐시는 같은 PR의 재실행에서만 복원될 수 있어요. 보안 관점에서도 캐시 경로에는 접근 토큰·자격증명 같은 민감 정보를 저장하지 말아야 해요 — 저장소에 읽기 접근이 있는 누구든 PR을 만들어 캐시 내용을 열어볼 수 있으니까요.

용량 한도와 퇴출 정책

GitHub은 7일 이상 접근하지 않은 캐시를 자동으로 제거해요. 캐시 개수에는 제한이 없지만, 저장소당 총 10GB로 크기가 제한돼요. 한도에 도달하면 가장 오래 접근하지 않은 것부터 퇴출(evict)해서 공간을 확보해요. 캐시가 자주 만들어졌다 지워지는 **캐시 스래싱(thrashing)**이 발생할 수 있으니, 필요할 때 저장소 캐시 목록을 점검하고 불필요한 캐싱은 제거하는 게 좋아요.

더 알아보기