[GitHub 100일 챌린지] Day 80 - 코드 리뷰 문화 만들기
100일 챌린지 Day 80 - 건강하고 생산적인 코드 리뷰 문화를 만들어 팀의 코드 품질과 협업을 향상시킵니다.
⏱️ 예상 학습 시간: 45-50분 📚 난이도: ⭐⭐⭐⭐ (고급)
배울 내용
- 코드 리뷰의 중요성과 원칙
- 효과적인 리뷰어 가이드
- 좋은 PR 작성자 가이드
- 코드 리뷰 체크리스트
- 건설적인 피드백 방법
- 리뷰 프로세스 자동화
시작하기 전에
이 내용은 다음 개념을 알고 있다면 더 쉽게 이해할 수 있습니다:
- ✅ [Day 79 - 팀 협업 워크플로우]
- ✅ Pull Request 작성 및 리뷰 경험
- ✅ 코드 품질에 대한 관심
- ✅ 팀 문화에 대한 이해
코드 리뷰는 기술이자 문화입니다. 좋은 리뷰 문화는 하루아침에 만들어지지 않지만, 올바른 원칙으로 시작하면 점진적으로 개선할 수 있어요!
1. 코드 리뷰란?
정의와 목적
코드 리뷰: 다른 개발자가 작성한 코드를 검토하고 피드백을 제공하는 과정
1
2
3
4
5
6
7
8
9
코드 리뷰의 목적:
┌─────────────────────────┐
│ 1. 코드 품질 향상 │
│ 2. 버그 조기 발견 │
│ 3. 지식 공유 │
│ 4. 팀 표준 유지 │
│ 5. 멘토링과 학습 │
│ 6. 버스 팩터 감소 │
└─────────────────────────┘
코드 리뷰의 효과
수치로 보는 효과:
1
2
3
4
5
6
7
연구 결과:
- 버그 발견률: 60-90% 증가
- 코드 유지보수 비용: 30-50% 감소
- 온보딩 시간: 40% 단축
- 팀 생산성: 20-30% 향상
(출처: IEEE, Microsoft Research)
2. 코드 리뷰 원칙
기본 원칙
1. 친절하게 (Be Kind)
1
2
3
4
5
6
7
8
❌ 나쁜 예:
"이 코드 엉망이네요. 다시 짜세요."
✅ 좋은 예:
"이 부분은 X 방식으로 구현하면 가독성이 더 좋을 것 같습니다.
예를 들어 다음과 같이 할 수 있습니다:
[코드 예시]
어떻게 생각하시나요?"
2. 구체적으로 (Be Specific)
1
2
3
4
5
6
7
❌ 나쁜 예:
"여기 문제 있어요."
✅ 좋은 예:
"Line 45: 이 함수는 null을 반환할 수 있어서
Line 52에서 NullPointerException이 발생할 수 있습니다.
null 체크를 추가하거나 Optional을 사용하면 좋겠습니다."
3. 건설적으로 (Be Constructive)
1
2
3
4
5
6
7
8
❌ 나쁜 예:
"이건 안 돼요."
✅ 좋은 예:
"현재 구현은 O(n²) 복잡도입니다.
해시맵을 사용하면 O(n)으로 개선할 수 있습니다:
[코드 예시]
이렇게 하면 대량의 데이터에서 성능이 크게 향상됩니다."
4. 질문하기 (Ask Questions)
1
2
3
4
5
6
❌ 나쁜 예:
"이렇게 하면 안 됩니다."
✅ 좋은 예:
"이 방식을 선택한 이유가 있나요?
저는 Y 방식도 고려해봤는데, 장단점을 비교해보면 좋을 것 같습니다."
5. 칭찬하기 (Praise Good Code)
1
2
3
4
✅ 좋은 예:
"이 에러 핸들링 방식 정말 좋네요!
사용자에게 명확한 메시지를 제공하면서
디버깅에도 필요한 정보를 로그에 남기는 부분이 훌륭합니다. 👍"
리뷰 우선순위
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1. 🔴 Critical (즉시 수정 필수)
- 보안 취약점
- 데이터 손실 가능성
- 프로덕션 크래시
2. 🟠 Major (수정 강력 권장)
- 버그
- 성능 문제
- 잘못된 로직
3. 🟡 Minor (개선 제안)
- 가독성
- 네이밍
- 스타일
4. 🟢 Nit (선택 사항)
- 사소한 스타일
- 개인 선호도
- "Nit: 여기 공백 하나 더" (무시 가능)
3. 리뷰어 가이드
리뷰 전 준비
1. 컨텍스트 파악:
1
2
3
4
5
리뷰 시작 전:
✅ PR 설명 읽기
✅ 연결된 Issue 확인
✅ 변경 범위 파악
✅ 테스트 결과 확인
2. 시간 확보:
1
2
3
4
집중 리뷰 시간:
- 방해받지 않는 환경
- 충분한 시간 (20-60분)
- 피곤하지 않은 상태
리뷰 체크리스트
기능 (Functionality):
1
2
3
4
5
6
7
8
☑ 요구사항 충족
- Issue에 명시된 기능 구현
- 엣지 케이스 처리
- 에러 핸들링
☑ 정상 동작
- 로직이 올바른가?
- 예상치 못한 부작용은?
코드 품질 (Code Quality):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
☑ 가독성
- 변수/함수명이 명확한가?
- 복잡한 로직에 주석이 있는가?
- 함수가 너무 길지 않은가?
☑ 단순성
- 불필요하게 복잡하지 않은가?
- YAGNI 원칙 준수
- DRY 원칙 준수
☑ 일관성
- 기존 코드 스타일과 일치
- 팀 컨벤션 준수
- 네이밍 컨벤션 준수
보안 (Security):
1
2
3
4
5
6
7
8
9
10
11
12
☑ 입력 검증
- 사용자 입력 검증
- SQL Injection 방지
- XSS 방지
☑ 인증/인가
- 권한 체크
- 토큰 검증
☑ 민감 정보
- 하드코딩된 비밀번호 없음
- API 키 노출 없음
성능 (Performance):
1
2
3
4
5
6
7
8
9
☑ 효율성
- 알고리즘 복잡도 적절
- N+1 쿼리 없음
- 불필요한 반복 없음
☑ 리소스
- 메모리 누수 없음
- DB 커넥션 관리
- 파일 핸들 정리
테스트 (Testing):
1
2
3
4
5
6
7
8
9
☑ 테스트 커버리지
- 주요 로직 테스트
- 엣지 케이스 테스트
- 에러 케이스 테스트
☑ 테스트 품질
- 테스트가 명확한가?
- 독립적인가?
- 빠른가?
문서 (Documentation):
1
2
3
4
5
6
7
8
☑ 코드 주석
- 복잡한 로직 설명
- Why 중심 주석
☑ 문서 업데이트
- README 업데이트
- API 문서 업데이트
- Changelog 추가
리뷰 코멘트 작성법
좋은 코멘트 구조:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. 문제 지적
2. 이유 설명
3. 대안 제시
4. (선택) 예시 코드
예시:
"이 함수는 여러 책임을 가지고 있어 SRP를 위반합니다. (문제)
이렇게 하면 테스트와 유지보수가 어려워집니다. (이유)
다음과 같이 분리하면 어떨까요? (대안)
```javascript
function validateUser(user) { ... }
function saveUser(user) { ... }
function sendWelcomeEmail(user) { ... }
``` (예시)
"
코멘트 템플릿:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 버그 지적
"🐛 Bug: [문제 설명]
재현 방법: [단계]
예상 동작: [설명]
제안: [해결 방법]"
# 성능 개선
"⚡ Performance: [현재 문제]
영향: [설명]
제안: [최적화 방법]
예상 개선: [수치]"
# 보안 이슈
"🔒 Security: [취약점]
위험도: Critical/High/Medium/Low
공격 시나리오: [설명]
해결 방법: [제안]"
# 칭찬
"👍 Great: [칭찬 내용]
특히 [구체적인 부분]이/가 인상적입니다!"
# 질문
"❓ Question: [질문]
[추가 설명이나 컨텍스트]"
# Nit (사소한 지적)
"Nit: [사소한 제안]
(필수는 아니지만 고려해보면 좋을 것 같습니다)"
4. PR 작성자 가이드
좋은 PR 만들기
1. 작은 PR:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
이상적인 PR 크기:
- 코드: 200-400 줄
- 파일: 5-10개
- 단일 기능/버그 수정
왜?
- 리뷰하기 쉬움
- 빠른 피드백
- 머지 충돌 감소
- 버그 발견 쉬움
큰 작업은 여러 PR로 분리:
PR 1: 모델 추가
PR 2: API 엔드포인트
PR 3: 프론트엔드 통합
2. 명확한 설명:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# PR 템플릿
## 📝 변경 사항
이 PR은 무엇을 하나요?
## 🎯 목적
왜 이 변경이 필요한가요?
## 🔗 관련 Issue
Closes #123
## 🧪 테스트
어떻게 테스트했나요?
- [ ] 로컬 테스트 완료
- [ ] 단위 테스트 추가
- [ ] 통합 테스트 확인
## 📸 스크린샷
(UI 변경 시)
## 📋 체크리스트
- [ ] 코드가 팀 스타일 가이드를 따릅니다
- [ ] 셀프 리뷰를 완료했습니다
- [ ] 주석을 추가했습니다 (복잡한 로직의 경우)
- [ ] 문서를 업데이트했습니다
- [ ] 테스트를 추가/업데이트했습니다
- [ ] 모든 테스트가 통과합니다
## 💡 추가 정보
리뷰어가 알아야 할 특별한 사항
3. 셀프 리뷰:
1
2
3
4
5
6
7
8
PR 제출 전 체크:
✅ 불필요한 console.log 제거
✅ 주석 처리된 코드 제거
✅ TODO 확인
✅ Lint 통과
✅ 테스트 통과
✅ 커밋 메시지 정리
✅ 변경 사항 다시 읽기
리뷰 받기
좋은 반응:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
✅ 감사 표현:
"좋은 지적 감사합니다! 수정하겠습니다."
✅ 이유 설명:
"이 방법을 선택한 이유는 X 때문입니다.
하지만 말씀하신 Y 방법도 좋네요.
성능 테스트 후 더 나은 방법을 선택하겠습니다."
✅ 질문하기:
"Z 방식도 고려했는데, 어떤 장단점이 있을까요?"
✅ 동의하지 않을 때:
"의견 감사합니다. 다만 A 이유로 현재 방식이
더 적합하다고 생각합니다. 어떻게 생각하시나요?"
피해야 할 반응:
1
2
3
4
5
6
7
8
9
10
❌ 방어적 태도:
"이게 표준 방식입니다."
"다른 코드도 다 이렇게 되어 있어요."
❌ 무시:
(코멘트에 답변하지 않음)
❌ 감정적 반응:
"왜 자꾸 지적하세요?"
"완벽한 코드는 없어요."
피드백 반영
빠른 대응:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
목표: 24시간 내 피드백 반영
1. 동의하는 코멘트:
- 즉시 수정
- "Done" 또는 "✅" 댓글
2. 논의 필요한 코멘트:
- 의견 제시
- 대안 논의
- 합의 후 수정
3. 큰 변경 필요:
- 새 커밋으로 추가
- 변경 내용 요약
4. Nit 코멘트:
- 시간 여유 시 수정
- 또는 "나중에 별도 PR로" 제안
5. 리뷰 프로세스
리뷰 타이밍
빠른 리뷰의 중요성:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
목표:
- 첫 리뷰: 24시간 이내
- 완료: 48시간 이내
이유:
✅ 컨텍스트 유지
✅ 빠른 배포
✅ 병목 현상 방지
✅ 팀 사기 향상
느린 리뷰의 문제:
❌ 작업 전환 비용
❌ 머지 충돌 증가
❌ 릴리스 지연
❌ 좌절감
리뷰 우선순위
1
2
3
4
5
6
우선순위 순서:
1. 🔥 긴급 버그 수정
2. 🚀 릴리스 차단 PR
3. 🆕 신입 개발자 PR (학습 목적)
4. 🔄 의존성 있는 PR
5. ✨ 일반 기능 PR
승인 기준
승인 (Approve):
1
2
3
4
5
6
7
8
9
언제 승인하나요?
✅ 모든 major 이슈 해결
✅ 테스트 통과
✅ 문서 업데이트
✅ Minor 이슈는 나중에 수정 가능
승인 코멘트 예시:
"LGTM! 몇 가지 nit이 있지만 별도 PR로 개선해도 좋을 것 같습니다. 👍
좋은 작업이었습니다!"
변경 요청 (Request Changes):
1
2
3
4
5
6
7
8
9
10
11
언제 변경 요청하나요?
❌ Critical 버그
❌ 보안 취약점
❌ 요구사항 미충족
❌ 아키텍처 문제
변경 요청 코멘트 예시:
"몇 가지 중요한 이슈가 있어 변경을 요청합니다:
1. [Critical] Line 45: SQL Injection 취약점
2. [Major] Line 78: Null pointer exception 가능
수정 후 다시 리뷰하겠습니다."
코멘트 (Comment):
1
2
3
4
5
언제 코멘트만 남기나요?
💬 질문
💬 제안
💬 논의 필요
💬 다른 리뷰어 대기 중
6. 리뷰 자동화
GitHub Actions 활용
자동 리뷰 할당:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# .github/workflows/auto-assign-reviewers.yml
name: Auto Assign Reviewers
on:
pull_request:
types: [opened, ready_for_review]
jobs:
assign:
runs-on: ubuntu-latest
steps:
- uses: kentaro-m/auto-assign-action@v1.2.1
with:
configuration-path: .github/auto-assign.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# .github/auto-assign.yml
addReviewers: true
numberOfReviewers: 2
reviewers:
- alice
- bob
- charlie
reviewGroups:
frontend:
- alice
- bob
backend:
- charlie
- david
코드 품질 자동 체크:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# .github/workflows/code-quality.yml
name: Code Quality
on:
pull_request:
branches: [main, develop]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Linter
run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Tests
run: npm test
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Coverage
run: npm run coverage
- name: Check Coverage
run: |
coverage=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
if (( $(echo "$coverage < 80" | bc -l) )); then
echo "Coverage is below 80%"
exit 1
fi
자동 코멘트:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# .github/workflows/pr-comment.yml
name: PR Comment
on:
pull_request:
types: [opened]
jobs:
comment:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v6
with:
script: |
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `
## 🎉 PR이 생성되었습니다!
리뷰 체크리스트:
- [ ] 코드가 요구사항을 충족하나요?
- [ ] 테스트가 충분한가요?
- [ ] 문서가 업데이트되었나요?
- [ ] 보안 이슈는 없나요?
빠른 리뷰 부탁드립니다! 🙏
`
})
7. 실전 시나리오
시나리오 1: 큰 PR
문제:
1
2
3
4
PR #123
- 파일: 50개
- 코드: 2,000줄
- 여러 기능 포함
해결:
1
2
3
4
5
6
7
8
9
10
리뷰어 코멘트:
"이 PR이 너무 커서 효과적으로 리뷰하기 어렵습니다.
다음과 같이 분리하면 어떨까요?
PR 1: 사용자 모델 추가
PR 2: 인증 API
PR 3: 프론트엔드 통합
각 PR을 순차적으로 머지하면 리뷰도 빠르고
문제 발생 시 원인 파악도 쉬울 것 같습니다."
시나리오 2: 의견 충돌
문제:
1
2
3
리뷰어 A: "이 부분은 X 방식으로 해야 합니다."
리뷰어 B: "아니요, Y 방식이 더 낫습니다."
작성자: "저는 Z 방식을 선호합니다."
해결:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1. 각자의 장단점 정리
2. 팀 표준 확인
3. 기술적 근거 제시
4. 필요시 기술 리더 참여
5. 결정 후 문서화
예시 코멘트:
"좋은 토론입니다! 각 방식의 장단점:
X 방식:
- 장점: 성능이 좋음
- 단점: 복잡함
Y 방식:
- 장점: 간단함
- 단점: 확장성 제한
Z 방식:
- 장점: 유연함
- 단점: 러닝 커브
이 경우 [이유]로 Y 방식을 선택하는 게 좋을 것 같습니다.
@tech-lead 의견 부탁드립니다."
시나리오 3: 신입 개발자 PR
상황:
1
2
3
4
신입 개발자의 첫 PR
- 기능은 동작
- 코드 품질 개선 필요
- 많은 수정 필요
좋은 리뷰:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"첫 PR 제출 축하합니다! 🎉
기능이 정상 동작하고 테스트도 잘 작성했네요.
몇 가지 개선 제안을 드립니다:
1. 변수명 개선 (Line 23)
`data` → `userData`
이유: 더 명확한 의미 전달
2. 함수 분리 (Line 45-78)
현재 함수가 여러 책임을 가지고 있어요.
다음과 같이 분리하면 좋을 것 같습니다:
[예시 코드]
3. 에러 핸들링 추가 (Line 92)
API 호출 실패 시 처리가 필요합니다.
질문 있으시면 언제든 물어보세요!
함께 더 나은 코드를 만들어봐요. 😊"
💡 초보자 팁 코드 리뷰가 처음이라면, 먼저 작은 PR부터 리뷰 받아보세요! 리뷰 댓글은 “질문”이나 “제안”으로 시작하면 부담이 덜합니다. 완벽한 리뷰는 없습니다. 계속하다 보면 자연스럽게 늘어요!
직접 해보기 (25-30분)
실습을 통해 배운 내용을 체화해봅시다!
📝 실습 1: PR 템플릿 만들기 (10분)
1
2
3
4
5
- [ ] 1. .github/pull_request_template.md 생성
- [ ] 2. "변경 내용" 섹션 추가
- [ ] 3. "테스트 방법" 섹션 추가
- [ ] 4. 체크리스트 추가
- [ ] 5. 새 PR 생성하여 템플릿 확인
📝 실습 2: 코드 리뷰 연습하기 (10분)
1
2
3
4
5
- [ ] 1. 과거 PR 하나 선택 (본인 또는 동료)
- [ ] 2. 체크리스트 기준으로 리뷰
- [ ] 3. 긍정적 피드백 3가지 찾기
- [ ] 4. 개선 제안 2가지 작성
- [ ] 5. 건설적인 톤으로 댓글 작성
📝 실습 3: 리뷰 가이드라인 문서 작성하기 (10분)
1
2
3
4
5
- [ ] 1. docs/CODE_REVIEW_GUIDE.md 생성
- [ ] 2. 리뷰어 체크리스트 추가
- [ ] 3. PR 작성자 가이드 추가
- [ ] 4. 피드백 예시 (좋은 예/나쁜 예) 추가
- [ ] 5. 팀과 공유
실습 완료 후: 이제 건강한 코드 리뷰 문화를 시작할 준비가 되었습니다!
😰 어려우시다면
이 내용이 어렵게 느껴진다면:
- 리뷰할 때 뭘 봐야 할지 모르겠는 경우
- 처음엔 체크리스트 사용하세요
- “이 코드가 이해되는가?” 하나만 봐도 충분
- 경험이 쌓이면 자연스럽게 더 많이 보게 됩니다
- 피드백이 공격적으로 느껴질까 걱정되는 경우
- “제안”이나 “질문” 형태로 표현하세요
- “이렇게 하는 게 어떨까요?” 대신 “왜 이렇게 했나요?”
- 이모지 사용으로 톤을 부드럽게
- 모든 PR에 리뷰하기 부담스러운 경우
- 중요한 PR부터 집중 리뷰
- 작은 PR은 빠르게 승인
- 팀원들과 리뷰 부담 분산
- 리뷰 받을 때 방어적이 되는 경우
- 리뷰는 코드에 대한 것, 사람에 대한 것이 아님
- 피드백은 성장의 기회
- 동의하지 않으면 예의 있게 설명
- 리뷰 시간이 너무 오래 걸리는 경우
- PR 크기를 줄이세요 (300줄 이하)
- 자동화 도구 활용 (린터, 포매터)
- 리뷰 시간 정해놓기 (하루 2회 등)
- 복습이 필요하다면
- Day 79: 팀 협업 워크플로우 복습
- 좋은 PR 사례 찾아보기
- 유명 오픈소스의 리뷰 문화 참고
꼭 기억하세요: 완벽한 리뷰 문화는 없습니다. 팀에 맞는 문화를 만들어가세요. 중요한 것은 서로를 존중하고 함께 성장하는 것입니다!
정리
완료 체크:
- 코드 리뷰의 중요성을 이해했다
- 친절하고 구체적인 리뷰를 할 수 있다
- 좋은 PR을 작성할 수 있다
- 리뷰 체크리스트를 활용할 수 있다
- 건설적인 피드백을 주고받을 수 있다
- 리뷰 프로세스를 자동화할 수 있다
- 직접 실습을 완료했다
핵심 요약:
- 원칙: 친절하게, 구체적으로, 건설적으로
- 리뷰어: 체크리스트 활용, 명확한 코멘트, 빠른 리뷰
- 작성자: 작은 PR, 명확한 설명, 셀프 리뷰, 빠른 반영
- 프로세스: 24시간 내 첫 리뷰, 우선순위 관리
- 문화: 학습 기회, 칭찬하기, 질문하기
- 자동화: GitHub Actions, 자동 할당, 품질 체크
실전 팁:
- ✅ PR은 200-400줄 이내로 유지
- ✅ 리뷰는 24시간 내 시작
- ✅ 칭찬도 적극적으로 (1:3 규칙 - 지적 1개당 칭찬 3개)
- ✅ “Nit”으로 선택적 제안 표시
- ✅ 코드가 아닌 사람 비판하지 않기
- ✅ 이모지로 분위기 부드럽게 (😊👍🎉)
- ✅ 논쟁은 오프라인이나 영상 통화로
- ✅ 팀 코드 리뷰 가이드라인 문서화
- ✅ 정기적으로 리뷰 프로세스 개선 회고
리뷰 명언:
1
2
3
4
5
6
"좋은 코드 리뷰는 코드를 개선하고,
훌륭한 코드 리뷰는 사람을 성장시킨다."
"리뷰는 찾는 게임이 아니라 함께 만드는 과정이다."
"오늘의 작은 개선이 내일의 큰 차이를 만든다."
Phase 8 완료! 🎉
축하합니다! GitHub의 협업 도구를 모두 마스터했습니다.
- Issues & Projects로 작업 관리
- Wiki로 문서화
- Discussions로 커뮤니티 운영
- Team 협업과 코드 리뷰 문화 구축
이제 여러분은 효과적인 팀 협업과 프로젝트 관리를 할 수 있습니다! 🚀
