GitHub Actions란?
GitHub Actions는 GitHub 저장소에 내장된 CI/CD 플랫폼입니다. Push, PR, 스케줄 등의 이벤트에 반응해 빌드, 테스트, 배포를 자동화합니다. 이 글에서는 기본 워크플로우를 넘어 매트릭스 빌드, 재사용 가능한 워크플로우, 캐싱 전략, 시크릿 관리 등 실전 패턴을 심화합니다.
워크플로우 기본 구조
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # 같은 브랜치의 이전 실행 취소
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm lint
test:
needs: lint # lint 통과 후 실행
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm test -- --coverage
- uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage/
concurrency는 같은 브랜치에서 여러 커밋을 빠르게 Push할 때 이전 실행을 취소해 리소스를 절약합니다. needs로 Job 간 의존 관계를 명시합니다.
매트릭스 빌드
여러 환경(Node 버전, OS)에서 동시에 테스트하는 패턴입니다:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node: [18, 20, 22]
exclude:
- os: macos-latest
node: 18 # macOS + Node 18 조합 제외
include:
- os: ubuntu-latest
node: 20
coverage: true # 이 조합에만 커버리지 추가
fail-fast: false # 하나 실패해도 나머지 계속 실행
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm test
- if: matrix.coverage
run: npm run test:coverage
fail-fast: false는 하나의 매트릭스 조합이 실패해도 나머지를 계속 실행합니다. 어떤 환경에서 실패하는지 전체 그림을 파악할 수 있습니다.
캐싱 전략
의존성 설치 시간을 대폭 줄이는 캐싱 패턴입니다:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# pnpm 캐시 (setup-node 내장)
- uses: pnpm/action-setup@v2
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
# Docker 레이어 캐시
- uses: docker/setup-buildx-action@v3
- uses: docker/build-push-action@v5
with:
context: .
push: false
cache-from: type=gha
cache-to: type=gha,mode=max
# 커스텀 캐시 (빌드 결과물 등)
- uses: actions/cache@v4
with:
path: |
.next/cache
dist/
key: build-${{ runner.os }}-${{ hashFiles('src/**') }}
restore-keys: |
build-${{ runner.os }}-
type=gha는 GitHub Actions 전용 Docker 캐시 백엔드로, 별도 설정 없이 레이어 캐싱을 활용할 수 있습니다. restore-keys는 정확한 키가 없을 때 접두사 매칭으로 가장 가까운 캐시를 복원합니다.
재사용 가능한 워크플로우
여러 저장소에서 공통 CI/CD 로직을 공유하는 패턴입니다:
# .github/workflows/reusable-deploy.yml (공통 저장소)
name: Reusable Deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
image-tag:
required: true
type: string
secrets:
KUBE_CONFIG:
required: true
SLACK_WEBHOOK:
required: false
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v4
- name: Set up kubectl
uses: azure/setup-kubectl@v3
- name: Deploy to K8s
env:
KUBECONFIG_DATA: ${{ secrets.KUBE_CONFIG }}
run: |
echo "$KUBECONFIG_DATA" | base64 -d > /tmp/kubeconfig
export KUBECONFIG=/tmp/kubeconfig
kubectl set image deployment/api
api=${{ inputs.image-tag }}
kubectl rollout status deployment/api --timeout=300s
- name: Notify Slack
if: always() && secrets.SLACK_WEBHOOK
run: |
STATUS=${{ job.status }}
curl -X POST ${{ secrets.SLACK_WEBHOOK }}
-d "{"text":"Deploy $STATUS: ${{ inputs.environment }}"}"
# 호출하는 워크플로우
name: Production Deploy
on:
push:
tags: ['v*']
jobs:
deploy:
uses: org/shared-workflows/.github/workflows/reusable-deploy.yml@main
with:
environment: production
image-tag: ghcr.io/org/api:${{ github.ref_name }}
secrets:
KUBE_CONFIG: ${{ secrets.PROD_KUBE_CONFIG }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
workflow_call로 정의한 워크플로우는 다른 저장소에서 uses로 호출할 수 있습니다. 이 패턴은 K8s ArgoCD GitOps 배포와 조합하면 완전한 GitOps 파이프라인을 구축할 수 있습니다.
Docker 빌드 + 레지스트리 Push
jobs:
build-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # GHCR Push 권한
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=sha,prefix=
type=ref,event=branch
type=semver,pattern={{version}}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
metadata-action은 Git 컨텍스트(브랜치, 태그, SHA)에서 자동으로 Docker 이미지 태그를 생성합니다. platforms로 멀티 아키텍처 빌드도 가능합니다.
Environment와 보호 규칙
프로덕션 배포에 승인 프로세스를 추가합니다:
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging # 자동 배포
steps:
- run: echo "Deploying to staging..."
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production # 승인 필요 (GitHub 설정)
url: https://api.example.com
steps:
- run: echo "Deploying to production..."
GitHub 저장소 Settings → Environments에서 production 환경에 Required reviewers를 설정하면, 해당 Job이 실행되기 전 지정된 사람의 승인이 필요합니다.
Composite Action: 재사용 가능한 Step
# .github/actions/setup-project/action.yml
name: 'Setup Project'
description: 'Install dependencies and setup environment'
inputs:
node-version:
default: '20'
runs:
using: 'composite'
steps:
- uses: pnpm/action-setup@v2
with:
version: 9
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
shell: bash
- run: pnpm prisma generate
shell: bash
# 사용
jobs:
test:
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-project
with:
node-version: '20'
- run: pnpm test
반복되는 Setup 단계를 Composite Action으로 추출하면 워크플로우가 깔끔해집니다.
시크릿 관리 베스트 프랙티스
- Environment secrets: 환경별(staging/production) 분리
- OIDC: AWS/GCP에 시크릿 없이 인증 (
aws-actions/configure-aws-credentials) - GITHUB_TOKEN: 자동 생성, 권한은
permissions로 최소화 - 마스킹:
::add-mask::값으로 로그에서 민감 정보 숨기기
# OIDC로 AWS 인증 (시크릿 키 불필요)
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456:role/deploy
aws-region: ap-northeast-2
# permissions 최소 권한 원칙
permissions:
contents: read
packages: write
id-token: write # OIDC에 필요
OIDC를 사용하면 장기 시크릿(AWS Access Key)을 저장하지 않아도 됩니다. K8s 시크릿 암호화와 조합하면 전체 시크릿 체인을 안전하게 관리할 수 있습니다.
마무리
GitHub Actions는 단순 CI를 넘어 매트릭스 빌드로 다환경 테스트, 재사용 워크플로우로 조직 표준화, GHA 캐시로 빌드 최적화, Environment 보호 규칙으로 안전한 배포, OIDC로 시크릿리스 인증까지 지원하는 완전한 CI/CD 플랫폼입니다. Composite Action과 Reusable Workflow를 적극 활용해 DRY한 파이프라인을 구축하세요.