LogoSkills

pr-preflight

변경된 패키지에 대해 unit + widget + integration 테스트를 실행하고 실패 시 PR 생성을 막는 Pre-PR 게이트입니다.

/cc-dev:pr:preflight — PR 올리기 전 자동 점검#

항목내용
실행 명령/cc-dev:pr:preflight
분류개발
난이도●●○ 보통
MCP 서버patrol

한마디로#

PR(코드 합치기 요청)을 올리기 전에 "바뀐 부분이 제대로 동작하는지" 자동으로 검사해 주는 마지막 관문입니다. 공장에서 제품을 출고하기 전 마지막 품질 검사를 통과해야만 내보내는 것과 같아요. 검사에 실패하면 PR 생성이 막힙니다.

누가·언제 쓰나요#

  • 개발자가 PR을 올리기 직전에 직접 실행할 때
  • 자동화된 개발 흐름(/cc-dev:run)이 진행 중 자동으로 이 점검을 부를 때
  • 테스트 작성 작업(/cc-e2e:kick-off)을 마친 다음 단계로 넘어갈 때
  • 코드를 원격에 올리는 순간(push) 자동으로 걸리도록 설정해 둔 경우(선택 사항)

무엇을 해주나요#

이번에 바뀐 코드 묶음(패키지)만 자동으로 찾아내어, 3단계 검사를 차례로 돌립니다.

  • 1단계 — 가장 작은 단위의 동작 검사(unit)
  • 2단계 — 화면 조각이 제대로 그려지는지 검사(widget)
  • 3단계 — 실제 사용 흐름이 끝까지 이어지는지 검사(integration)

검사 결과는 사람이 읽을 수 있는 요약 보고서로 나오고, 필요하면 파일로도 저장됩니다(.claude/preflight-report-{시각}.json). 전체 통과(PASS)하면 PR을 진행해도 좋다는 신호를, 하나라도 실패하면 PR을 막는 신호를 돌려줍니다.

어떻게 쓰나요#

# 기본 — 바뀐 패키지를 자동으로 찾아 unit + widget 검사 + 가벼운 integration(@smoke)
/cc-dev:pr:preflight

# 비교 기준이 되는 base 브랜치를 직접 지정
/cc-dev:pr:preflight --base development

# 특정 패키지만 골라서 검사
/cc-dev:pr:preflight --scope feature_common_auth,feature_application_store

# integration(실제 사용 흐름) 검사 포함
/cc-dev:pr:preflight --with-integration           # 핵심만 빠르게(@smoke, 기본)
/cc-dev:pr:preflight --with-integration=full      # 바뀐 패키지의 전체 흐름 검사

# 결과를 리포트 파일로 저장
/cc-dev:pr:preflight --save-report

# 실패한 부분을 자세히 보기
/cc-dev:pr:preflight --verbose

# 실제로 돌리지 않고  " 무엇을 검사할지 "   계획만 미리 보기
/cc-dev:pr:preflight --dry-run

# 예외 — 긴급 수정(hotfix)일 때만, 사유를 적고 전체 건너뛰기
/cc-dev:pr:preflight --skip-all --reason  " 프로덕션 결제 크래시 응급 패치 "

참고로 가장 기본 단위인 unit/widget 검사는 임의로 건너뛸 수 없습니다(--skip-unit, --skip-widget은 정책상 거부되며 관리자 승인이 필요). 전체를 건너뛰는 --skip-all은 긴급 상황 전용으로, 반드시 사유(--reason)를 적어야 하고 기록이 남습니다.

안에서 무슨 일이 벌어지나요#

  1. 무엇과 비교할지 정하기 — 기준이 되는 base 브랜치를 자동으로(또는 지정한 대로) 결정합니다.
  2. 바뀐 부분 찾아내기 — 기준 대비 어떤 파일이 바뀌었는지 뽑아, 그 파일이 속한 코드 묶음(패키지)을 알아냅니다. 자동 생성된 파일이나 바뀐 코드가 전혀 없으면 일찍 마칩니다.
  3. 3단계 검사 실행 — 작은 단위 검사(unit) → 화면 조각 검사(widget) → 실제 흐름 검사(integration)를 순서대로 돌립니다. 중간에 하나라도 실패하면 거기서 멈추고 보고합니다. 테스트할 기기가 없으면 흐름 검사는 건너뛰고 경고만 남깁니다.
  4. 결과 정리·신호 반환 — 단계별 통과/실패, 바뀐 패키지 목록, 다음에 할 일을 요약해 보여주고, PR을 진행해도 되는지(허용/차단)를 알려줍니다.

⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

Triggers#

  • PR 올리기 직전 수동 실행
  • /cc-dev:run Step 8 자동 호출
  • /cc-e2e:kick-off 완료 후 다음 단계
  • lefthook pre-push 훅에서 호출 (선택)

사용법#

# 기본 — 변경 패키지 자동 감지, unit + widget 필수 + @smoke integration
/cc-dev:pr:preflight

# base 브랜치 명시
/cc-dev:pr:preflight --base development

