Claude + GitHub Actions로 만든 자동 요약 워크플로우
#시작된 리뷰
최근 팀에 복직한 분이 생기면서 자연스럽게 PR 리뷰를 하기 시작했다. 리뷰 기준이나 범위를 정한 건 아니었고, 아직은 가볍게 살펴보는 정도다.
하지만 점점 작업 영역이 겹치고, 누가 어떤 작업을 했는지 빠르게 파악할 필요가 생겼다. 싱크를 맞추려면 PR을 더 자주 보고, 더 빨리 이해해야 한다는 뜻이었다.
게다가 우리 제품도 이제 MVP 단계를 어느 정도 벗어나면서, 짧은 이터레이션 단위로 기능을 빠르게 추가하고 있었다. 그만큼 PR 수도 늘어나고, 한 번의 PR이 갖는 맥락도 더 중요해졌다. 그래서 리뷰 효율을 높이기 위해 자동으로 요약해주는 워크플로우를 만들었다.
#기존 방식의 한계
처음에는 단순히 PR 템플릿만 만들어 두었다. PR이 생성되면 GitHub Workflow가 실행되어 diff와 커밋 내역을 보여주는 정도였다. PR 제목은 브랜치 이름을 따서 Feature to Dev 같은 단순한 형식으로 구성했고, 라벨도 브랜치명을 그대로 복사하는 수준이었다.
PR 템플릿은 있었지만, 요약이나 주요 변경사항, 영향도처럼 사고를 요하는 섹션은 비어 있었고 직접 채워야 했다. 사실상 형식은 있지만, 내용을 직접 써야 하는 템플릿이었다. 의미없을 정도였다.
당연히 PR을 올린 사람은 리뷰 사항을 적어야하는 것은 똑같았고 PR을 위해 쓴 시간은 쌓이고 쌓이면 불편으로 다가오기 마련이다. 리뷰어 입장에서도 PR의 내용을 빠르게 파악하기엔 여전히 부족했다.
#그래서 생각해낸 자동으로 요약해주는 PR 워크플로우
PR을 만들 때마다 내용을 쓰는 게 귀찮았고, 읽을 때도 이게 어떤 작업인지 감을 잡기 어려웠다. 이 반복적인 작업을 줄이고 싶었다.
그래서 PR이 생성되면 코드를 분석해서 제목, 요약, 변경사항, 영향도, 체크리스트 등을 자동으로 채워주는 워크플로우를 만들었다.
리뷰 봇을 한 번 만들겠다고 지원받은 엔트로픽 API key를 가지고 진행했다. 후에는 진짜로 리뷰 봇을 만들어보는 걸로하고… AI를 활용해 코드 diff를 Claude API로 분석해 JSON 형식의 구조화된 데이터를 받아오고, 그 내용을 GitHub Actions가 PR 본문에 자동으로 채워주는 방식이다.
그럼 한번 파악해보자
#구조

▲ 워크플로우 구조
- draft PR이나 skip-ai-review 라벨이 붙은 PR은 제외하는 조건을 시작으로 워크플로우가 동작한다.
- GitHub Compare API로 2-dot diff(base..head)를 우선 추출하고, 실패 시 git diff로 대체한다.
- Claude에는 100KB 이하로 요약된 diff, 변경 파일 수, 줄 수 등의 정보가 전달된다.
- 프롬프트는 JSON 응답만 받도록 구성되어 있다.
#생성되는 템플릿 예시
# 📋 PR 요약
릴리즈 자동화 및 Slack 알림 개선
## 🔄 변경사항
### ✨ 새로운 기능
- GitHub Actions 자동 릴리즈 추가
### ♻️ 리팩토링
- Slack 알림 포맷 수정
## 🎯 영향도 분석
- 영향받는 컴포넌트: github workflows
- Breaking Changes: 없음
- 성능 영향: 없음
## ✅ 리뷰 체크리스트
- [ ] 워크플로우 실행 확인
- [ ] Slack 메시지 출력 확인
## 🧪 테스트 가이드
PR 생성 후 자동 알림과 릴리즈 동작을 확인한다.
## ⚠️ 주의사항 및 리스크
- GitHub Token 권한 변경 사항
#실제 워크플로우 결과물

