Claude Code와 GitHub Actions로 일일 개발 업무 자동화: 내가 사용하는 3가지 워크플로
출처: Dev.to
이 글을 읽고 나면 Claude 로 새로운 이슈를 자동 분류해 주는 GitHub Actions 워크플로, 실제 커밋을 기반으로 오래된 CHANGELOG 를 매일 밤 재작성하는 작업, 그리고 PR 브랜치에서 실패한 Lint 를 자동으로 고쳐 패치를 다시 푸시하는 claude CLI 단계까지 모두 갖추게 됩니다. 세 가지 모두 오늘 바로 복사‑붙여넣기만으로 실행할 수 있으며, 제가 놓치고 있었던 API 호출로 $14 를 낭비하게 만든 정확한 라인도 보여드리겠습니다.
왜 Claude Code 를 내 노트북이 아니라 GitHub Actions CI 로 옮겼는가
먼저 직설적인 결론부터: 터미널에서 Claude Code 를 인터랙티브하게 실행하는 것은 빌드할 때는 좋지만 잡일에는 최악입니다. 잡일은 당신이 잠들어 있거나 회의 중이거나 다른 일에 컨텍스트를 전환했을 때 일어나죠. 저는 하루에 약 70분을 라벨링, 릴리즈 노트 작성, 그리고 똑같은 사소한 Lint 실패를 고치는 일에 쓰고 있었고, 이 모든 작업에 제 뇌를 쓸 필요가 없었습니다.
핵심은 @anthropic-ai/claude-code 가 비대화형 모드를 제공한다는 점입니다. claude -p "prompt" 는 헤드리스 모드로 실행돼 표준 출력에 결과를 출력하고 상태 코드로 종료합니다. 이것이 “AI 어시스턴트”와 “크론 잡” 사이의 전부 연결 고리입니다. 헤드리스로 실행되면 GitHub Actions 가 비밀 관리, 레포 체크아웃, PR 쓰기 권한 등을 이미 갖춘 무료 스케줄러가 됩니다.
실제 수치 (3주 차)
- 주당 6.2시간 회수
- Claude API 비용 월 약 $9 (CI 전용 계량키 사용, Max 플랜과 별도)
- 아래 “실수” 섹션에서 다룰 부끄러운 사건 1건
워크플로 1: Claude CLI 로 GitHub 이슈를 30초 이내에 자동 분류
가장 지루한 잡일이 가장 가치 있는 자동화 대상입니다. 새로운 이슈는 라벨이 붙지 않은 채로 방치되곤 했죠. 이제 Claude 가 이슈 본문을 읽고, 실제 라벨 세트 중에서 선택해 한 문단의 분류 코멘트를 남깁니다.
핵심 설계 선택
레포에 존재하는 실제 라벨 리스트를 gh 로 Claude 에 전달합니다. 그래서 라벨이 prio/high 인데 Claude 가 priority: P0 같은 환상을 만들지 못합니다. 모델을 실제 데이터에 기반하게 하는 것이 유용한 봇과 시끄러운 봇을 구분하는 차이점입니다.
# .github/workflows/triage.yml
name: Claude issue triage
on:
issues:
types: [opened]
permissions:
issues: write
contents: read
jobs:
triage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Triage with Claude
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BODY: ${{ github.event.issue.body }}
NUM: ${{ github.event.issue.number }}
run: |
LABELS=$(gh label list --limit 100 --json name -q '.[].name' | paste -sd ',')
SUGGESTION=$(claude -p "You are triaging a GitHub issue. \
Available labels (pick 1-3 ONLY from this list): $LABELS. \
Issue text: $BODY. \
Reply with a JSON object: {\"labels\": [...], \"comment\": \"one short paragraph\"}" \
--model claude-haiku-4-5-20251001 --output-format json | jq -r '.result')
echo "$SUGGESTION" | jq -r '.labels[]' | while read -r L; do
gh issue edit "$NUM" --add-label "$L" || true
done
echo "$SUGGESTION" | jq -r '.comment' | gh issue comment "$NUM" --body-file -
Enter fullscreen mode
Exit fullscreen mode
참고 여기서는
claude-haiku-4-5-20251001모델을 사용합니다. Opus 가 아니라 Haiku 를 쓰는 이유는 분류 작업이므로 비용이 약 10분의 1 수준이며 실행 시간도 ~4초에 불과합니다. 실제 코드를 작성하는 작업에만 비싼 모델을 사용하세요. 이 한 가지 선택만으로 이슈당 비용을 약 $0.03 → $0.004 로 낮출 수 있었습니다.
워크플로 2: Git 커밋을 기반으로 CHANGELOG.md 를 매일 밤 재작성하는 파이썬 작업
모든 프로젝트의 CHANGELOG 는 시간이 지나면 뒤처집니다. 제 경우 5주 간격이었죠. 아무도 실행하지 않는 Git 훅 대신, 매일 새벽 2시에 지난 24시간 커밋을 diff 하고 Claude 에게 인간이 읽을 수 있는 릴리즈 노트로 요약하도록 요청합니다. 그런 뒤 PR 을 열어 머지 전에 검토하도록 합니다.
또다시 중요한 점: grounding
“최근에 뭐가 바뀌었나요?” 라고 Claude 에 묻는 것이 아니라 커밋 자체를 넘겨주고, 새로운 정보를 만들어내는 것을 금지합니다. 아래 파이썬 스크립트는 프롬프트를 만들고 SDK 를 직접 호출합니다(구조화된 입력을 파싱해야 할 때 쉘보다 깔끔합니다).
# scripts/changelog.py
import subprocess, datetime, os
from anthropic import Anthropic
def commits_since(hours=24):
since = (datetime.datetime.now(datetime.timezone.utc)
- datetime.timedelta(hours=hours)).isoformat()
out = subprocess.run(
["git", "log", f"--since={since}", "--no-merges",
"--pretty=format:%h %s"],
capture_output=True, text=True, check=True,
)
return out.stdout.strip()
def summarize(commits: str) -> str:
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
msg = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=800,
messages=[{
"role": "user",
"content": (
"Turn these git commits into changelog bullets grouped "
"under ### Added / ### Fixed / ### Changed. "
"Use ONLY information present in the commit messages "
"— do not invent features. Commits:\n\n" + commits
),
}],
)
return msg.content[0].text
if __name__ == "__main__":
commits = commits_since(24)
if not commits:
print("No commits