# 특정 패키지만
/cc-dev:pr:preflight --scope feature_common_auth,feature_application_store

# integration 포함
/cc-dev:pr:preflight --with-integration           # @smoke(기본)
/cc-dev:pr:preflight --with-integration=full      # 변경 패키지의 전체 integration

# 리포트 저장
/cc-dev:pr:preflight --save-report

# 실패 상세 (verbose)
/cc-dev:pr:preflight --verbose

# Dry run — 실행 계획만 출력
/cc-dev:pr:preflight --dry-run

# 예외 — hotfix
/cc-dev:pr:preflight --skip-all --reason  " 프로덕션 결제 크래시 응급 패치 "

파라미터#

파라미터필수설명기본
--basebase 브랜치auto (upstream → development)
--scope패키지 scope 수동 지정 (콤마)auto (git diff 감지)
--with-integration[=smoke|full]integration 레이어 실행 (⚠️ Patrol 은 --flavor staging = 공유 백엔드 — 아래 참고)smoke (로컬)
--skip-integrationintegration 명시 skipdefault 행동과 동일
--skip-unit / --skip-widget정책상 거부 — 관리자 승인 필요false
--skip-all전량 skip (hotfix 전용)false
--reason⚠️--skip-all 시 필수 사유
--save-report리포트 JSON 저장false
--verbose실패 상세 덤프false
--dry-run계획만 출력false
--from-hooklefthook 호출 표시 (리포트 간결)false

실행 단계#

  1. Base 브랜치 결정 — 우선순위: --base → upstream → development → main
  2. 변경 파일 추출git diff --name-only "$BASE"..HEAD
  3. 변경 패키지 매핑
    • 파일 경로 → 위로 올라가며 pubspec.yaml 을 만난 첫 디렉토리
    • 자동 생성 파일(.g.dart, .freezed.dart)은 부수 변경으로 분류. ⛔ .patrol_test.dart 는 손으로 쓴 테스트 소스라 여기 포함하지 않는다 — 다른 실제 소스 변경과 동일하게 취급
    • 변경 없음 → 조기 종료 (PR 에 코드 변경 없음)
  4. 레이어 1: Unit 실행melos exec --scope=... -- flutter test --exclude-tags=integration
    • FAIL → 중단, 리포트, exit≠0
  5. 레이어 2: Widget 실행 — 위 명령에 포함됨 (일반 Flutter 위젯 테스트만 해당; BDD 시나리오는 Widget 레이어를 생성/실행하지 않고 Patrol E2E 로만 검증한다)
    • FAIL → 중단, 리포트, exit≠0
  6. 레이어 3: Integration 실행 (조건부)
    • --with-integration=smoke (기본) → @smoke 태그 Patrol 시나리오
    • --with-integration=full → 변경 패키지의 모든 integration
    • 디바이스 없음 → skip + 경고
    • ⚠️ 환경 확인이 디바이스 확인과 함께 온다: Patrol 은 --flavor staging 으로 공유 백엔드에 쓴다 (cc-flutter:integration-testingTestAccount 는 팀 공유 계정이다). 실행 전 cc-quality:qa-environment-hygiene 의 환경 등급을 판정하고, 공유 스테이징(E1)이면 변이 전 원본 캡처(CBM)를 전제로 실행한 뒤 /cc-quality:cleanup 으로 정리한다. 로컬 격리(E0)로 대체 가능하면 그쪽을 먼저 쓴다 (cc-dev:parallel-test-env)
    • FAIL → 중단, 리포트, exit≠0
  7. 집계 리포트 — 레이어별 PASS/FAIL, 변경 패키지 목록, 다음 단계 안내
  8. PR 진행 허용/차단 플래그 반환

출력#

  • stdout 리포트 (사람 읽기용)
  • (선택) .claude/preflight-report-{timestamp}.json
  • (skip 시) .claude/preflight-skip.log
  • exit code (0 PASS, 1 FAIL, 2 POLICY VIOLATION)

Skip 정책#

--skip-unit, --skip-widget항상 정책 위반 으로 reject. --skip-all--reason 필수 + 감사 로그 기록 + CI 가 강한 게이트로 대체 실행.

정책 상세: rules/pr-preflight-policy.md

실패 케이스#

원인대응
Base 브랜치 추정 실패--base 명시 안내 후 중단
melos 없음flutter test + 디렉토리 스캔 폴백
scenarios/*_test.dart 컴파일 실패 (step 이름 불일치)코드 생성기가 없으므로 재실행이 아니라 dart analyze 로 원인 확인 후 직접 수정
디바이스 없음 (integration 요청 시)skip + 경고 / 또는 --skip-integration 권유
자동 생성 파일만 변경패키지 scope 에서 제외, 안내
--skip-all --reason 미제공정책 위반 exit

관련#

  • 스킬 본체: skills/pr/SKILL.md
  • 정책: rules/pr-preflight-policy.md
  • 연계 커맨드: /cc-dev:run (Step 8 자동 호출), /cc-e2e:kick-off
  • 조직 테스트 표준: cc-flutter/skills/unit-testing, widget-testing, bdd-testing, integration-testing