πŸ™

GitHub Webhook은 μ–΄λ–»κ²Œ λ™μž‘ν•˜λ‚˜?

git push β†’ HTTP POST β†’ CI/CD 트리거

GitHub Webhook은 Repository Settings > Webhooksμ—μ„œ URL을 λ“±λ‘ν•˜λ©΄ λ™μž‘ν•©λ‹ˆλ‹€. 이벀트 λ°œμƒ μ‹œ GitHubκ°€ ν•΄λ‹Ή URL둜 JSON payload와 ν•¨κ»˜ HTTP POSTλ₯Ό λ³΄λƒ…λ‹ˆλ‹€. X-Hub-Signature-256 ν—€λ”λ‘œ HMAC μ„œλͺ…을 ν¬ν•¨ν•˜μ—¬ μš”μ²­μ˜ μ§„μœ„λ₯Ό 검증할 수 μžˆμŠ΅λ‹ˆλ‹€. μˆ˜μ‹  μ„œλ²„λŠ” 200 OKλ₯Ό 10초 내에 λ°˜ν™˜ν•΄μ•Ό ν•˜λ©°, μ‹€νŒ¨ μ‹œ GitHubκ°€ μžλ™μœΌλ‘œ μž¬μ‹œλ„ν•©λ‹ˆλ‹€.

ꡬ쑰 λ‹€μ΄μ–΄κ·Έλž¨

사전 μ„€μ •
πŸ‘€
Repository Owner
Settings → Webhooks → Add
πŸ™
GitHub
URL + Secret μ €μž₯
이벀트 λ°œμƒ μ‹œ
πŸ‘¨β€πŸ’»
개발자
git push
πŸ™
GitHub
push event 감지
HTTP POST
X-Hub-Signature-256
X-GitHub-Event: push
πŸ–₯️
λ‚΄ μ„œλ²„
μ„œλͺ… 검증 CI/CD 트리거
μ„œλͺ… 검증 (λ³΄μ•ˆ ν•„μˆ˜!):
expected = HMAC-SHA256(secret, body)
actual = request.headers["X-Hub-Signature-256"]
secure_compare(expected, actual) # true → 정상
μ£Όμ˜μ‚¬ν•­
  • 10초 λ‚΄ 200 OK λ°˜ν™˜ ν•„μš” (무거운 μ²˜λ¦¬λŠ” λ°±κ·ΈλΌμš΄λ“œλ‘œ)
  • μ‹€νŒ¨ μ‹œ GitHubκ°€ μžλ™ μž¬μ‹œλ„ (μ΅œλŒ€ 3회)
  • Settings → Webhooksμ—μ„œ 전솑 둜그 확인 κ°€λŠ₯
  • 둜컬 개발 μ‹œ ngrok ν•„μš” (곡개 URL이 μ—†μœΌλ―€λ‘œ)

λ™μž‘ 흐름

1

Repository Settingsμ—μ„œ Webhook URL + Secret 등둝

2

κ°œλ°œμžκ°€ git push μ‹€ν–‰ (λ˜λŠ” PR 생성, Issue λ“±)

3

GitHubκ°€ λ“±λ‘λœ URL둜 HTTP POST 전솑 (JSON payload)

4

X-Hub-Signature-256 ν—€λ”λ‘œ HMAC-SHA256 μ„œλͺ… 포함

5

μˆ˜μ‹  μ„œλ²„κ°€ μ„œλͺ… 검증 ν›„ 이벀트 처리 (CI/CD 트리거 λ“±)

6

μ„œλ²„κ°€ 200 OK λ°˜ν™˜ (10초 λ‚΄, μ‹€νŒ¨ μ‹œ GitHub μž¬μ‹œλ„)

μž₯점

  • 섀정이 맀우 간단
  • 이벀트 μ’…λ₯˜ μ„Έλ°€ν•˜κ²Œ 선택 κ°€λŠ₯
  • μ‹€νŒ¨ μ‹œ μžλ™ μž¬μ‹œλ„
  • GitHub UIμ—μ„œ 전솑 둜그 확인 κ°€λŠ₯

단점

  • 곡개 URL ν•„μˆ˜ (둜컬 개발 μ‹œ ngrok ν•„μš”)
  • 10초 νƒ€μž„μ•„μ›ƒ (무거운 μ²˜λ¦¬λŠ” λΉ„λ™κΈ°λ‘œ)
  • μ„œλͺ… 검증 κ΅¬ν˜„ ν•„μš”
  • 이벀트 μˆœμ„œ 보μž₯ μ•ˆ 됨

μ‚¬μš© 사둀

CI/CD μžλ™ λΉŒλ“œ (Jenkins, GitHub Actions) Slack/Discord μ•Œλ¦Ό μžλ™ 배포 트리거 μ½”λ“œ 리뷰 봇