CI/CD 기초 (4) - Cache, Secrets, and Artifacts
캐시, Secrets, artifact부터 workflow_dispatch, schedule, 상태 배지까지 실무 파이프라인에 자주 등장하는 GitHub Actions 부품들을 정리합니다.
2편과 3편으로 CI와 CD의 뼈대는 끝났습니다. 이번 편은 뼈대에 붙는 부품들입니다. 남의 저장소 워크플로를 읽을 때 이 다섯 가지를 알면 대부분 해석이 됩니다.
cache
runner는 매번 깨끗한 머신이라는 것이 CI의 장점이지만, 대가가 있습니다. 의존성을 매번 처음부터 설치한다는 것입니다. 코드 한 줄 고친 push에도 몇 분씩 설치를 기다리게 되고, 느린 CI는 사람들이 결과를 안 보게 만듭니다.
캐시는 이 설치 결과물을 실행 사이에 보관해 두는 기능입니다. setup 계열 action에는 대부분 내장되어 있어서 옵션 한 줄이면 켜집니다.
1
2
3
4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip" # requirements 파일이 안 바뀌면 설치 생략
원리는 단순합니다. 의존성 목록 파일(requirements.txt 등)의 내용을 키로 삼아 설치 결과를 저장해 두고, 다음 실행에서 파일이 같으면 저장본을 내려받아 씁니다. 파일이 바뀌면 키가 달라지므로 다시 설치합니다. “무엇이 바뀌면 다시 하는가”를 키로 표현한다는 이 원리는 Docker의 layer cache 등 다른 곳에서도 똑같이 나오므로 익혀둘 가치가 있습니다.
Secrets
3편에서 미뤄둔 부분입니다. 배포 토큰, API 키, 서버 접속 정보 같은 비밀값은 YAML에 직접 쓰면 안 됩니다. 저장소를 볼 수 있는 사람 전부와 git 히스토리에 영구히 남기 때문입니다.
GitHub 저장소의 Settings에서 Secrets and variables, Actions로 들어가 이름과 값을 등록하면, 워크플로에서 이렇게 참조합니다.
1
2
3
- run: ./deploy.sh
env:
DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
${{ ... }}는 GitHub Actions의 표현식 문법으로, 실행 시점에 값으로 치환됩니다. 3편의 if: github.ref == ...에서 이미 한 번 나온 문법입니다. Secrets의 값은 등록한 뒤에는 아무도 다시 볼 수 없고, 로그에 찍히면 자동으로 ***로 가려집니다.
한 가지 예외를 알아두면 편합니다. 같은 GitHub 안에서의 작업, 예를 들어 GitHub의 이미지 저장소(GHCR)에 push하는 것 정도는 직접 등록 없이 secrets.GITHUB_TOKEN이라는 자동 발급 토큰으로 됩니다. 5편에서 실제로 씁니다.
artifact
job이 끝나면 runner는 사라지고, 그 안에서 만든 파일도 함께 사라집니다. 빌드 결과물이나 테스트 리포트를 남기고 싶으면 artifact로 올려두어야 합니다.
1
2
3
4
- uses: actions/upload-artifact@v4
with:
name: coverage-report
path: htmlcov/
올려둔 artifact는 Actions 탭의 해당 실행 페이지에서 내려받을 수 있고, 다른 job에서 actions/download-artifact로 받아 쓸 수도 있습니다. 후자가 중요합니다. job끼리는 머신이 달라 파일을 직접 공유할 수 없으므로, build job이 만든 결과물을 deploy job이 이어받는 통로가 artifact입니다.
캐시와 헷갈리기 쉬운데 용도가 다릅니다. 캐시는 “다음 실행을 빠르게 하기 위한 재료”라서 없어도 그만이고, artifact는 “이번 실행이 만든 결과물”이라서 그 자체가 목적입니다.
workflow_dispatch와 schedule
지금까지 쓴 event는 push와 pull_request였습니다. 실무에서 자주 만나는 두 가지가 더 있습니다.
1
2
3
4
on:
workflow_dispatch: # Actions 탭에 수동 실행 버튼이 생긴다
schedule:
- cron: "0 0 * * *" # 매일 UTC 0시(한국 오전 9시)에 실행
workflow_dispatch는 사람이 버튼을 눌러 실행하는 트리거입니다. 재배포, 일회성 작업, 그리고 3편의 Continuous Delivery처럼 “준비는 자동, 실행은 사람”인 단계에 씁니다.
schedule은 cron 문법으로 주기 실행을 겁니다. 코드 변경과 무관하게 도는 작업, 예를 들어 매일 밤의 데이터 갱신이나 의존성 취약점 점검에 씁니다. 시각이 UTC 기준이라는 점만 주의하면 됩니다.
트리거는 겹쳐 쓸 수 있습니다. push, pull_request, workflow_dispatch를 모두 걸어두고 “평소엔 자동, 필요하면 수동”으로 운영하는 것이 흔한 구성입니다.
상태 배지
저장소 README 상단에서 자주 보는 초록색 “passing” 배지는 GitHub Actions가 제공하는 이미지입니다. Actions 탭에서 워크플로를 선택하고 우측 메뉴의 “Create status badge”를 누르면 마크다운이 복사됩니다.
1

기능적으로는 장식이지만, “이 저장소는 자동 검사가 돌고 있고 지금 초록이다”를 저장소에 들어온 사람에게 한눈에 알려주는 역할을 합니다.
정리
| 부품 | 용도 |
|---|---|
| cache | 의존성 설치 결과를 실행 사이에 보관해 시간 단축 |
| Secrets | 비밀값을 YAML 밖에 두고 ${{ secrets.NAME }}으로 참조 |
| artifact | job의 결과물을 보관하고 job 사이에 전달 |
| workflow_dispatch | 수동 실행 버튼 |
| schedule | cron 주기 실행, UTC 기준 |
| 배지 | README에 CI 상태 표시 |
부품까지 갖췄으니 남은 것은 조립입니다. 다음 편에서 작은 앱 하나로 테스트부터 이미지 배포까지 전체 파이프라인을 만듭니다.