동작하는 코드
GitHub Flow 전체 흐름을 한 번에 실습합니다.
1단계: 이슈 만들기
gh issue create \
--title "about 페이지 추가" \
--body "사이트에 소개 페이지가 없습니다. 추가해주세요."
출력:
https://github.com/username/my-project/issues/1
2단계: 브랜치 만들기
git checkout main
git pull # 항상 최신 main에서 시작
git checkout -b feature/1-about-page
이슈 번호를 브랜치 이름에 포함하면 추적이 쉽습니다: feature/1-about-page
3단계: 작업 + 커밋
echo "<h1>소개</h1><p>안녕하세요!</p>" > about.html
git add about.html
git commit -m "feat: about 페이지 추가 (closes #1)"
직접 수정하기
4단계: Push + PR 생성
git push -u origin feature/1-about-page
gh pr create \
--title "feat: about 페이지 추가" \
--body "## 변경 사항
- about.html 추가
## 관련 이슈
closes #1
## 체크리스트
- [x] 기능 구현
- [x] HTML 유효성 확인
- [ ] 모바일 테스트"
5단계: 코드 리뷰 피드백 받기
리뷰어가 이런 코멘트를 달았다고 가정합니다:
"about.html의 소개 문구를 더 구체적으로 써주세요."
6단계: 피드백 반영
# 수정
echo "<h1>소개</h1><p>DaleSchool에 오신 것을 환영합니다!</p>" > about.html
git add about.html
git commit -m "fix: about 페이지 소개 문구 수정 (리뷰 반영)"
git push
# PR에 자동으로 반영됩니다
피드백 반영 후 리뷰어에게 재검토 요청:
gh pr review --request-review @reviewer-username
7단계: Merge + 정리
PR 승인 후:
gh pr merge --squash # feature 커밋들을 하나로 합쳐서 병합
git checkout main
git pull # 병합된 내용 가져오기
git branch -d feature/1-about-page # 로컬 브랜치 삭제
두 번째 PR: 수정 사이클 더 연습
# CI 실패 시 수정 사이클
gh pr checks 1 # CI 상태 확인
출력:
Some checks were not successful
✗ CI / test (1m 30s)
✓ CI / lint (45s)
# 실패한 테스트 수정
vim about.test.js
git add about.test.js
git commit -m "test: about 페이지 테스트 추가"
git push
gh pr checks 1 # 다시 확인
"왜?" — GitHub Flow가 널리 쓰이는 이유
GitHub Flow는 단순합니다. 핵심 규칙은 하나입니다:
main 브랜치는 항상 배포 가능한 상태여야 한다.
그래서:
- 직접 main에 push하지 않는다
- 모든 작업은 feature 브랜치에서
- 항상 PR을 통해서만 main에 합친다
main ──────────────────────────────→ (항상 안정, 언제든 배포 가능)
↑ merge PR ↑ merge PR
feature-1 ──────→ feature-2 ────→
Conventional Commits 규칙
타입(범위): 변경 내용
타입:
feat 새 기능 추가
fix 버그 수정
docs 문서 변경
style 코드 포맷 (기능 변경 없음)
refactor 리팩토링 (기능 변경 없음)
perf 성능 개선
test 테스트 추가/수정
chore 빌드 시스템, 패키지 등 기타
ci CI/CD 설정
# 좋은 커밋 메시지 예시
git commit -m "feat(auth): Google OAuth 로그인 추가"
git commit -m "fix(cart): 장바구니 수량 업데이트 버그 수정"
git commit -m "docs(api): 인증 엔드포인트 문서 추가"
git commit -m "refactor(user): UserService 클래스 분리"
git commit -m "test(login): 로그인 폼 유효성 검사 테스트 추가"
브랜치 보호 규칙
GitHub에서 main 브랜치를 보호하는 설정 (Settings → Branches):
- Require pull request reviews: 최소 N명 승인 필요
- Require status checks: CI 통과 필수 (실패 시 merge 불가)
- Restrict pushes: 직접 push 차단
이 설정이 있으면 git push origin main이 거부됩니다.
흔한 실수
실수 1: 오래된 main에서 브랜치 생성
# 나쁜 습관: 오래된 main에서 브랜치 생성
git checkout main
git checkout -b feature/new # main이 최신인지 확인 안 함
# 좋은 습관
git checkout main
git pull # 항상 최신화 후 브랜치 생성
git checkout -b feature/new
실수 2: PR 본문 없이 생성
# 리뷰어가 맥락을 모름
gh pr create --title "업데이트"
# 리뷰어가 이해할 수 있는 PR
gh pr create \
--title "feat: 검색 자동완성 추가" \
--body "## 변경 사항
자동완성 드롭다운 구현
## 관련 이슈
closes #45
## 테스트 방법
1. 검색창에 글자 입력
2. 드롭다운 확인"
실수 3: 너무 큰 PR
# 피하세요: 50개 파일 변경
# 리뷰하기 어렵고 충돌 위험 높음
# 권장: 하나의 목적, 작은 단위
# feature/login-ui → login UI만
# feature/login-api → login API만
# 나눠서 PR 생성
실수 4: 피드백 반영 후 리뷰 재요청 안 하기
수정 후 push만 하고 리뷰어에게 알리지 않으면 리뷰어가 모릅니다. GitHub에서 "Re-request review" 버튼을 클릭하거나:
gh pr review --request-review @reviewer
심화 학습
Git Flow vs GitHub Flow vs Trunk-based
세 가지 주요 워크플로우:
| | Git Flow | GitHub Flow | Trunk-based | | --------- | ---------------------------------------------- | --------------------- | ------------- | | 브랜치 수 | 많음 (main, develop, feature, release, hotfix) | 적음 (main + feature) | 최소 (main만) | | 복잡도 | 높음 | 중간 | 낮음 | | 배포 빈도 | 낮음 (릴리스 주기) | 높음 | 매우 높음 | | 적합 | 버전 기반 소프트웨어 | 웹 서비스 | 고급 CI/CD 팀 |
GitHub Flow가 대부분의 웹 서비스 팀에 적합합니다.
PR 자동화: GitHub Actions
PR이 열리면 자동으로 테스트가 실행되도록 설정:
# .github/workflows/ci.yml
name: CI
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: "20"
- run: npm install
- run: npm test
이 설정으로 PR 생성/업데이트 시 자동으로 테스트가 실행되고 결과가 PR에 표시됩니다.
:::details{title="PR 리뷰 문화"] 좋은 코드 리뷰의 원칙:
리뷰어:
- 코드가 아닌 로직/패턴을 검토
- 구체적이고 건설적인 피드백
- "왜?" 질문으로 이해 돕기
- 칭찬도 아끼지 않기
작성자:
- 리뷰 피드백을 개인 공격으로 받아들이지 않기
- 피드백에 대한 이유 설명
- 수정 후 re-request review
- 대화로 해결 (코멘트 쓰레드) :::
- GitHub에 저장소를 만들고 이슈 하나를 생성하세요.
- 이슈 번호를 포함한 브랜치 이름으로 작업하고 커밋하세요 (예:
feature/1-about-page). - Conventional Commits 형식으로 커밋 메시지를 작성하고 PR을 만드세요.
- PR 본문에 변경 내용, 관련 이슈, 체크리스트를 포함하세요.
gh pr merge --squash로 병합하고 main을 pull해서 최신화하세요.
Q1. GitHub Flow에서 main 브랜치에 대한 올바른 설명은?
- A) 개발자가 직접 push해서 최신 상태를 유지한다
- B) 항상 배포 가능한 안정적인 상태를 유지해야 한다
- C) 테스트가 실패해도 기능이 완성되면 merge한다
- D) 하나의 PR만 동시에 열 수 있다