Skip to content

Latest commit

 

History

History
240 lines (188 loc) · 8 KB

File metadata and controls

240 lines (188 loc) · 8 KB


Gitlab AI Code Review


About

GitLab Merge Request pipeline에서 Job으로 실행되는 AI 코드 리뷰.

별도 리뷰 서버를 두지 않고, 각 GitLab repository의 MR pipeline job이 Docker image를 pull한 뒤 ai-code-review CLI를 실행한다. CLI는 GitLab API로 MR 변경 내용을 읽고 Gemini에 리뷰를 요청한 뒤, MR summary note와 added line comment를 GitLab에 작성한다.

현재 사용중인 모델 : Gemini 3.1 Flash Lite model - 무료 토큰 제한이 높고, 빠르고 경량화 모델 중 성능이 우수함.

Preview

image
image

Features

  • GitLab API를 통한 MR 메타데이터, 최신 diff 버전, 변경 파일 조회
  • 인라인 리뷰 코멘트 작성을 위한 코멘트 가능한 추가 라인(added lines) 만 매핑
  • 안전한 교체 라인이 있을 때 added-line comment에 GitLab single-line suggestion block 추가
  • diff 이해도 향상을 위한 변경 파일 주변 제한된 로컬 워크스페이스 컨텍스트 조회
  • Gemini 기반 MR 수준의 코드 요약(code summary), 실행 가능한 라인 단위 지적 사항, 리뷰 제한/노트 포함 구조화 결과 생성
  • MR draft note(요약 + 라인 코멘트) 생성
  • 기본 동작: 동일 head_sha 중복 리뷰 방지 / 선택 동작: AI_REVIEW_FORCE=true 시 재리뷰 허용
  • 오래된 코멘트 방지를 위한 posting/publishing 전 stale head_sha 검사
  • 대규모 MR 정책 기반 처리: 한도 내 일반 라인 리뷰, soft-limit 초과 시 summary-only 모드, hard-limit 초과 시 hard skip
  • 노이즈 감소를 위한 리뷰 제외 파일(lock/generated/binary/build outputs 등) 필터링
  • 언어/프레임워크에 따라 조합할 수 있는 rule pack 지원: default(항상 적용), spring, node-express, react-nextjs, python-django-fastapi, nestjs, go-gin-echo, vue-nuxt
  • AI_REVIEW_MAX_COMMENTS, AI_REVIEW_MAX_COMMENTS_PER_FILE 기반 코멘트 볼륨 제어
  • non-blocking 리뷰(allow_failure: true) 유지로 AI 장애 시에도 파이프라인 진행 차단 방지
  • 추적성 확보를 위한 실행 artifact(ai-review-result.json) 상시 기록

동작 흐름

GitLab Merge Request
        |
        v
MR Pipeline
        |
        v
ai-code-review job
        |
        v
Docker image: ghcr.io/squatboy/gitlab-code-review:<tag>
        |
        v
ai-code-review CLI
        |
        +--> GitLab API: MR 정보, diff version, 변경 파일 조회
        |
        +--> Gemini API: structured review result 생성
        |
        +--> GitLab API: draft note 생성 후 bulk publish
        |
        +--> ai-review-result.json artifact 저장

GitLab CI 적용

대상 repository의 .gitlab-ci.yml에 아래 job을 추가한다.

ai-code-review:
  stage: test
  image: ghcr.io/squatboy/gitlab-code-review:v0.1.0-rc3
  variables:
    AI_REVIEW_ENABLED: "true"
    AI_REVIEW_FORCE: "false"
    AI_REVIEW_LANGUAGE: "ko"
    AI_REVIEW_MODEL: "gemini-3.1-flash-lite-preview"
    AI_REVIEW_MAX_COMMENTS: "10"
    AI_REVIEW_MAX_COMMENTS_PER_FILE: "3"
    AI_REVIEW_RULE_PACKS: "default"
    AI_REVIEW_RESULT_PATH: "ai-review-result.json"
  allow_failure: true
  script:
    - ai-code-review
  artifacts:
    when: always
    expire_in: 7 days
    paths:
      - ai-review-result.json
  rules:
    - if: '$AI_REVIEW_ENABLED == "false"'
      when: never
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID && $CI_MERGE_REQUEST_TITLE !~ /^(Draft:|WIP:)/'
      when: on_success
    - when: never

runner 설정:

  • tags 필드는 선택사항입니다. Runner가 untagged job을 지원하지 않으면 추가하세요.
    tags:
      - <your-runner-tag>

GitLab CI Variables

Group level variable로 등록하는 것을 기본으로 한다.

