infra
Platform

모듈 맵

[SW Eng] PR과 코드 리뷰 — 머지 전 품질 관문이 만드는 것

0 / 38 완료

펼치기
0 / 38 완료0%

PM·SRE를 위한 소프트웨어 엔지니어링 · 14 / 38

[SW Eng] PR과 코드 리뷰 — 머지 전 품질 관문이 만드는 것

Pull Request 흐름, 코드 리뷰가 품질·지식공유에 기여하는 원리, 머지 게이트(CI·승인·보호 규칙)를 PM·인프라 관점에서 정리합니다

🚨INCIDENT ALERT
HIGH

배포 후 같은 종류의 버그가 또 났습니다. 회고에서 누군가 말합니다. "이거 리뷰 때 봤어야 했는데, 그냥 승인 눌렀어요." 또 다른 PR은 변경 800줄짜리라 아무도 제대로 못 보고 통과됐습니다. 한편 한 개발자가 퇴사하자 그가 만든 모듈을 아무도 이해하지 못해 손을 못 댑니다. PR과 코드 리뷰는 '형식적 승인 절차'가 아니라, 품질을 만들고 지식을 퍼뜨리고 한 사람 의존을 줄이는 핵심 협업 메커니즘입니다.

이번 챕터에서 배울 것
  • 1PR이 "머지 전 품질·협업 관문"임을 설명할 수 있다
  • 2코드 리뷰가 버그 발견 외에 지식공유·집단소유에 기여함을 설명할 수 있다
  • 3머지 게이트(CI·승인·보호 규칙)의 구성을 설명할 수 있다
  • 4리뷰 병목의 원인(큰 PR·편중)과 해소법을 제시할 수 있다

PR 라이프사이클 — Draft부터 Merged까지 상태 흐름확대 위 그림처럼 PR은 Draft → Open → Changes Requested → Approved → Merged 상태를 거치며, CI 실패나 리뷰 거부 시 해당 단계에서 차단됩니다.

PR — 합치기 전에 거치는 관문

💡개념

요청 + 리뷰 + 자동검사가 한자리에

PR(Pull Request, GitLab은 Merge Request)은 "내 브랜치를 main에 합쳐 주세요"라는 요청이자, 합치기 전 검증이 모이는 곳입니다.

TEXT
PR 한 건에 모이는 것:
  1. 변경 내용(diff)과 "무엇을·왜" 설명
  2. 연결된 이슈(이 PR이 푸는 백로그 항목)
  3. 자동 검사(CI): 빌드·테스트·린트·보안 스캔 결과
  4. 리뷰어의 코멘트·승인/변경요청
  5. 머지 가능 여부(게이트 통과 시 머지 버튼 활성)

PR은 Git 기본 흐름의 브랜치를 브랜치 전략의 규칙대로 main에 합치는 마지막 관문입니다. 여기서 막으면 비용이 싸고(아직 prod 아님), 통과시키면 CI/CD 파이프라인을 타고 배포로 흘러갑니다. PM·인프라는 PR 상태로 "이 기능이 머지됐나(=배포 후보인가)"를 추적합니다.

리뷰가 만드는 것 — 버그를 넘어

💡개념

리뷰의 진짜 가치는 지식과 집단 소유

리뷰의 표면 목적은 버그·결함을 일찍 잡는 것이지만, 더 큰 가치는 사람과 조직에 있습니다.

  • 지식 공유: 리뷰어가 그 코드를 이해하게 됨 → "한 사람만 아는 코드"가 줄어듦.
  • 집단 소유(collective ownership): 코드가 '내 것'이 아니라 '우리 것'이 됨.
  • bus factor 완화: 한 명이 빠져도 팀이 멈추지 않음(오프닝의 퇴사 문제 예방).
  • 일관성: 패턴·스타일이 팀 표준으로 수렴.
  • 온보딩: 신규 멤버가 리뷰를 통해 코드베이스와 관례를 배움.

그래서 좋은 리뷰 문화는 "통과/반려"의 권력 행사가 아니라, 함께 코드를 더 낫게 만드는 대화입니다. 리뷰 코멘트는 사람이 아니라 코드를 향하고, 칭찬과 질문을 섞습니다. PM·인프라 관점: 리뷰가 살아있는 팀은 지식이 분산돼 있어 장애·이탈에 강합니다.

