6단계
GitHub Actions 품질 게이트
25 분
GitHub Actions 품질 게이트
PR 이 머지되기 전 자동 차단. "내 로컬에서는 됐는데" 를 줄이는 가장 확실한 방법.
1. 최소 워크플로
# .github/workflows/test.yml
name: test
on:
pull_request:
push:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: "pnpm" }
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: "pnpm" }
- run: pnpm install --frozen-lockfile
- run: pnpm test --run
--frozen-lockfile 로 의존성 변조 방지.
2. 매트릭스 빌드
strategy:
matrix:
node: [20, 22]
os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v4
with: { node-version: ${{ matrix.node }} }
OS · 버전 조합 테스트. 월 무료 사용량이 빠르게 소모되므로 핵심만.
3. 캐시 활용
- uses: actions/cache@v4
with:
path: ~/.cache/pnpm
key: pnpm-${{ hashFiles('pnpm-lock.yaml') }}
Node · Playwright · Rust · Java 모두 캐시 필수. 초기 빌드 10 분 → 재실행 1 ~ 2 분.
4. E2E (Playwright)
e2e:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with: { node-version: "20", cache: "pnpm" }
- run: pnpm install --frozen-lockfile
- run: pnpm exec playwright install --with-deps chromium
- run: pnpm exec playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 7
if: always() 로 실패해도 리포트 업로드. 원인 분석 필수.
5. 실제 DB 사용 (testcontainers)
services 가 아닌 testcontainers 가 Docker-in-Docker 로 직접 PG 띄움. 별도 services 섹션 불필요.
- run: pnpm test:integration # testcontainers 자동 실행
env:
TESTCONTAINERS_RYUK_DISABLED: true # CI 에서 필요 시
6. 시크릿 관리
steps:
- run: pnpm test
env:
DATABASE_URL: ${{ secrets.TEST_DB_URL }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
Repository Settings → Secrets. 로그에 절대 echo 하지 말 것.
7. PR block 규칙
GitHub Settings → Branches → Protection rule:
main브랜치Require status checks to passlint,test,e2e모두 통과 요구Require branches to be up to date(머지 전 rebase)- Admin 우회 비활성
이 세팅만으로 "빨간 상태에서 머지" 가 구조적으로 불가능해짐.
8. 리포트 알림
- name: Slack on failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{ "text": "${{ github.repository }} main 빌드 실패: ${{ github.run_id }}" }
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
main 빌드 실패만 알림. PR 단계 알림은 소음.
9. 자주 걸리는 자리
- cache 키 부정확 —
hashFiles('pnpm-lock.yaml')기준으로만 - timeout 부족 — 첫 e2e 는 15 ~ 20 분 잡기
- Playwright install 빠뜨림 —
playwright install --with-deps chromium - 리포트 아티팩트 미업로드 — 실패 원인 파악 불가
10. 비용 절감
- Private repo: 월 2000 분 무료 (이후 과금)
- matrix 로 6 조합 × 10 분 × 일일 20 PR = 1200 분 → 월 초과 쉬움
- 핵심 조합만 + PR-only 로 제한
하고픈 말
초기 세팅 반나절이지만 이후 "내 로컬에서는 됐는데" 소요 시간 대비 회수가 압도적. 머지 게이트는 팀 규모가 커질수록 가치가 배가됨.
Next
- backend/06-api-handler-pattern
- philosophy/02-ssot-everywhere
🎉 테스트 전략과 품질 게이트 완주를 축하해요
이어서 어떤 걸 배워 볼까요?