
1편에서 워크플로우 구조, 트리거, job과 step을 다뤘습니다. 2편에서는 빌드 속도를 높이는 캐싱, 여러 환경을 한 번에 테스트하는 Matrix, 워크플로우를 재사용하는 방법, 그리고 실전에서 자주 쓰는 패턴들을 정리합니다.
캐싱 — actions/cache
의존성 설치는 매번 하면 시간이 많이 걸립니다. 캐시를 써두면 key가 같으면 다운로드 없이 복원합니다.
- name: 의존성 캐시
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
key가 완전히 일치하면 캐시를 복원합니다. 없으면 restore-keys에 있는 것 중 가장 최근 것으로 복원합니다. job이 끝나면 path에 지정한 경로를 key로 저장합니다.
hashFiles()는 파일의 해시를 계산합니다. package-lock.json이 바뀌면 key가 바뀌어서 캐시를 새로 만듭니다.
언어별 캐시 패턴
# Node.js
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# Python (pip)
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
# CMake / C++ (빌드 캐시)
- uses: actions/cache@v4
with:
path: build
key: ${{ runner.os }}-cmake-${{ hashFiles('**/CMakeLists.txt') }}
setup 액션들은 캐싱을 내장하고 있어서 더 간단하게 쓸 수 있습니다.
# setup 액션 내장 캐시 (권장)
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # 자동으로 npm 캐시 처리
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
Matrix 빌드
여러 환경 조합을 병렬로 테스트합니다. 각 조합마다 별도 job이 생성됩니다.
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: python --version
위 설정이면 3(OS) × 3(버전) = 9개 job이 동시에 실행됩니다.
matrix 조합 제외 / 추가
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node: ['18', '20']
exclude:
- os: windows-latest
node: '18' # 이 조합만 제외
include:
- os: ubuntu-latest
node: '20'
extra: "추가 변수" # 특정 조합에 변수 추가
fail-fast
하나가 실패해도 나머지를 계속 실행하려면 fail-fast: false를 씁니다.
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
Artifacts — 파일 저장과 공유
job 사이에 파일을 전달하거나, 빌드 결과물을 다운로드할 때 씁니다.
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: cmake -S . -B build && cmake --build build
- name: 빌드 결과 업로드
uses: actions/upload-artifact@v4
with:
name: build-output
path: build/myapp
retention-days: 7 # 보관 기간 (기본 90일)
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: 빌드 결과 다운로드
uses: actions/download-artifact@v4
with:
name: build-output
path: ./app
- run: ls ./app
재사용 가능한 워크플로우
워크플로우를 함수처럼 만들어서 다른 워크플로우에서 호출합니다.
호출 가능한 워크플로우 정의
# .github/workflows/deploy-template.yaml
name: Deploy Template
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
DEPLOY_KEY:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v4
- name: 배포
env:
DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
run: echo "${{ inputs.environment }}에 배포"
호출하는 쪽
# .github/workflows/ci.yaml
jobs:
deploy-staging:
uses: ./.github/workflows/deploy-template.yaml
with:
environment: staging
secrets:
DEPLOY_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
deploy-prod:
needs: deploy-staging
uses: ./.github/workflows/deploy-template.yaml
with:
environment: production
secrets:
DEPLOY_KEY: ${{ secrets.PROD_DEPLOY_KEY }}
환경 (Environments)
GitHub 저장소 Settings → Environments에서 환경을 만들고, 보호 규칙과 Secrets를 환경별로 분리할 수 있습니다.
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: https://my-app.com # GitHub UI에 링크로 표시
steps:
- run: echo "프로덕션 배포"
environment를 지정하면 해당 환경에 설정된 보호 규칙(승인 필요 등)이 적용됩니다.
실전 패턴
Node.js CI
name: Node.js CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test
- run: npm run build
npm ci는 npm install보다 빠르고 재현성이 높습니다. lock 파일 기반으로 정확히 설치합니다.
Python CI
name: Python CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- run: pip install -r requirements.txt
- run: pip install pytest ruff
- name: 린트
run: ruff check .
- name: 테스트
run: pytest --tb=short
Docker 이미지 빌드 & 푸시
name: Docker Build
on:
push:
tags: ['v*']
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Docker Buildx 설정
uses: docker/setup-buildx-action@v3
- name: Docker Hub 로그인
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: 메타데이터 추출
id: meta
uses: docker/metadata-action@v5
with:
images: myuser/myapp
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: 빌드 & 푸시
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
cache-from: type=gha
cache-to: type=gha,mode=max
cache-from: type=gha는 GitHub Actions 캐시로 Docker 레이어를 캐싱합니다. 재빌드 속도가 크게 빨라집니다.
PR에 코멘트 달기
- name: PR 코멘트
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '✅ 빌드 성공!'
})
릴리즈 자동 생성
name: Release
on:
push:
tags: ['v*']
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 빌드
run: |
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
- name: GitHub Release 생성
uses: softprops/action-gh-release@v1
with:
files: |
build/myapp
build/myapp.tar.gz
generate_release_notes: true # 커밋 기반으로 릴리즈 노트 자동 생성
권한 설정
기본적으로 워크플로우에 주어지는 토큰 권한을 최소화하고, 필요한 것만 열어주는 게 보안에 좋습니다.
permissions:
contents: read # 전체 기본값
jobs:
build:
permissions:
contents: write # 릴리즈 생성용
issues: write # 이슈 코멘트용
pull-requests: write
알아두면 편한 것들
워크플로우 수동 재실행
GitHub UI에서 실패한 job만 재실행하거나 전체를 다시 돌릴 수 있습니다.
워크플로우 건너뛰기
커밋 메시지에 [skip ci]나 [ci skip]을 넣으면 해당 커밋은 워크플로우가 실행되지 않습니다.
디버그 로그 활성화
저장소 Secrets에 ACTIONS_RUNNER_DEBUG=true와 ACTIONS_STEP_DEBUG=true를 추가하면 상세 로그가 찍힙니다.
실행 시간 제한
jobs:
build:
timeout-minutes: 30 # job 전체 제한
steps:
- name: 빌드
timeout-minutes: 10 # step 개별 제한
run: make build
기본 제한은 6시간입니다. 무한 루프 같은 상황을 방지하려면 명시적으로 지정하는 게 좋습니다.
정리 표
자주 쓰는 공식 Actions
| Action | 용도 |
|---|---|
actions/checkout@v4 |
코드 체크아웃 |
actions/setup-node@v4 |
Node.js 설치 + 캐시 |
actions/setup-python@v5 |
Python 설치 + 캐시 |
actions/cache@v4 |
의존성 캐시 |
actions/upload-artifact@v4 |
파일 업로드 |
actions/download-artifact@v4 |
파일 다운로드 |
docker/login-action@v3 |
Docker 레지스트리 로그인 |
docker/build-push-action@v5 |
Docker 빌드 & 푸시 |
docker/metadata-action@v5 |
Docker 태그/레이블 생성 |
actions/github-script@v7 |
GitHub API 호출 |
softprops/action-gh-release@v1 |
GitHub Release 생성 |
핵심 패턴 요약
| 패턴 | 키워드 |
|---|---|
| 의존성 캐싱 | actions/cache, setup-* 내장 cache |
| 다중 환경 테스트 | strategy.matrix |
| job 간 파일 전달 | upload-artifact / download-artifact |
| 워크플로우 재사용 | workflow_call / uses: ./.github/workflows/ |
| Docker 레이어 캐시 | cache-from: type=gha |
| 수동 실행 + 입력 | workflow_dispatch.inputs |
| 환경별 배포 | environment + Secrets |
| 조건부 실행 | if: github.ref_name == 'main' |
'블로그, 컴퓨터 > Cheatsheets' 카테고리의 다른 글
| C++ STL 정리 (2편) — 알고리즘, 이터레이터, 유틸리티 (0) | 2026.06.01 |
|---|---|
| C++ STL 정리 (1편) — 컨테이너 (0) | 2026.06.01 |
| GitHub Actions 정리 (1편) — 개념, 워크플로우 구조, 트리거 (0) | 2026.05.31 |
| CMake 정리 (2편) — 서브디렉토리, 외부 라이브러리, 실용 패턴 (0) | 2026.05.30 |
| CMake 정리 (1편) — 개념, CMakeLists.txt, 기본 빌드 (0) | 2026.05.30 |