codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
에듀›테스트 전략과 품질 게이트›6단계

6단계

GitHub Actions 품질 게이트

0회 조회

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 pass
  • lint, test, e2e 모두 통과 요구
  • Require branches to be up to date (머지 전 rebase)
  • Admin 우회 비활성

이 세팅만으로 "빨간 상태에서 머지" 가 구조적으로 불가능해짐.

8. 컨벤션 감사 스텝

차단 항목은 빌드·테스트·lint 만이 아니다. 팀 규약을 검사하는 셸 스크립트도 평범한 스텝으로 끼울 수 있다. 종료 코드 1 이면 잡 실패 → §7 의 브랜치 보호가 걸려 있으면 머지 차단.

scripts/audit.sh — 변경된 파일에서 금지 패턴을 찾는다:

#!/usr/bin/env bash
set -euo pipefail

# PR 에서 바뀐 파일만 대상
files=$(git diff --name-only origin/main... -- '*.ts' '*.tsx')
[ -z "$files" ] && exit 0

# 디버그 console.log · 남은 TODO 마커
if echo "$files" | xargs grep -nE 'console\.log|// *TODO' 2>/dev/null; then
  echo "::error::금지 패턴 발견 — 머지 전 정리할 것"
  exit 1
fi
echo "audit ok"

워크플로에 잡으로 추가하고, fetch-depth: 0 으로 diff 비교 대상을 확보한다:

audit:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
      with: { fetch-depth: 0 }   # origin/main 비교용 히스토리
    - run: bash scripts/audit.sh

마지막 한 단계 — Settings → Branches 보호 규칙의 Require status checks 목록에 audit 잡을 추가한다. 이러면 리뷰어가 깜빡해도 금지 패턴이 들어간 PR 은 기계적으로 막힌다. i18n 키 정합·내부 링크 점검 같은 불변식 검사도 같은 틀로 얹는다.

주의: 감사 스크립트는 빠르고 결정적이어야 한다. 어쩌다 빨갛게 뜨는 감사는 팀이 게이트를 불신하게 만들고, 결국 우회로 이어진다.

9. 리포트 알림

- 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 단계 알림은 소음.

10. 자주 걸리는 자리

  • cache 키 부정확 — hashFiles('pnpm-lock.yaml') 기준으로만
  • timeout 부족 — 첫 e2e 는 15 ~ 20 분 잡기
  • Playwright install 빠뜨림 — playwright install --with-deps chromium
  • 리포트 아티팩트 미업로드 — 실패 원인 파악 불가

11. 비용 절감

  • Private repo: 월 2000 분 무료 (이후 과금)
  • matrix 로 6 조합 × 10 분 × 일일 20 PR = 1200 분 → 월 초과 쉬움
  • 핵심 조합만 + PR-only 로 제한

하고픈 말

초기 세팅 반나절이지만 이후 "내 로컬에서는 됐는데" 소요 시간 대비 회수가 압도적. 머지 게이트는 팀 규모가 커질수록 가치가 배가됨.

Next

  • backend/06-api-handler-pattern
  • philosophy/02-ssot-everywhere

← 5단계

Playwright E2E

🎉 테스트 전략과 품질 게이트 완주를 축하해요

이어서 어떤 걸 배워 볼까요?

다음: 웹 보안의 기초 — JWT · OAuth · OWASP →전체 강좌 둘러보기