본문으로 건너뛰기
개발 머꼬
개발 노트GitHub Actions
hohyeon.dev33

봇이 만든 PR에서 CI가 하나도 돌지 않은 이유

  • #CI/CD
  • #Engineering Note
  • #GitHub Actions

문제 발생

의존성 업데이트를 자동화했습니다. 워크플로가 pnpm update를 돌리고 변경사항으로 PR을 만드는 구조였는데, 그 PR에서는 CI가 하나도 돌지 않았습니다. 사람이 만든 PR에서는 정상이었습니다.

체크가 비어 있으니 "필수 체크 통과" 조건도 영원히 만족되지 않아 자동 머지도 멈췄습니다.

원인 분석

의도된 제약입니다. GitHub 문서가 명시합니다 — 기본 토큰으로 만들어진 워크플로 이벤트는 대부분의 이벤트 유형에 대해 워크플로 실행을 아예 만들지 않으며, 예외는 workflow_dispatchrepository_dispatch입니다.

이유는 명확합니다. 워크플로가 커밋을 만들고, 그 커밋이 다시 워크플로를 트리거하면 무한 재귀가 됩니다. 과금과 부하 모두 폭발합니다.

관련 규칙이 하나 더 있습니다 — GITHUB_TOKEN을 사용하는 워크플로가 PR을 만들거나 갱신한 경우, opened/synchronize/reopened 활동 유형의 pull_request 이벤트는 승인이 필요한 워크플로 실행을 만듭니다.

즉 "CI가 안 도는" 것은 버그가 아니라 안전장치입니다.

해결 방안

  1. 다른 자격증명으로 PR을 만듭니다. GitHub App 토큰(권장)이나 별도 계정의 PAT를 쓰면 그 이벤트는 정상적으로 워크플로를 트리거합니다. App 토큰은 수명이 짧고 권한을 좁힐 수 있어 PAT보다 낫습니다.
- uses: actions/create-github-app-token@v2
  id: app-token
  with:
    app-id: ${{ vars.BOT_APP_ID }}
    private-key: ${{ secrets.BOT_PRIVATE_KEY }}

- uses: peter-evans/create-pull-request@v7
  with:
    token: ${{ steps.app-token.outputs.token }}   # GITHUB_TOKEN 이 아니다
  1. 또는 검증을 같은 워크플로 안에서 끝냅니다. PR을 만들기 전에 그 job에서 lint·typecheck·build를 돌리면, 트리거 문제 자체가 사라집니다. 의존성 업데이트처럼 검증 항목이 정해져 있으면 이 방식이 단순합니다.

  2. workflow_dispatch는 예외라는 점을 활용합니다. 후속 작업이 필요하면 기본 토큰으로도 workflow_dispatch를 호출할 수 있습니다 — 재귀 위험이 없는 명시적 호출이기 때문입니다.

  3. 자동화 계정의 권한을 좁힙니다. 이 우회는 결국 "워크플로가 워크플로를 부를 수 있게" 만드는 일이므로, 그 자격증명이 할 수 있는 일을 최소로 제한하고 재귀 종료 조건을 분명히 둡니다.

  4. 필수 체크 정책과 함께 봅니다. 체크가 아예 생성되지 않으면 브랜치 보호 규칙이 영원히 만족되지 않습니다 — 자동 머지를 붙이기 전에 이 조합을 먼저 확인합니다.

공식 문서

마지막 수정

좋아요북마크

댓글0

아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.