패스노트
도메인 3. Claude Code 설정과 워크플로

3.6CI/CD 통합

예상 학습 시간 40

Claude Code는 대화형 터미널 밖에서도 동작합니다. 헤드리스(headless) 모드로 스크립트·파이프라인에 넣거나, GitHub Actions로 PR·이슈에 자동 응답하게 할 수 있습니다. 이 수업에서는 비대화형 실행의 플래그, 출력 형식, 권한 처리, 그리고 CI 자동화 패턴을 다룹니다.

헤드리스 모드 기본기

-p(또는 --print) 플래그를 주면 Claude Code가 대화형 UI 없이 프롬프트 하나를 처리하고 종료합니다.

# 기본: 결과 텍스트만 출력
claude -p "이 저장소의 테스트 실행 명령을 알려줘"

# 파이프 입력과 조합
cat build-error.log | claude -p "이 빌드 실패의 원인을 한 줄로 요약해줘"

# JSON 출력 — 스크립트에서 파싱할 때
claude -p "변경된 파일을 요약해줘" --output-format json

# 스트리밍 JSON — 진행 이벤트가 필요할 때
claude -p "..." --output-format stream-json

CI에서 중요한 플래그들:

  • --allowedTools "Bash(npm run test:*),Read" — 이 실행에서 허용할 도구를 명시. 헤드리스에서는 사람이 승인할 수 없으므로 필요한 도구를 사전에 열어 줍니다.
  • --max-turns 20 — 에이전틱 루프의 최대 턴 수를 제한해 폭주를 방지합니다.
  • --permission-mode — 모드 지정. 완전 무인 실행이 필요하면 격리 환경에서 bypassPermissions를 씁니다.
  • --continue / --resume — 이전 세션을 이어받아 다단계 파이프라인을 구성합니다.

인증은 환경 변수 ANTHROPIC_API_KEY로 전달하며, CI 시크릿 저장소에 보관합니다. JSON 출력에는 결과 텍스트 외에 비용·턴 수 같은 메타데이터가 포함되므로, 파이프라인에서 비용을 집계하는 데도 쓸 수 있습니다.

GitHub Actions 통합

공식 GitHub Actions 통합을 설치하면 PR·이슈 코멘트에서 @claude를 멘션해 작업을 맡길 수 있습니다. 대화형 설치는 Claude Code 안에서 /install-github-app 명령으로 진행합니다.

# .github/workflows/claude.yml (개념 예시)
name: Claude
on:
  issue_comment:
    types: [created]
jobs:
  claude:
    if: contains(github.event.comment.body, '@claude')
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

이 구성으로 가능한 대표 시나리오는 다음과 같습니다.

  • 이슈 → PR: 이슈에 "@claude 이 버그 고쳐줘"라고 달면 브랜치를 만들어 수정 PR을 올립니다.
  • PR 자동 리뷰: PR이 열릴 때 코드 리뷰 코멘트를 자동으로 답니다.
  • CI 실패 대응: 실패한 빌드 로그를 분석해 수정 제안이나 수정 PR을 만듭니다.

Actions 환경은 그 자체로 격리된 러너이므로 무인 실행의 위험이 로컬보다 낮지만, 그래도 워크플로의 permissions를 최소로 좁히고, 어떤 이벤트에 반응할지 조건을 명확히 거는 것이 안전 수칙입니다. 특히 외부 기여자의 코멘트로 트리거되는 워크플로는 프롬프트 인젝션 통로가 될 수 있어 트리거 권한을 관리해야 합니다.

파이프라인 설계 패턴과 안전장치

패턴 1 — 게이트형 검사기. 파이프라인의 한 단계로 Claude를 넣어 통과/실패를 판정하게 합니다. 예: 변경된 마이그레이션 파일의 위험도 평가, 릴리스 노트 초안 검증. JSON 출력을 파싱해 exit code로 변환합니다.

result=$(claude -p "이 diff에 파괴적 DB 변경이 있으면 BLOCK, 없으면 PASS만 출력해라" \
  --allowedTools "Bash(git diff:*)" --output-format json)
