본문 바로가기

front-TEST

Github Action Cache 를 사용하여 CI/CD 최적화

로컬 환경에서 개발을 할 때는 외부 패키지를 최초에 딱 한 번만 설치하면 되지만, 항상 새롭게 셋업되는 CI 서버에서는 이 작업을 매번 다시 해야합니다.

 

깃허브에서 제공하는 캐시(Cache) 액션을 사용하여 CI 서버에서 발생할 수 있는 불필요한 패키지 재설치를 예방하여 워크플로우의 최적화를 해보았습니다.

 

 

 

 

 


 

테스트 환경

  • Runner 환경: ubuntu-20.04
  • Node.js 버전: 20.15.0 (.nvmrc 파일 기반)
  • 패키지 매니저: Yarn
  • 캐싱 대상: node_modules
  • 의존성 파일: yarn.lock

 

 

해당 레포에는 `.github/workflows` 폴더 안에 `deploy-dev/release/production.yml` (환경별로 각각의 3개의 파일이 존재) 이 있는데요. 

PR 을 생성하고 merge 를 하면 github action workflow 에 작성된 코드로 CI/CD 자동배포가 진행됩니다.

 

개발 레포에서 [development 환경 기준] 워크플로 평균 실행시간이 1분 10초 ~ 1분 40초 사이 입니다.

 

그 중에서 `의존성 설치` 와 `빌드` 쪽에서 시간 소요가 많은 것을 볼 수 있습니다.

이번에는 `의존성 설치` 하는 부분의 속도를 줄여보는 작업을 시작하겠습니다.

 

 

 

 

 

[development 환경 기준] .github/workflows` 폴더 안에 `deploy-dev.yml 파일   step 중에

`name: Install dependencies.  run: yarn ` 을 실행하는 단계를 보면, 

jobs:
  deploy_to_production:
    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20.15.0

      - name: Install dependencies  👈
        run: yarn

 

 

무려 20초가 걸리는 걸 알 수 있습니다.

 

매번 `Install dependencies` 를 하는 것 대신, 의존성의 변경이 있을 때만 딱 1번 의존성을 설치하고 해당 의존성을 캐싱해두면 많은 시간 절약을 할 수 있을 것 같은데요.

의존성을 캐싱하기 위해서는 `node_modules` 폴더를 캐싱하면 됩니다.

 

 

 

캐시 적용


 

step 에 아래와 같은 코드를 추가해줍니다.

👇 add this!
 - name: Cache node_modules
   uses: actions/cache@v3
   id: yarn-cache
  	with:
    	# 캐싱할 대상을 정합니다. (대상의 path를 지정)
   	# 여기서는 npm에서 의존성이 설치되는 디렉터리인 node_modules를 지정
   path: |
        node_modules
        .yarn/cache
    
    	# 캐싱의 기준은 key를 기준으로 합니다.
   	# 의존성이 변경되면, 함께 변경되는 파일인 package-lock.json을 key로 잡아줍니다.
        key: ${{ runner.os }}-node-modules-${{ hashFiles('**/yarn.lock') }}
      	restore-keys: |
          ${{ runner.os }}-node-modules-
    
    # key가 유효하지 않은 경우 runner의 운영체제 값과 node라는 suffix를 key로 복구합니다.
    # 결과적으로 package-lock.json이 변경되지 않았다면 캐싱된 node_modules를 사용합니다.
    # 만약 복구될 캐시가 없다면 아래에서 사용할 cache-hit는 false가 됩니다.

   

path 에 명시되어 있는 파일들이 캐싱이 되고, 캐싱된 파일을 재사용할 경우 path 에 명시되어 있는 경로에 다시 옮겨져 실행됩니다.

 

 

`cache action` 을 추가하고, 다음 step 에서 `cache hit` 을 기준으로 `Install Dependencies` 를 할지 말지 결정하는 코드도 추가해줍니다.

 - name: Install dependencies 
    if: steps.cache.outputs.cache-hit != 'true' 👈add this!
    run: yarn

 

 

 

 

 

워크플로우 실행

처음 Actions가 실행될 때 Cache가 존재하지 않기 때문에 Cache Action이 실행될때 로그가 찍힙니다.

  • (Run actions/cache@v3)
    • Cache not found for input keys: Linux-node-modules-f9a890966f638992bedf436d0fa242f47672707de2481d74488676d053e5988c, Linux-node-modules-
    • Cache Key의 형태는 우리가 지정한 ${{ runner.os }}-node-modules-${{ hashFiles('**/yarn.lock') }}

의존성 설치에는 24s 가 소요되었습니다. 

 

Post Cache actions step 은 GitHub Actions의 step이 종료되면 `actions/cache` 패키지가 워크플로우를 종료하면서 추가로 마무리하는 action입니다. 이 step에서 캐시가 저장되었음을 캐시 key와 함께 알려주고 있는데요. 그러면 캐시가 실제로 GitHub에 저장되어 있는지 확인해 봅시다.

 

GitHub Repository의 Actions -> Caches 탭을 통해 캐시 저장소로 들어가세요.

 

70 MB의 방금 설치한 의존성 파일이 캐시 된 것을 확인할 수 있습니다. workflow 에서 생성된 cache key 와 동일한 네이밍을 가지고 있는 것을 볼 수 있습니다. 

 

이번에는 저장된 캐시가 잘 동작하는지 보기 위해 `src` 파일 내부의 소스 코드를 하나 수정하고 push 를 해봅니다.  (yml 파일은 수정하지 않음)

 

상단의 Run actions/cache@v3에 따르면 캐시가 정상적으로 복원되었다고 명시되어 있습니다.. 이유는, 첫 번째 GitHub Actions가 동작할 때 만들어 둔 캐시가 있기 때문이고, 그를 복원시켰기 때문인데요.

그리고, 의존성에 변함이 없기 때문에 Install dependencies 는 실행시키지 않아서 0s 소요인 것 을 볼 수 있다.

- name: Install dependencies
    if: steps.yarn-cache.outputs.cache-hit != 'true' 👈 해당 조건문으로 실행되기 때문!
    run: yarn

 

 

 

 

 

 

 

결과


기존 dependencies 설치 소요시간 : 20 s

cache 적용 후 dependencies 설치 소요시간 : 0s + 4s (Cache node+module) + 3s (Post Cache node_modules) = 7s

  • 의존성 설치 시간: 0초 (캐시에서 복원되었으므로 설치가 불필요)
  • 캐시 검색: 4초
  • Post Cache 처리: 3초
  • 결과적으로, 7초 만에 종속성 준비가 완료되었습니다.

[구분] 캐싱 적용 전 캐싱 적용 후

Dependencies 설치 시간 20초 7초
• Cache hit 여부 해당 없음 Cache hit (100%)
• 세부 시간 분석    
캐시 검색 N/A 4초
Post Cache N/A 3초

캐싱 적용을 통해 의존성 설치에 소요되는 시간을 65% 단축하였습니다.

(20초 → 7초)

 

 

 

 

 

 

 

version upgrade

actions/cache@v3 actions/cache@v4로 업그레이드 적용.

https://github.com/actions/cache

 

GitHub - actions/cache: Cache dependencies and build outputs in GitHub Actions

Cache dependencies and build outputs in GitHub Actions - actions/cache

github.com

 

버전 v4로 올려야 한다고 합니다. actions/cache@v4 로 코드 변경해주시면 됩니다! 

 

 

 

 

 

 

 

 

 

 


 

 

참고

https://docs.github.com/ko/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows

https://github.com/actions/cache?tab=readme-ov-file

https://www.daleseo.com/github-actions-cache/

728x90
반응형