▲ 템플릿 예시
#AI 기반 자동 PR 요약 시스템: 핵심 구현 개념
#1. diff 추출: Compare API vs git diff
PR의 변경사항을 정확하게 추출하기 위해 두 가지 방식을 조합하여 안정성을 높였다.
git diff로 작성하여 워크플로우를 돌릴 때 만약 diff에 yml의 수정사항이 섞여있을 경우 포맷이 잘못되어서 해당 스크립트를 실행해버리는 이슈가 있었다.
항목 | GitHub Compare API (base..head) | 로컬 git diff (base...head) |
---|---|---|
개념 | 2-dot diff: base 이후부터 head까지의 변경사항. base는 제외되며, 해당 브랜치에서 발생한 모든 순방향 변경 내역을 포함. | 3-dot diff: base와 head의 **merge-base(공통 조상)**와 head 간의 차이. 즉, head 브랜치에서 순수하게 추가된 변경사항만 보여줌. |
장점 | - rebase나 force-push 이후에도 신뢰 가능한 diff 결과 제공 - GitHub 서버에서 계산되므로 속도 빠름, 추가 환경 불필요 | - 파일 필터링 등 세밀한 옵션 제어 가능 - 개발자가 로컬에서 보는 변경 내역과 가장 유사 |
단점 | - 매우 큰 PR(수백 개 파일 이상)에서는 타임아웃 또는 diff 실패 가능 - GitHub UI에서 diff 크기 제한 존재 | - CI 워크플로우에서 실행하려면 Git fetch depth 및 체크아웃 설정 필요 |
인증 | secrets.GITHUB_TOKEN 필요 (권한 있는 토큰이면 대체 가능) | 로컬 Git 환경 기반으로, 별도 인증 필요 없음 |
✨ 구현 전략
GitHub Compare API를 우선적으로 사용하여 가장 정확한 diff를 시도하고, API 실패 시 git diff 명령어를 Fallback으로 사용하여 워크플로우의 안정성을 확보
#2. Claude 프롬프트 설계: 안정적인 JSON 응답 확보
AI가 일관된 형식의 결과물을 반환하도록 프롬프트를 정교하게 설계하는 것이 중요하다.
이는 결과를 보면서 찾아가면 된다.
당신은 숙련된 코드 리뷰어입니다.
아래 Git diff를 바탕으로 다음 항목을 JSON으로 작성하세요:
- title
- summary
- changes
- ... (기타 항목들) ...
마크다운은 포함하지 말고, 아래 예시와 동일한 형식의 JSON 객체만 반환하세요.
예시 형식:
{
"title": "🔧 GitHub Actions 워크플로우 개선",
"summary": "AI 리뷰 로직을 개선하여 응답 정확도를 높였습니다."
}
핵심 포인트
- 명확한 역할 부여(Role-playing): "숙련된 코드 리뷰어" 또는 “세계 최고의 코드 리뷰어”, 영어로 한다면 “world-class code reviewer”라는 역할을 부여하여 AI의 응답 품질과 페르소나를 제어한다.
- 원샷 프롬프팅(One-shot Prompting): 예시 형식을 통해 실제 출력 예시를 제공함으로써, AI가 원하는 JSON 구조를 훨씬 더 안정적으로 준수하도록 유도한다. 예시를 제대로 적지 않을 경우 생각보다 튀는 값들을 넣게 된다.
- 부정 지시어(Negative Instruction): "마크다운은 포함하지 마세요, DO NOT, NEVER"와 같이 원치 않는 동작을 명시적으로 금지하여, 후속 파싱 단계에서 발생할 수 있는 오류를 최소화한다.
JSON 형식을 강제한 이유는 GitHub API로 분석 결과를 전달하거나, 워크플로우 내에서 데이터를 가공하기 위한 정형화된 포맷이 필수적이기 때문이다.
#3. 입력 데이터 제한: 100KB diff 제한
AI에 전달하는 diff 데이터의 크기를 100KB로 제한하는 안전장치를 두었다.
본인 팀에서 PR을 올리는 주기나 스코프를 산정해서 조절해 나가면 된다.
- 비용 제어 (Cost Control): 입력 토큰 양에 비례하는 API 비용을 예측 가능한 범위 내로 유지한다..
- 성능 유지 (Performance): 입력이 클수록 길어지는 AI의 분석 시간을 단축하여 워크플로우가 빠르게 완료되도록 한다.
또 다른 시각
대용량 PR의 경우, grep -vE와 같은 명령어로 package-lock.json 등 중요도가 낮은 파일을 필터링하여 diff 크기를 효과적으로 줄입니다.
#4. GitHub Actions 이벤트: pull_request와 pull_request_target
이 워크플로우의 핵심은 두 가지 PR 이벤트를 목적에 맞게 함께 사용하는 것이다.
항목 | pull_request | pull_request_target |
---|---|---|
토큰 제공 여부 | ✅ 자동으로 GITHUB_TOKEN 제공됨 | ✅ 자동으로 GITHUB_TOKEN 제공됨 |
토큰 권한 범위 | read 수준 (ex. PR 본문 수정 ❌) | write 수준 (ex. PR 본문 수정, 라벨 추가 가능 ✅) |
외부 PR 접근 권한 | 외부 포크 PR의 경우 제한됨 (보안 위해 코드 접근 차단됨) | 외부 포크 PR에도 접근 가능 (주의 필요) |
사용 목적 | 안전한 코드 검사, 빌드 | PR 메타데이터 수정 (본문, 라벨 등) |
즉, pull_request로 변경사항을 안전하게 읽어오고, pull_request_target으로 분석 결과를 PR에 안전하게 쓰는 구조를 통해 보안과 결과를 보장
이 외에도 라벨링 기준 설계, JSON 오류 처리, API 응답 재시도 등 여러 요소가 있지만, 위 네 가지는 yml 파일 내에서 중요한 역할을 한다.
#실패했을 땐 어떻게?
Claude 응답이 실패하면, 아래와 같은 기본 템플릿이 들어간다.
{
"title": "📝 코드 변경사항 분석 필요",
"summary": "분석을 수행할 수 없습니다.",
...,
}
기본적인 리뷰 체크리스트와 안내 문구만 포함되며, 직접 작성해야 한다.
#적용 방법
- 🔗 GIST의 YAML 파일을 .github/workflows/{원하는_이름}.yml로 저장
- GitHub Settings > Secrets에 ANTHROPIC_API_KEY 등록
- PR을 생성하면 자동으로 분석되고, 제목과 본문이 채워짐
- gist의 yml 스텝별로 주석을 달아놓았다. 참고하면서 커스텀하면 된다.
- 코드 양을 보면 딱봐도 많아보인다. 그래서 개선이 필요하다는 것이었다. 필요하다면 직접 개선해봐도 좋다.
- diff를 저장할 파일의 크기를 여기서는 100kb 정도로 제한했다 (100000 pr_diff.txt 로 찾아보면 나올 것이다) 필요하다면 늘리면 된다
#만들면서…
사실 이 워크플로우는 처음부터 체계적으로 설계된 건 아니다.
AI로 뭔가를 많이 하고 있던 시기라서 그냥 “Claude로 한번 만들어볼까?”라는 문득 떠오른 생각에서 시작되었다.
yml을 작성하는 방법이나. 각 스텝별로 필요한 로직들을 잘 몰랐고, 일단 돌아가게 만드는 게 목표였다. 그래서 바이브 코딩으로 진행했다.
그런데 결과물이 나름 잘 나왔고 괜찮다는 평도 받았다.
물론 바이브 코딩을 한다고 뚝딱 나오는 건 아니였다. 생각보다 출력 결과물을 포맷하는 과정에서 고생을 했었고 따옴표나 쌍따옴표로 인해서도 포맷이 깨지는 이슈가 있었다. 그래서 diff 파일을…
단순하게 여기서 끝나는게 아니고 내가 이후에 이를 가다듬고 더 잘 사용하기 위해서는 구조를 이해해야 했고 이를 위해 글로 한번 정리하면서 나 또한 프로세스를 파악하는 시간을 가졌다. 그러다 보니 개선할 부분도 눈에 보이기 시작했다.
#다음에 생각 중인 것들
- Slack 알림 연동
- Claude 외 다른 모델도 비교 테스트
- 라벨링 기준을 더 세분화하는 방향
- 구조 개선을 동안 재사용성 높이기 및 불필요 스텝 줄이기
#마무리하며
이 워크플로우는 리뷰를 대신해주는 도구는 아니다.
다만, PR을 더 보기 좋게 만들고, 리뷰 준비에 드는 부담을 줄여주는 데 확실히 도움이 된다.
변경 내용을 정리하고, 리뷰의 출발점을 만드는 건 개발자 본인에게도 중요한 일이다.
그걸 조금 더 쉽게, 반복 없이, 자연스럽게 할 수 있도록 만든 작은 자동화다.
누군가에게는 이 흐름이 참고가 될 수도 있겠다 싶어 이렇게 정리하게 되었다.
같은 고민을 하고 있다면, 한번 적용해보길 추천한다.
한번 해보면 어? 할만한데 라는 생각이 들 것이다.