echo "$result" | jq -r '.result' | grep -q PASS || exit 1

패턴 2 — 대량 반복 처리. 파일 목록을 순회하며 같은 변환을 적용합니다. 각 항목이 독립적이므로 실패해도 해당 항목만 재시도하면 됩니다.

패턴 3 — 이벤트 구동 자동화. 이슈 라벨링, 스테일 PR 정리, 문서 갱신처럼 사람이 미루기 쉬운 유지보수를 스케줄·이벤트로 돌립니다.

공통 안전장치는 다음과 같습니다.

  • 도구 최소화: --allowedTools를 작업에 필요한 최소로 좁힙니다. 쓰기가 필요 없는 검사 작업에 Edit를 열지 않습니다.
  • 턴 제한: --max-turns로 무한 루프 비용을 차단합니다.
  • 결과 검증: Claude의 출력(예: PASS/BLOCK)이 형식을 벗어날 수 있으므로 파싱 실패를 실패로 처리합니다.
  • 사람 게이트 유지: 자동 생성된 PR은 자동 머지하지 않고 사람 리뷰를 거치게 합니다. CI의 Claude는 제안자이지 최종 승인자가 아닙니다.

시험 함정

  • 헤드리스 모드에서도 도구 승인 프롬프트가 뜬다고 생각하기 — 사람이 없으므로 --allowedTools 등으로 사전 허용해야 합니다.
  • -p 실행이 세션을 이어간다고 착각하기 — 기본은 1회 실행 종료이며, 이어가려면 --continue/--resume이 필요합니다.
  • CI에서 --max-turns 없이 무제한 실행을 방치하는 구성을 정상으로 보기.
  • 자동 생성 PR을 자동 머지까지 시키는 선택지 고르기 — 사람 리뷰 게이트를 남기는 것이 모범 답안입니다.
  • API 키를 워크플로 파일에 평문으로 넣는 선택지 — 반드시 시크릿으로 전달합니다.
  • 외부 코멘트 트리거의 프롬프트 인젝션 위험을 무시하기.

실습 시나리오

실제 시험과 같은 형식의 시나리오 문제입니다.

매일 밤 저장소의 오래된 TODO 주석을 수집해 이슈로 정리하는 무인 작업을 GitHub Actions로 만들려 합니다. 안전하게 구성하는 방법으로 가장 적절한 것은?

빌드 연습 · 헤드리스 검사기 만들기

50
  1. 1.단발 실행 확인

    claude -p로 저장소 요약을 요청하고 텍스트 출력을 확인합니다.

    기대 결과 · 대화형 UI 없이 결과만 출력되고 프로세스가 종료됩니다.

  2. 2.JSON 출력 파싱

    --output-format json으로 실행해 jq로 result 필드를 추출합니다.

    기대 결과 · 스크립트에서 결과 텍스트와 메타데이터를 분리해 쓸 수 있습니다.

  3. 3.도구 제한 실험

    --allowedTools에서 Bash를 빼고 명령 실행이 필요한 작업을 시켜 봅니다.

    기대 결과 · 허용되지 않은 도구 사용이 차단되는 것을 확인합니다.

  4. 4.게이트 스크립트 작성

    git diff를 검사해 PASS/BLOCK을 출력하게 하고 exit code로 변환하는 셸 스크립트를 만듭니다.

    기대 결과 · BLOCK일 때 스크립트가 비정상 종료(exit 1)합니다.

  5. 5.형식 이탈 방어

    출력이 PASS/BLOCK 형식을 벗어난 경우를 실패로 처리하는 분기를 추가합니다.

    기대 결과 · 예상 밖 출력에서도 파이프라인이 조용히 통과하지 않습니다.

  6. 6.워크플로 파일 초안

    이 스크립트를 PR 이벤트에 연결하는 GitHub Actions 워크플로 초안을 작성합니다(실행은 선택).

    기대 결과 · 시크릿 주입·권한 최소화가 반영된 워크플로 YAML이 완성됩니다.

출처 및 더 읽기