
Dependabot의 PR을 Claude Code가 자동으로 리뷰하게 만드는 GitHub Actions
요약
Dependabot의 의존성 업데이트 PR을 Claude Code가 자동으로 분석하고 리뷰 댓글을 달아주는 GitHub Actions 구축 방법을 소개합니다. 라이브러리 개요, 변경 사항, 파괴적 변경 여부 및 리스크를 자동으로 조사하여 개발자의 리뷰 부담을 줄여줍니다.
핵심 포인트
- Claude Code를 활용한 의존성 업데이트 자동 리뷰 워크플로우 구축
- pull_request_target 트리거를 통한 API 키 및 쓰기 권한 확보
- 라이브러리 사용 위치 및 리스크 평가 자동화
- 보안을 고려한 GitHub Actions 구성 방식 설명
서론
Dependabot을 사용하고 있으면 의존성 패키지(dependency package) 업데이트 PR이 매일같이 날아옵니다. 감사한 일이기도 하지만, 하나하나 진지하게 리뷰하려고 하면 다음과 같은 문제에 직면합니다.
- 애초에 어떤 라이브러리이며, 우리 코드의 어디에서 사용되고 있는가
- CHANGELOG / 릴리스 노트(release note)에 파괴적 변경(breaking changes)은 없는가
- 메이저(major) / 마이너(minor) / 패치(patch) 중 무엇이며, 리스크가 어느 정도인가
매번 수동으로 조사해야 하므로 은근히 소모가 큽니다. 결과적으로 "일단 모아서 merge"하거나 "방치해서 쌓아두기" 중 하나가 되기 쉽습니다.
그래서 본 기사에서는 Dependabot이 PR을 생성하면, Claude Code가 1차 리뷰를 자동으로 작성하여 PR에 댓글을 달도록 하는 GitHub Actions를 만듭니다. anthropics/claude-code-action을 사용하여 "라이브러리 개요·업데이트 내용·파괴적 변경·사용 위치·리스크 평가·권장 액션"을 정해진 포맷으로 게시하는 구성입니다.
인간의 리뷰를 대체하려는 것이 아니라, "최종 판단 전의 조사 업무"를 대신 수행하게 하는 것이 목적입니다.
완성된 형태의 동작
- Dependabot이 의존성 업데이트 PR을 open 한다
- 워크플로우(workflow)가 실행되고, Claude Code가 PR의 diff·본문·코드베이스를 조사한다
- 구조화된 리뷰 결과가 PR 댓글로 자동 게시된다
실제로 게시되는 댓글의 이미지는 다음과 같습니다.
### 📦 라이브러리 개요
foo는 HTTP 클라이언트 라이브러리로, 본 프로젝트에서는 API 호출 전반에 이용하고 있습니다.
### 📝 업데이트 내용
...
워크플로우 전체
먼저 전체 코드를 보여드린 후, 포인트를 순서대로 설명하겠습니다.
name: Dependabot PR Review
on:
pull_request_target:
...
pull_request가 아니라 pull_request_target인 이유
포인트 1: 이 부분이 이 워크플로우에서 가장 중요한 부분입니다.
일반적인 CI라면 on: pull_request를 사용하지만, Dependabot이 만든 PR에서 pull_request를 사용하면 GITHUB_TOKEN은 read-only가 되며, 시크릿(secret)도 기본적으로 전달되지 않습니다. 이는 "포크(fork)나 봇(bot)으로부터의 PR이 멋대로 시크릿을 훔치거나 쓰지 못하도록 하기 위한" GitHub의 보안 사양입니다.
하지만 이번 경우에는 다음과 같은 이유로 read-only 상태로는 곤란합니다.
ANTHROPIC_API_KEY(Claude를 호출하기 위한 API 키)를 시크릿에서 읽고 싶다- 리뷰 결과를 PR에 **댓글로 작성(comment) = 쓰기 권한(write permission)**이 필요하다
그래서 pull_request_target을 사용합니다. 이것은 PR의 코드가 아니라, 베이스 리포지토리(base repository, 머지 대상 브랜치)의 컨텍스트에서 동작하는 트리거이며, 시크릿에 대한 액세스와 read/write 토큰을 사용할 수 있습니다.
on:
pull_request_target:
types: [opened]
types: [opened]로 한정한 이유는, PR이 생성된 첫 번째 1회만 리뷰하면 충분하기 때문입니다 (커밋(commit)마다 리뷰를 던지면 API 비용이 늘어납니다).
pull_request_target의 위험성과 이를 차단하는 가드
포인트 2: pull_request_target은 강력한 만큼 위험합니다. 시크릿과 쓰기 권한을 가진 상태로 동작하기 때문에, 만약 PR의 head 코드(즉, 외부에서 유입된 코드)를 무심코 실행하면 시크릿을 탈취당하는 전형적인 취약점으로 이어질 수 있습니다.
이를 차단하는 것이 작업(job) 서두의 if 조건과 최상위 레벨의 permissions: {}입니다.
permissions: {} # 우선 기본적으로 모든 권한을 박탈
jobs:
review:
...
각각의 의미는 다음과 같습니다.
permissions: {}: 워크플로우 전체의 기본 권한을 비웁니다. 그 후 작업 단위로 필요한 최소한의 권한만 다시 부여합니다. "기본 전체 허용"을 피하는 정석적인 방법입니다.
(최상위 레벨) -
: 실행자가 Dependabot일 때만 동작하도록 설정합니다. 사람이나 다른 bot의 PR에서는 트리거되지 않도록 합니다. github.actor == 'dependabot[bot]'
:github.event.pull_request.head.repo.full_name == github.repository
PR 브랜치가 동일한 리포지토리에 있을 때만 동작하게 합니다. Dependabot의 PR은 동일 리포지토리 내의 브랜치에서 생성되므로 이 조건을 통과하지만, 포크(Fork)된 리포지토리에서 "나는 Dependabot이다"라고 사칭하며 들어오는 PR은 여기서 차단됩니다. pull_request_target을 사용하여 시크릿(Secret)을 다룰 때 가장 중요한 가드(Guard)입니다.
작업(Job)의: 댓글 게시에 필요한 permissions인 pull-requests: write / issues: write와, 코드를 읽기 위한 contents: read만 허용합니다.
나아가, 후술할 claude_args를 통해 Claude가 사용할 수 있는 도구(Tool)를 읽기 작업 및 PR 댓글 작성으로만 제한하고 있으므로, "업데이트된 의존성 패키지 자체를 실행하는" 것과 같은 동작은 수행하지 않습니다.
포인트 3: head를 명시적으로 checkout 하기
pull_request_target은 베이스 브랜치(Base branch)의 컨텍스트에서 동작하기 때문에, actions/checkout을 그대로 사용하면 머지(Merge) 대상이 되는 코드가 체크아웃되어 PR의 변경 내용이 로컬로 가져와지지 않습니다. 리뷰 대상인 PR의 차이점(Diff)을 보기 위해서는 head의 SHA를 명시적으로 지정해야 합니다.
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
여기서 "외부 코드를 가져오는" 행위가 발생하므로, 포인트 2의 동일 리포지토리 판정이 더욱 중요해집니다. Dependabot의 동일 리포지토리 PR로 한정했기 때문에 안심하고 head를 가져올 수 있습니다.
포인트 4: claude-code-action 설정의 핵심
- uses: anthropics/claude-code-action@v1
if: env.ANTHROPIC_API_KEY != ''
env:
...
각 설정의 핵심 포인트입니다.
: API 키가 설정되지 않은 환경에서는 action을 스킵합니다. 키를 등록하지 않은 포크(Fork)나, 설정 전의 리포지토리에서 워크플로우가 실패하는 것을 방지하기 위한 안전장치입니다. if: env.ANTHROPIC_API_KEY != ''
:allowed_bots: "dependabot[bot]"
claude-code-action은 기본적으로 bot이 생성한 이벤트에 반응하지 않을 수 있으므로, Dependabot의 PR에 대해 동작할 수 있도록 명시적으로 허용합니다.
: Claude가 사용할 수 있는 도구를 화이트리스트(Whitelist)로 제한합니다. 여기서는 claude_args의 --allowedTools를 통해 gh pr diff / gh pr view (PR 읽기), gh pr comment (결과 게시), Read / Grep / Glob (코드베이스 조사), WebFetch (CHANGELOG 등 취득)만 허용합니다. 임의의 쉘 명령어를 실행하게 하지 않는 것이 보안상 매우 중요합니다.
: 폭주 및 비용 초과를 방지하기 위한 턴(Turn) 수 상한 설정입니다. --max-turns 30
포인트 5: 리뷰 내용을 결정하는 프롬프트
리뷰의 품질은 프롬프트에 달려 있습니다. 위 워크플로우의 prompt와 같이, "리뷰 절차", "리뷰 관점", "출력 포맷"을 나누어 작성하면 매번 일관된 구조화된 리뷰를 받을 수 있습니다.
절차: gh pr diff / gh pr view로 차이점과 릴리스 노트를 확인 → 부족할 경우 WebFetch로 CHANGELOG를 취득 → Grep/Glob으로 사용처를 특정하는 조사 순서를 명시합니다.
관점: 라이브러리 개요, 업데이트 내용, 파괴적 변경(Breaking Changes), 사용처, 리스크 평가, 권장 액션의 6가지 항목을 반드시 채우도록 합니다.
출력: 섹션 제목이 포함된 마크다운(Markdown) 포맷을 고정합니다.
마지막으로 게시 방법의 팁이 하나 있습니다. 리뷰 본문에는 줄바꿈, 백틱(backtick), 특수 문자가 많이 포함되어 있기 때문에, gh pr comment --body "..."와 같이 본문을 직접 전달하면 셸(shell) 이스케이프 문제로 인해 형식이 깨지기 쉽습니다. 임시 파일에 내용을 작성한 후 --body-file을 사용하여 게시하도록 하면 안전합니다.
Dependabot 측 설정 (덤)
이 워크플로우는 "Dependabot이 PR을 생성한다"는 것을 전제로 하므로, .github/dependabot.yml 측의 설정도 가볍게 살펴보겠습니다. 최소 구성은 다음과 같습니다.
version: 2
updates:
- package-ecosystem: npm
...
labels:로 지정한 라벨은 다른 메커니즘(특정 라벨이 붙은 PR에 대해서만 CI를 실행하는 게이트 등)과 조합하면, "Dependabot PR에는 자동으로 라벨을 붙이고, CI와 리뷰도 자동으로 실행하는" 연동 체계를 구축할 수 있습니다.
주의사항
- 비용 상한 설정:
types: [opened]로 실행 횟수를 제한하고,--max-turns로 턴(turn) 수를 제한해 두어야 합니다. Dependabot PR은 수가 많기 때문에, 커밋(commit)마다 실행하게 되면 API 과금이 쌓이게 됩니다. - 동일 리포지토리 판정 (
pull_request_target의 가드(head.repo.full_name == github.repository)와actor판정은 시크릿(secret) 보호의 생명선입니다. "일단 빼두자"는 절대 금물입니다. - AI 리뷰는 1차 정보: 어디까지나 "조사 자동화"이며, 최종적인 머지(merge) 판단은 사람이 한다는 전제하에 운영하는 것이 안전합니다.
- 임의의 셸 실행을 허용할 경우,
allowedTools는 최소한으로:pull_request_target문맥에서는 사고가 발생하기 쉽습니다. 읽기(read)와 댓글(comment) 작성으로만 범위를 좁히는 것을 권장합니다.
요약
- Dependabot PR의 1차 리뷰는
claude-code-action으로 자동화할 수 있습니다. - 시크릿(secret)과 쓰기(write) 권한이 필요하므로
pull_request_target을 사용합니다. 단,permissions: {}설정과actor판정, 동일 리포지토리 판정으로 가드해야 합니다. - head SHA를 명시적으로 체크아웃(checkout)하여 리뷰 대상의 차분(diff)을 가져옵니다.
--allowedTools와--max-turns로 권한과 비용을 제한합니다.- 프롬프트에서 "절차·관점·출력 포맷"을 구조화하면 매번 안정적인 리뷰를 얻을 수 있습니다.
"Dependabot PR이 쌓여서 방치되고 있다", "업데이트 내용을 매번 확인하는 것이 번거롭다"라고 느끼는 팀에게 1차 리뷰 자동화는 매우 효과적입니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기