배포 후 같은 종류의 버그가 또 났습니다. 회고에서 누군가 말합니다. "이거 리뷰 때 봤어야 했는데, 그냥 승인 눌렀어요." 또 다른 PR은 변경 800줄짜리라 아무도 제대로 못 보고 통과됐습니다. 한편 한 개발자가 퇴사하자 그가 만든 모듈을 아무도 이해하지 못해 손을 못 댑니다. PR과 코드 리뷰는 '형식적 승인 절차'가 아니라, 품질을 만들고 지식을 퍼뜨리고 한 사람 의존을 줄이는 핵심 협업 메커니즘입니다.
- 1PR이 "머지 전 품질·협업 관문"임을 설명할 수 있다
- 2코드 리뷰가 버그 발견 외에 지식공유·집단소유에 기여함을 설명할 수 있다
- 3머지 게이트(CI·승인·보호 규칙)의 구성을 설명할 수 있다
- 4리뷰 병목의 원인(큰 PR·편중)과 해소법을 제시할 수 있다
확대
위 그림처럼 PR은 Draft → Open → Changes Requested → Approved → Merged 상태를 거치며, CI 실패나 리뷰 거부 시 해당 단계에서 차단됩니다.
PR — 합치기 전에 거치는 관문
요청 + 리뷰 + 자동검사가 한자리에
PR(Pull Request, GitLab은 Merge Request)은 "내 브랜치를 main에 합쳐 주세요"라는 요청이자, 합치기 전 검증이 모이는 곳입니다.
PR 한 건에 모이는 것:
1. 변경 내용(diff)과 "무엇을·왜" 설명
2. 연결된 이슈(이 PR이 푸는 백로그 항목)
3. 자동 검사(CI): 빌드·테스트·린트·보안 스캔 결과
4. 리뷰어의 코멘트·승인/변경요청
5. 머지 가능 여부(게이트 통과 시 머지 버튼 활성)
PR은 Git 기본 흐름의 브랜치를 브랜치 전략의 규칙대로 main에 합치는 마지막 관문입니다. 여기서 막으면 비용이 싸고(아직 prod 아님), 통과시키면 CI/CD 파이프라인을 타고 배포로 흘러갑니다. PM·인프라는 PR 상태로 "이 기능이 머지됐나(=배포 후보인가)"를 추적합니다.
리뷰가 만드는 것 — 버그를 넘어
리뷰의 진짜 가치는 지식과 집단 소유
리뷰의 표면 목적은 버그·결함을 일찍 잡는 것이지만, 더 큰 가치는 사람과 조직에 있습니다.
- 지식 공유: 리뷰어가 그 코드를 이해하게 됨 → "한 사람만 아는 코드"가 줄어듦.
- 집단 소유(collective ownership): 코드가 '내 것'이 아니라 '우리 것'이 됨.
- bus factor 완화: 한 명이 빠져도 팀이 멈추지 않음(오프닝의 퇴사 문제 예방).
- 일관성: 패턴·스타일이 팀 표준으로 수렴.
- 온보딩: 신규 멤버가 리뷰를 통해 코드베이스와 관례를 배움.
그래서 좋은 리뷰 문화는 "통과/반려"의 권력 행사가 아니라, 함께 코드를 더 낫게 만드는 대화입니다. 리뷰 코멘트는 사람이 아니라 코드를 향하고, 칭찬과 질문을 섞습니다. PM·인프라 관점: 리뷰가 살아있는 팀은 지식이 분산돼 있어 장애·이탈에 강합니다.
확대
위 그림처럼 리뷰어는 정확성, 가독성, 성능, 보안, 테스트 커버리지의 5가지 축을 기준으로 코드를 점검합니다.
머지 게이트와 리뷰 흐름 — 직접 점검
머지 게이트가 제대로 걸려 있는지, 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
보호 규칙:
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) 보호 규칙의 변경(해제·복원)은 감사 로그와 알림으로 추적해 '풀어둔 채 방치'를 막습니다. 장애 대응을 막는 게이트는 우회 문화를 만들고, 그 문화가 게이트 자체보다 더 큰 위험이 됩니다.
확대
위 그림처럼 좋은 리뷰는 질문형·긍정 포함·우선순위 표시로 코드를 향하고, 인신공격·단정형·완벽주의는 팀 문화를 해칩니다.
인프라/플랫폼 엔지니어로서 당신은 머지 게이트의 설계자입니다 — 브랜치 보호 규칙(필수 승인·CI 통과·서명), 자동 검사 파이프라인(테스트·린트·보안 스캔·IaC 검증)을 구성해 "검증 안 된 코드는 main에 못 들어온다"를 시스템으로 보장합니다. 특히 인프라 코드(Terraform·K8s 매니페스트)도 PR·리뷰·자동 검증(plan diff)을 거치게 해 '클릭 한 번 운영 사고'를 막습니다. PM은 PR 상태와 리뷰 흐름으로 기능 진행을 추적하고, 리뷰 병목을 칸반 vs 스크럼 vs 워터폴의 WIP 관점으로 진단해 팀의 처리 흐름을 건강하게 유지합니다.
이것으로 Phase 3(버전관리·협업)을 마칩니다. 다음 Phase에서는 머지된 코드가 자동으로 빌드·테스트·배포되는 길 — CI/CD와 릴리스 전략을 다룹니다.
실전 랩으로 손에 익히기: PR 코드리뷰 실습 — PR 크기·리뷰 렌즈·승인/변경요청 결정을 직접 판단합니다.