코드 리뷰 체크리스트 — 정확성·가독성·성능·보안·테스트 5축확대 위 그림처럼 리뷰어는 정확성, 가독성, 성능, 보안, 테스트 커버리지의 5가지 축을 기준으로 코드를 점검합니다.

코드 리뷰 판단 — 무엇을 보고 어떻게 굴릴까
PR이 너무 커서 리뷰가 형식적800줄 PR은 '형식 승인'으로 통과돼 버그가 새 나간다. 200~400줄 이하로 쪼개라. 작은 PR = 깊은 리뷰 + 빠른 머지. 'PR 크기가 리뷰 품질을 정한다'
무엇을 우선 볼까정확성·보안 먼저(버그·취약점), 그다음 가독성·테스트. 스타일·포매팅은 린터/포매터에 위임 — 사람은 기계가 못 잡는 것에. '스타일 논쟁은 도구로 끝낸다'
리뷰가 며칠씩 안 됨(블로킹)PR 대기시간이 길면 컨텍스트 손실·머지 충돌. 리뷰 SLA(예: 1일)·작은 PR로 회전을 빠르게. '리뷰 지연은 팀 속도를 죽인다'
지적을 막을까 통과시킬까버그·보안·설계 결함=blocking, 취향·사소한 개선=non-blocking(nit:). 모든 코멘트를 머지 차단으로 쓰면 리뷰가 무기가 된다. '막을 것과 제안할 것을 구분'
리뷰어가 도메인을 모름작성자가 PR 설명에 '무엇을·왜·어떻게 테스트했나'를 적어 리뷰를 돕는다. 리뷰는 지식 공유·집단 소유의 기회 — 버그 잡기만이 목적이 아님
자동 검사 vs 사람 리뷰 경계테스트·린트·취약점 스캔은 CI 게이트로 자동, 사람은 설계·맥락·의도에. '기계가 잡을 건 기계가, 사람은 사람만 잡을 것을'

머지 게이트와 리뷰 흐름 — 직접 점검

1브랜치 보호 규칙과 PR 크기·대기시간 점검

머지 게이트가 제대로 걸려 있는지, PR이 너무 크거나 오래 묶이지 않는지 점검합니다. 인프라/플랫폼팀이 설정·모니터링합니다.

로컬 터미널
# main 브랜치 보호 규칙 확인(필수 승인·CI 통과 강제 여부)
gh api repos/:owner/:repo/branches/main/protection --jq '.required_pull_request_reviews, .required_status_checks'

# 열린 PR의 크기(변경 줄 수)와 리뷰 상태·생성 시각
gh pr list --state open --json number,additions,deletions,createdAt,reviewDecision
OUTPUT
보호 규칙:
  required_approvals: 1        ← 최소 1명 승인 필수(OK)
  required_status_checks: ci   ← CI 통과 필수(OK)

열린 PR:
  #142  +812 -30   3일 전  REVIEW_REQUIRED   ← 거대 PR + 3일 대기(병목!)
  #150  +45  -12   2시간 전 APPROVED          ← 작고 빠름(이상적)
gh pr list --state open --json number,additions,createdAt,reviewDecision
🔍실행 후 확인할 것
  • 보호 규칙에 required_approvals와 CI가 없으면 → 검증 안 된 코드가 main 직행 가능. 인프라가 즉시 보호 규칙을 건다(직접 푸시 금지)
  • PR 변경 줄 수가 400+이면 "제대로 리뷰 불가" 신호 — 리뷰어가 대충 승인하게 됨. 작게 쪼개도록 요청(한 PR=한 관심사)
  • PR 평균 대기시간(생성→머지)이 길면 리뷰 병목 → 리뷰어 로테이션·응답 SLA·자동검사 강화로 해소. 흐름이 막히면 칸반 vs 스크럼 vs 워터폴의 WIP 관점으로 진단
  • CI가 빨간데 머지된 흔적이 있으면(강제 머지) → 게이트 우회. 누가 언제 우회했는지 추적하고 정책을 강화

상황: 큰 기능을 한 PR(800줄)로 올렸는데, 리뷰어가 양에 압도돼 핵심 로직을 놓치고 승인합니다. 그 결과 같은 유형의 버그가 거르지 못한 채 반복 배포됩니다.

