사이드 프로젝트를 하다가 pr를 생성할때마다 내용을 작성하는게 귀찮아서 자동화 해줄 수 있는 방법이 없을까? 생각했다.
내가 commit을 올린 파일들을 기반으로 AI로 파일들의 내용을 요약하면 어떨까?
먼저 github action이란 뭘까?
GitHub Actions는 빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD(연속 통합 및 지속적인 업데이트) 플랫폼입니다.
나같은 경우엔 git push를 하는 순간 액션이 발동 되게 했다.
name: Auto Pull Request
on:
push:
branches:
- "feature/*"
- "bugfix/*"
- "refactor/*"
jobs:
...
- name: Create Pull Request (Auto)
if: success()
env:
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
git fetch origin main
# 1. Commits & Internal Stats (Fallback/Base)
printf "## 📝 Commits\n" > pr_body.txt
git log origin/main..HEAD --pretty=format:"- %s (%h)" >> pr_body.txt
printf "\n\n## 📊 File Changes\n\`\`\`\n" >> pr_body.txt
git diff origin/main..HEAD --stat >> pr_body.txt
printf "\`\`\`\n" >> pr_body.txt
FALLBACK_BODY=$(cat pr_body.txt)
# 2. Try AI Summary
FINAL_BODY="$FALLBACK_BODY"
if [[ -n "$GEMINI_API_KEY" ]]; then
echo "GEMINI_API_KEY is present, attempting AI summary... "
AI_SUMMARY=$(node scripts/generate-pr-summary.mjs || echo "")
if [[ -n "$AI_SUMMARY" ]]; then
FINAL_BODY="$AI_SUMMARY
---
$FALLBACK_BODY"
else
echo "AI Summary failed. Using fallback."
fi
else
echo "GEMINI_API_KEY not found. Using fallback."
fi
# Save to file to avoid shell argument limits/issues
printf "%s\n" "$FINAL_BODY" > pr_description.md
gh pr create \
--base main \
--head ${{ github.ref_name }} \
--title "PR: ${{ github.ref_name }}" \
--body-file pr_description.md \
|| echo "PR already exists or encountered an error"
위의 단계에서 모두 성공했을때 실행이 되도록 했다.
먼저 AI를 사용해야하기 때문에 API_KEY를 등록해줬다.
등록 방법
Repository > Settings > Secrets and Variables > Actions >
Repository secrets에 원하는 키 값을 넣어주면 된다.
이때 API_KEY는 Gemini나 OpenAI를 활용하면 된다.
AI_SUMMARY=$(node scripts/generate-pr-summary.mjs || echo "")
AI로 내용을 요약해야하기 때문에 스크립트를 만들어준다.
① Git 변경 사항 추출
const diff = execSync(
"git diff origin/main..HEAD -- . ':!pnpm-lock.yaml' ':!*.min.js' ':!*.svg'"
).toString();
git diff origin/main..HEAD: 메인 브랜치와 현재 작업 중인 브랜치의 차이점을 텍스트로 뽑아낸다.
제외 설정 (:!file): pnpm-lock.yaml이나 이미지 파일 등은 텍스트가 너무 길고 AI에게 필요 없으므로 제외하여 토큰 비용을 아낀다.
② 길이 제한 (Safety)
const MAX_CHARS = 100000;
// 너무 길면 자름
변경 사항이 너무 방대하면 API 요청 한도를 넘거나 에러가 날 수 있어 안전하게 자른다.
③ 프롬프트 구성 및 API 호출
```js
const prompt = `
You are a skilled senior software engineer.
...
**IMPORTANT: Please write the response in Korean (한국어).**
...
Diff: ${diffData}
`;
AI에게 "너는 시니어 개발자야. 이 코드 변경점(diff)을 보고 한국어로 요약해줘"라고 역할을 부여한다. 원하는 내용이 있으면 커스텀 하면 된다.
④ Gemini API 통신
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent...`,
// ...
);
구글의 Gemini AI 모델(gemini-2.5-flash)에게 프롬프트를 보낸다.
참고: 현재 시점(2026년 1월)에서 사용 가능한 최신 모델 버전을 작성함.
⑤ 결과 출력
console.log(cleanSummary);
스크립트가 console.log로 출력한 내용을 아까 YAML 파일의 AI_SUMMARY=$(node ...) 부분에서 변수로 받아채서 PR 본문에 넣습니다.
결과

이런식으로 auto-pr runner가 생겼고 완료가 되면

자동으로 pr 내용까지 작성해서 올려준다! (현재는 한국어로 작성해달라고 수정)