AI_CODE_REVIEW_GITLAB_TOKEN
AI_REVIEW_API_KEY

AI_CODE_REVIEW_GITLAB_TOKEN:

  • 권장: GitLab Group Access Token
  • 대안: 전용 bot 계정의 Personal Access Token
  • 권한: 대상 project에 Developer 이상
  • scope: api
  • 용도:
    • MR 읽기
    • MR discussion/note 조회
    • draft note 생성
    • draft note bulk publish
  • 같은 project 내부 MR pipeline에서 사용하려면 protected variable로 두지 않는다.

AI_REVIEW_API_KEY:

  • Gemini API key 원문
  • GitLab CI variable에서는 masked/hidden 설정 권장

설정값

Variable Default 설명
AI_REVIEW_ENABLED true false면 job 내부에서 리뷰를 스킵한다.
AI_REVIEW_FORCE false true면 같은 head_sha도 다시 리뷰한다.
AI_REVIEW_LANGUAGE en 리뷰 결과 언어. 한국어는 ko 로 선언
AI_REVIEW_MODEL gemini-3.1-flash-lite-preview Gemini 모델명.
AI_REVIEW_MAX_COMMENTS 10 MR 전체 line comment 최대 개수.
AI_REVIEW_MAX_COMMENTS_PER_FILE 3 파일당 line comment 최대 개수.
AI_REVIEW_RULE_PACKS default 적용할 rule pack. comma-separated string. default는 항상 적용됨.
AI_REVIEW_RESULT_PATH ai-review-result.json 결과 artifact 파일 경로.

지원 rule pack:

  • default: 언어/프레임워크 공통 기준(정합성, 보안, 무결성, 회귀 위험)
  • spring: Spring/JPA/MyBatis/REST 중심 점검
  • node-express: Node.js/Express API 및 미들웨어 중심 점검
  • react-nextjs: React/Next.js 렌더링 경계 및 계약 중심 점검
  • python-django-fastapi: Django/FastAPI ORM·검증·권한 중심 점검
  • nestjs: NestJS 모듈/DI 경계, guard/interceptor/pipe 흐름, DTO 검증, 권한 점검
  • go-gin-echo: Go Gin/Echo 컨텍스트 타임아웃·취소, 고루틴 안전성, 검증, API 계약 점검
  • vue-nuxt: Vue/Nuxt SSR-CSR 경계, hydration 불일치, 라우트 가드/인증 흐름, XSS 위험 점검

동작 정책:

  • 알 수 없는 rule pack은 무시하고 리뷰를 계속 진행한다.
  • 무시된 pack 이름은 리뷰 summary의 제한 항목에 표시된다.
  • 예시: AI_REVIEW_RULE_PACKS=spring,nestjs,go-gin-echo

현재 리뷰 정책

  • MR pipeline에서만 실행한다.
  • fork MR은 제외한다.
  • Draft: 또는 WIP: 제목의 MR은 제외한다.
  • 같은 head_sha에 이미 summary note가 있으면 duplicate_head_sha로 스킵한다.
  • AI_REVIEW_FORCE=true면 같은 head_sha도 다시 리뷰한다.
  • line comment는 added line에만 작성한다.
  • 정확한 단일 교체 라인이 있을 때만 added-line comment에 suggestion을 첨부한다.
  • 삭제 line, context line, multi-line range에는 comment하지 않는다.
  • AI 리뷰 실패는 pipeline을 막지 않는다.
  • 실행 결과는 항상 ai-review-result.json artifact로 남긴다.

Local Development

의존성 설치:

pnpm install

빌드:

pnpm build

테스트:

pnpm test

lint:

pnpm lint

로컬 non-network smoke:

AI_REVIEW_ENABLED=false pnpm dev

기대 결과:

  • CLI가 실행된다.
  • ai-review-result.json이 생성된다.
  • status가 skipped로 기록된다.

Docker Image Build

GitHub Actions workflow는 quality check 통과 후 GHCR에 multi-arch image를 publish한다.

  • Pull request: pnpm build, pnpm test, pnpm lint, Docker build 검증만 실행하고 push하지 않는다.
  • main push: ghcr.io/squatboy/gitlab-code-review:sha-<short_sha>를 push한다.
  • v* tag push: version tag (예: v0.1.0)만 push한다.
  • latest tag는 사용하지 않는다.

로컬 테스트:

docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t ghcr.io/squatboy/gitlab-code-review:<version> \
  --push .

manifest 확인:

docker manifest inspect ghcr.io/squatboy/gitlab-code-review:<version>