원인: PR이 너무 커서 사람이 실질적으로 리뷰할 수 없습니다. 연구·경험칙상 리뷰 효과는 PR이 작을수록 급격히 좋아지고, 수백 줄을 넘으면 '형식 승인(rubber-stamp)'으로 전락합니다.

진단:

로컬 터미널
gh pr view 142 --json additions,deletions,files --jq '{lines: (.additions+.deletions), files: (.files|length)}'
# {lines: 842, files: 23} → 한 번에 리뷰 불가 규모

해결: 큰 작업은 여러 작은 PR로 분할합니다 — "스키마 변경 → API → UI"처럼 단계로 쪼개면 각 PR이 리뷰 가능해지고, Git 기본 흐름에서 본 선택적 롤백도 쉬워집니다. 자동화로 사람의 부담을 덜어, 린트·포맷·테스트는 CI가 잡고 리뷰어는 설계·로직·예외처리에 집중하게 합니다. 리뷰 체크리스트(인수기준 충족? 예외 처리? 테스트 추가?)를 PR 템플릿에 넣는 것도 효과적입니다.

심화 — 게이트는 통과를 강제할 뿐, 검토를 강제하지 못한다

💡개념

심화: 승인이 형식이 되는 순간들 — 규칙의 구멍과 부작용

보호 규칙과 CI를 다 걸어도 '제대로 읽었는가'는 시스템이 보장하지 못합니다. 게이트를 설계하는 사람이라면, 규칙이 놓치는 구멍과 규칙이 만들어내는 부작용까지 알아야 합니다.

  • 승인 뒤에 얹은 커밋(stale approval): 승인을 받은 PR에 커밋을 추가로 푸시하면? 설정에 따라 기존 승인이 그대로 유지돼, 아무도 안 본 코드가 승인된 채 머지됩니다. '새 커밋 푸시 시 기존 승인 무효화(dismiss stale approvals)' 옵션은 인프라가 챙겨야 할 보호 규칙의 디테일입니다.
  • 지표의 역습: 리뷰 대기시간을 KPI로 재기 시작하면 빨라지는 것은 검토가 아니라 승인입니다 — 코멘트 0개짜리 LGTM이 늘어납니다. 대기시간과 함께 '코멘트 없는 승인 비율' 같은 반대 지표를 같이 봐야 게이트가 형식화되는 것을 조기에 감지할 수 있습니다.
  • 필수 승인 수는 팀 규모의 함수입니다: 필수 승인 2명은 리뷰어 풀이 열 명일 때와 세 명일 때 전혀 다른 규칙입니다. 작은 팀의 과한 승인 수는 안전이 아니라 상시 병목이 되고, 결국 우회 관행을 만듭니다. 조직이 바뀌면 규칙도 재조정 대상입니다.
  • 리뷰 시간의 대부분은 읽는 시간이 아니라 왕복 대기입니다: 코멘트→수정→재확인 한 왕복에 하루씩 걸리는 조직이라면, 규칙이 아니라 왕복 수를 줄여야 합니다 — 올리기 전 셀프 리뷰로 뻔한 지적을 미리 제거하고, 논쟁이 예상되는 설계는 PR 전에 짧은 대화로 합의합니다. 이건 도구 설정이 아니라 작성자의 습관 영역입니다.

규칙은 리뷰의 하한선을 만들 뿐입니다 — 상한선은 문화가 만듭니다.

상황: 프로덕션 장애 중, 3줄짜리 수정 PR이 CI까지 통과하고 대기 중입니다. 그런데 결제 모듈은 코드 오너 승인이 필수인데 CODEOWNERS에 시니어 한 명만 등록돼 있고, 그가 휴가입니다. 장애가 길어지자 결국 관리자 권한으로 보호 규칙을 우회해 머지했고 — 일주일 뒤 보니 그때 풀어둔 규칙이 아직 꺼진 채였습니다.

원인: 게이트가 평시만 가정하고 설계됐습니다. (1) 코드 오너가 1명 = 승인 경로의 단일 장애점(SPOF), (2) 긴급 우회(break-glass) 절차가 없어 우회가 기록 없는 임기응변으로 일어남, (3) 우회 후 원복을 사람 기억에 맡겨 보호가 풀린 채 방치됐습니다.

진단:

로컬 터미널
gh api repos/:owner/:repo/branches/main/protection --jq '.required_pull_request_reviews'
# require_code_owner_reviews: true + CODEOWNERS 오너 1명 → SPOF 확인
git log main --since='1 week' --format='%an %s' | grep -v 'Merge pull request'
# 규칙이 풀린 기간의 직접 푸시 흔적 감사

해결: (1) CODEOWNERS는 핵심 경로마다 개인이 아니라 팀(최소 2명 이상) 으로 지정합니다. (2) 긴급 배포용 break-glass 절차를 미리 문서화합니다 — 누가 어떤 조건에서 우회할 수 있고, 우회는 자동으로 기록되며, 사후 24시간 내 리뷰를 보완한다까지. (3) 보호 규칙의 변경(해제·복원)은 감사 로그와 알림으로 추적해 '풀어둔 채 방치'를 막습니다. 장애 대응을 막는 게이트는 우회 문화를 만들고, 그 문화가 게이트 자체보다 더 큰 위험이 됩니다.

코드 리뷰 문화 — Do vs Don't 피드백 방식확대 위 그림처럼 좋은 리뷰는 질문형·긍정 포함·우선순위 표시로 코드를 향하고, 인신공격·단정형·완벽주의는 팀 문화를 해칩니다.

💼
실무 맥락
현업 패턴

인프라/플랫폼 엔지니어로서 당신은 머지 게이트의 설계자입니다 — 브랜치 보호 규칙(필수 승인·CI 통과·서명), 자동 검사 파이프라인(테스트·린트·보안 스캔·IaC 검증)을 구성해 "검증 안 된 코드는 main에 못 들어온다"를 시스템으로 보장합니다. 특히 인프라 코드(Terraform·K8s 매니페스트)도 PR·리뷰·자동 검증(plan diff)을 거치게 해 '클릭 한 번 운영 사고'를 막습니다. PM은 PR 상태와 리뷰 흐름으로 기능 진행을 추적하고, 리뷰 병목을 칸반 vs 스크럼 vs 워터폴의 WIP 관점으로 진단해 팀의 처리 흐름을 건강하게 유지합니다.

이것으로 Phase 3(버전관리·협업)을 마칩니다. 다음 Phase에서는 머지된 코드가 자동으로 빌드·테스트·배포되는 길 — CI/CD와 릴리스 전략을 다룹니다.

실전 랩으로 손에 익히기: PR 코드리뷰 실습 — PR 크기·리뷰 렌즈·승인/변경요청 결정을 직접 판단합니다.

지식 확인

퀴즈 — 8문제

Q1

Pull Request(PR)의 핵심 목적으로 가장 적절한 것은?

Q2

코드 리뷰가 '버그 발견' 외에 주는 핵심 가치는?

Q3

'머지 게이트(브랜치 보호 규칙)'의 예로 적절한 것은?

Q4

리뷰가 병목이 되어 PR이 며칠씩 묶일 때의 바람직한 대응은?

Q5

린트·포맷·테스트는 CI 자동검사에 맡기고, 사람 리뷰는 무엇에 집중해야 하는가?

Q6

리뷰 품질과 속도를 동시에 높이는 PR 작성 습관은?

Q7

[심화] 승인을 받은 PR에 작성자가 커밋을 추가로 푸시했다. 게이트 설계자가 반드시 챙겨야 할 보호 규칙의 디테일은?

Q8

[심화] 프로덕션 장애 중 3줄짜리 핫픽스 PR이 CI는 통과했지만 필수 코드오너(시니어 1명)가 휴가라 4시간째 머지 못 하고, 결국 관리자 권한으로 보호 규칙을 우회했다. 근본 원인과 재발 방지로 옳은 것은?

0 / 8 답변

🧪 실습으로 확인하기

PR 코드리뷰 — 무엇을 보고 어떻게 승인·변경요청하나

중급

PR을 리뷰 가능한 크기로 만드는 판단부터, diff를 보는 우선순위(정확성·경계조건 > 테스트 > 설계 > 가독성 > 스타일과 상시 보안 렌즈), 차단·제안을 구분한 존중하는 코멘트와 approve/request-changes 결정 기준까지 코드리뷰의 실무 기준을 세운다.

50📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요