Skip to main content
Glama

gitl

Action 자체 테스트

CLI 및 CI용 AI 기반 git 히스토리 리뷰어. gitl(git-log-lens)은 저장소의 git 히스토리를 읽고 LLM을 통해 구조화된 엔지니어링 산출물로 변환합니다:

  • gitl review <range> — 커밋 범위 / PR에 대한 AI 리뷰와 CI 게이팅용 기계 판독 가능 위험 점수(low|medium|high) 제공(--fail-on=high → 종료 코드 2); 터미널에 토큰을 실시간 스트리밍; 디스크 기반 LLM 응답 캐시와 CI용 선택적 공유 원격 캐시; 사용자 정의 시스템 프롬프트 템플릿; --stagedgit commit 전에 스테이징된(커밋되지 않은) 변경 사항을 리뷰합니다(pre-commit 훅으로도 사용 가능).

  • gitl changelog [<range>] — conventional commits로 그룹화된 Keep a Changelog 스타일 체인지로그 생성(기본값: 마지막 태그 → HEAD); 기본적으로 결정론적이며, --ai는 모델로 읽기 쉬운 릴리스 노트 산문으로 재작성할 수 있습니다;

  • gitl digest [--days=N] [--repos=a,b,c] — 작성자/주제/파일별 활동 요약, 여러 저장소를 병렬로 포함; 대화형 TUI 뷰어(--tui).

깔끔한 CLI 바이너리와 GitHub Action 래퍼 — 서버, 데이터베이스, 호스팅 키 저장소 없음. BYOK(자체 키 사용) 방식으로 다중 제공자 지원: OpenAI 호환 API, Ollama(로컬/자체 호스팅), Azure OpenAI, 네이티브 Anthropic(Claude), Google Gemini. 텔레메트리 없음.

상태: v0.6.2 릴리스 — 세 가지 명령 모두 실제 저장소에서 세 가지 출력 형식(md|text|json)으로 작동합니다. Action은 AI 리뷰를 고정 PR 댓글로 게시하고 위험 점수로 게이팅합니다. 릴리스 바이너리는 크로스 컴파일되고 cosign 서명되며 SLSA L3 빌드 출처가 적용됩니다(VERIFY.md 참조).

빠른 시작

Go 1.22+gitPATH에 필요합니다.

# build
go build ./...

# AI review of a commit range — streams tokens to the terminal in real time
GITL_API_KEY=sk-... go run ./cmd/gitl review HEAD~5..HEAD

# no key = deterministic offline review (heuristic risk, no network call)
go run ./cmd/gitl review HEAD~5..HEAD

# review staged (not yet committed) changes before `git commit`
go run ./cmd/gitl review --staged

# review a GitHub PR by number — requires the `gh` CLI (installed + authenticated);
# resolves base/head via gh, fetches `pull/N/head` locally when needed, and reviews
# the merge-base diff (base...head), same as GitHub shows
go run ./cmd/gitl review pr/42

# machine-readable output for CI + risk gating
go run ./cmd/gitl review HEAD~5..HEAD --format=json
go run ./cmd/gitl review HEAD~5..HEAD --fail-on=high   # exit code 2 on high risk
# exit codes: 0 = ok (risk below --fail-on), 1 = tool/runtime error (git/LLM/
# config failure), 2 = the --fail-on risk gate triggered — CI can branch on 2

# estimate cost without making an API call
go run ./cmd/gitl review HEAD~5..HEAD --dry-run

# custom system-prompt template (e.g. your team's review policy) — set via
# config only (prompt.system_template_file); there is no --system-template flag
# see Configuration → Custom templates below

# skip the on-disk LLM cache (always call the model)
go run ./cmd/gitl review HEAD~5..HEAD --no-cache

# disable streaming (non-interactive, buffered output)
go run ./cmd/gitl review HEAD~5..HEAD --no-stream

# suppress the informational offline-mode notice on stderr (errors and the
# review output are unaffected) — also via GITL_QUIET=1 or output.quiet: true
go run ./cmd/gitl review HEAD~5..HEAD --quiet

# changelog from last tag (or full history if no tags) — no LLM by default
go run ./cmd/gitl changelog
go run ./cmd/gitl changelog v1.2.0..HEAD --format=json

# AI changelog: the model rewrites the grouped result as release-note prose and
# reclassifies significant non-conventional commits out of "Other". Without an API
# key (or on a malformed model response) it falls back to the deterministic
# changelog with a warning — never fails. --dry-run/--max-cost-usd/--no-cache work
# the same as for review.
GITL_API_KEY=sk-... go run ./cmd/gitl changelog --ai

# activity summary for the last N days — no LLM
go run ./cmd/gitl digest --days=14

# multi-repo digest: runs in parallel; one unreachable repo does not fail the rest
go run ./cmd/gitl digest --repos=../service-a,../service-b --format=json

# interactive TUI viewer for digest (requires a TTY)
go run ./cmd/gitl digest --days=14 --tui

go run ./cmd/gitl version
go run ./cmd/gitl --help

# tests
go test ./...

설치:

# Go toolchain
go install github.com/akomyagin/gitl/cmd/gitl@latest

# Homebrew (macOS/Linux)
brew install akomyagin/tap/gitl

# npm — downloads the prebuilt binary for your platform from GitHub Releases
# and verifies its SHA256 checksum (no Go toolchain needed).
npx gitl-cli review HEAD~5..HEAD   # or: npm install -g gitl-cli

# Or download a signed release binary from GitHub Releases (see VERIFY.md)

셸 완성

gitl은 bash, zsh, fish, PowerShell용 cobra 생성 완성 스크립트를 제공합니다.

Homebrew는 bash/zsh/fish 완성 스크립트를 자동으로 설치합니다(릴리스 아카이브에도 completions/ 아래에 포함되어 있습니다). 그 외에는 필요 시 활성화하세요:

# bash (current shell)
source <(gitl completion bash)
# bash (persistent) — Linux
gitl completion bash > /etc/bash_completion.d/gitl
# zsh (persistent)
gitl completion zsh > "${fpath[1]}/_gitl"
# fish
gitl completion fish > ~/.config/fish/completions/gitl.fish
# PowerShell
gitl completion powershell | Out-String | Invoke-Expression

고정 값 집합이 있는 플래그 — --format(md|text|json), --fail-on(never|low|medium|high), --provider — 는 허용 값을 자동 완성합니다.

로컬 다중 제공자 테스트(Ollama)

docker-compose.yml개발 의존성만 시작합니다 — 다중 제공자 LLM 클라이언트 테스트용 로컬 Ollama 인스턴스(gitl 자체는 컨테이너화되지 않음):

docker compose up ollama

Related MCP server: grippy-code-review

구성

빠른 경로: gitl init은 주석이 달린 시작용 .gitl.yaml을 저장소 루트에 작성합니다(기존 파일이 있으면 --force 없이는 덮어쓰지 않음; --output은 다른 위치에 작성). 이 섹션에서 복사-붙여넣기 대신 해당 파일을 편집하세요 — 아래 나머지는 전체 참조입니다.

우선순위로 병합되는 두 수준: 플래그 > 환경 변수 > .gitl.yaml(저장소) > ~/.config/gitl/config.yaml(개인). 저장소 수준의 .gitl.yaml은 공유 팀 정책(위험 임계값, 제외 경로, 체인지로그 카테고리)으로 커밋됩니다. 키가 없으면 gitl은 결정론적 오프라인 모드로 실행됩니다.

오프라인 모드에서 — 또는 실제 모델이 유효한 위험 블록을 생략하고 gitl이 휴리스틱으로 폴백할 때 — 위험 헤더에 *(heuristic)*이 주석으로 표시됩니다(--format=json에서는 "heuristic": true). 따라서 결정론적 점수가 모델 자체의 판단으로 오인되지 않습니다.

제공자 (llm.provider)

# OpenAI-compatible API (default)
llm:
  provider: "openai"
  api_key: ""            # or env GITL_API_KEY
  base_url: "https://api.openai.com/v1"
  model: "gpt-4o-mini"

# Ollama — local/self-hosted, no key, free
llm:
  provider: "ollama"
  base_url: "http://localhost:11434/v1"
  model: "llama3.1"

# Azure OpenAI — custom auth/endpoint format
llm:
  provider: "azure_openai"
  api_key: ""             # or env GITL_API_KEY
  model: "gpt-4o-mini"    # used only for cost estimation
  azure_openai:
    endpoint: "https://<resource>.openai.azure.com"
    deployment: "<deployment-name>"
    api_version: "2024-08-01-preview"

# Anthropic (native Claude Messages API)
llm:
  provider: "anthropic"
  api_key: ""            # or env GITL_API_KEY
  model: "claude-sonnet-4-6"
  # base_url optional; defaults to https://api.anthropic.com

# Google Gemini (Google AI Studio)
llm:
  provider: "gemini"
  api_key: ""            # or env GITL_API_KEY
  model: "gemini-2.5-flash"
  # base_url optional; defaults to https://generativelanguage.googleapis.com/v1beta

스트리밍 (output.stream)

대화형으로 리뷰할 때(TTY에서 md 또는 text 형식), gitl은 토큰이 도착하는 대로 터미널에 스트리밍합니다 — 전체 응답을 기다리지 않습니다. 스트리밍은 기본적으로 켜져 있으며 CI(비-TTY stdout), --format=json, 그리고 사용자 정의 output.template_file이 구성된 경우 자동으로 꺼집니다(템플릿은 전체 응답이 필요하므로 리뷰가 버퍼링된 후 템플릿을 통해 렌더링됩니다).

스트리밍은 현재 OpenAI 호환 제공자(openai / ollama / azure_openai)에서만 구현되어 있습니다. 네이티브 anthropic 또는 gemini 제공자를 사용하면 gitloutput.stream / --no-stream과 관계없이 동일한 리뷰를 단일 버퍼링된 응답으로 투명하게 생성합니다(토큰 단위 출력 없음).

output:
  stream: true   # default; set false to always buffer

호출별 비활성화: gitl review HEAD~5..HEAD --no-stream

색상 (output.color)

대화형 터미널에서 gitl review는 헤더의 위험 수준을 색상으로 표시합니다(HIGH 빨간색, MEDIUM 노란색, LOW 초록색). stdout이 TTY가 아닐 때(파이프, CI 로그) 색상은 자동으로 꺼지며 --format=json 출력에는 절대 나타나지 않습니다. 우선순위(높은 순):

  1. NO_COLOR 환경 변수 설정(값이 무엇이든, 비어 있어도) — 색상 끔 (no-color.org);

  2. 구성의 output.color: false(또는 GITL_OUTPUT_COLOR=false) — 색상 끔;

  3. stdout이 TTY가 아님 — 색상 끔;

  4. 그 외 — 색상 켬.

output:
  color: true   # default; set false to disable ANSI color

자동 모드 (output.quiet)

API 키가 없으면 review는 실행할 때마다 "결정론적 오프라인 리뷰 사용" 안내를 stderr에 출력합니다(changelog --ai도 유사한 폴백 안내를 출력합니다). 알려진 오프라인 컨텍스트 — 특히 모든 커밋에서 실행되는 pre-commit 훅 — 에서는 해당 배너가 노이즈입니다. 다음 중 하나로 억제할 수 있습니다(각 계층이 독립적으로 억제를 켤 수 있음):

  1. review / changelog--quiet 플래그;

  2. GITL_QUIET 환경 변수 설정(값이 무엇이든, 비어 있어도);

  3. 구성의 output.quiet: true(또는 GITL_OUTPUT_QUIET=true).

--quiet는 정보성 배너만 무음 처리합니다: 오류, stdout의 렌더링된 리뷰/체인지로그, --fail-on 게이트는 영향을 받지 않습니다.

output:
  quiet: false   # default; set true to suppress the offline notices

LLM 응답 캐시 (cache)

gitl review는 모델 응답을 디스크에 캐시합니다(제공자 + 모델 + 프롬프트의 SHA-256). 동일한 diff는 API 호출이나 비용 없이 캐시된 결과를 즉시 재사용합니다.

cache:
  enabled: true    # default
  ttl_hours: 24    # entries older than this are ignored

캐시는 ~/.cache/gitl/review/에 있습니다(XDG 준수). 호출별 비활성화: gitl review HEAD~5..HEAD --no-cache

--format=json에서 모든 리뷰 산출물은 추가 실행 메타데이터를 포함합니다(schema_version1로 유지; 이전 소비자는 동일한 문서에 두 개의 새 키가 추가된 것을 볼 수 있음):

{
  "duration_ms": 1234,
  "cache": { "hit": true, "tier": "local" }
}
  • duration_ms — 전체 리뷰 실행의 벽시계 시간(밀리초)(캐시 히트도 실제로는 일반적으로 아주 작은 숫자를 보고합니다).

  • cache.hit — 이 리뷰가 새 모델 호출 대신 LLM 응답 캐시에서 제공되었는지 여부.

  • cache.tier — 실행에 적용된 캐시 토폴로지: none(오프라인 모드, --no-cache, cache.enabled: false, 또는 ttl_hours <= 0), local(디스크 전용), 또는 tiered(디스크 + 원격). 특정 히트를 제공한 백엔드가 아니라 구성된 모드를 보고합니다.

의도적으로 아직 usage(토큰 수) 필드가 없습니다: gitl은 응답에서 제공자 사용량을 파싱하지 않으며, 영구히 비어 있는 필드는 없는 것보다 나쁩니다. 사용량 파싱이 도입되면 스키마 변경 없이 추가 방식으로 추가될 것입니다.

공유 원격 캐시 (cache.remote) — 옵트인

옵트인, 기본 꺼짐, BYO-백엔드: gitl은 서비스를 호스팅하지 않으며 구성하기 전까지 어떤 캐시에도 네트워크 요청을 하지 않습니다. CI 콜드 스타트에 유용합니다 — 모든 러너는 빈 디스크로 시작하지만, 공유 HTTP KV 엔드포인트를 통해 한 러너가 동일한 diff에 대한 다른 러너의 리뷰를 재사용할 수 있습니다.

cache:
  enabled: true
  ttl_hours: 24
  remote:                     # opt-in shared cache for CI cold starts (off by default)
    url: https://cache.example.com/gitl   # your endpoint; gitl hosts nothing
    token_env: GITL_REMOTE_CACHE_TOKEN    # env var holding an optional bearer token
    timeout_ms: 3000

구성되면 로컬 디스크 캐시가 첫 번째 계층으로 유지됩니다: 읽기는 디스크를 먼저 확인한 다음 원격을 확인합니다(원격 히트는 디스크에 백필됨); 쓰기는 둘 다 수행합니다.

프로토콜은 HTTP를 통한 단순 키-값 저장소입니다 — 모든 정적 객체 저장소나 작은 핸들러로 작동합니다:

  • GET {url}/{key} → JSON 항목 본문과 함께 200, 또는 404 = 미스. 다른 상태, 네트워크 오류, 타임아웃은 모두 미스로 처리됩니다.

  • PUT {url}/{key} — JSON 항목을 요청 본문으로(Content-Type: application/json) → 모든 2xx = 저장됨.

  • token_env가 비어 있지 않은 값의 환경 변수를 지정하면 두 요청 모두 Authorization: Bearer <token>을 전달합니다. 토큰 자체는 구성 파일에서 절대 읽지 않습니다(GITL_API_KEY와 동일한 규율).

  • 키는 64자 16진수 SHA-256 문자열입니다. 값은 서버에 불투명합니다.

안전 계약: 모든 원격 실패(타임아웃, 5xx, 연결 불가능한 엔드포인트)는 로컬 캐시 / 캐시 없음으로 자동 폴백됩니다 — 리뷰를 실패시키지 않습니다. 저장된 항목에는 불투명 해시로 키가 지정된 모델의 응답만 포함됩니다: diff나 프롬프트 텍스트는 원격 캐시에 도달하지 않습니다. ttl_hours보다 오래된 항목은 서버가 무엇을 반환하든 클라이언트 측에서 무시됩니다.

위험 추세 (policy.risk_log_enabled)

모든 gitl review 실행은 위험 결과(수준, 범위, 제공자, 타임스탬프)를 로컬 JSONL 로그에 추가합니다: $XDG_DATA_HOME/gitl/risk-history.jsonl(기본값 ~/.local/share/gitl/risk-history.jsonl; Windows에서는 %AppData%\gitl\). gitl digest는 이를 읽어 저장소별 **"위험 추세(최근 N일)"** 섹션을 표시합니다 — 수준별 리뷰 수, 고위험 방향(창의 최근 절반 vs 이전 절반), 최근 리뷰 몇 개. --format=json에서는 선택적 risk_trend 필드로 나타납니다(schema_version1로 유지; 이전 소비자는 이전과 동일한 문서를 봅니다). 히스토리가 없는 저장소는 해당 섹션을 생략합니다.

리뷰는 origin 원격 URL로 저장소와 연관됩니다(origin이 없으면 작업 트리 경로로 폴백).

제한 사항: 히스토리는 사용자 머신에만 로컬입니다 — CI 러너 간에 유지되지 않으므로(각각 콜드 디스크로 시작), 추세는 CI가 아닌 로컬 개발자용 기능입니다.

구성에서 옵트아웃(CLI 플래그 없음):

policy:
  risk_log_enabled: false

사용자 정의 템플릿 (prompt.*_template_file / output.template_file)

독립적인 구성 전용 재정의(이 중 어떤 것에도 CLI 플래그가 없음):

  • prompt.system_template_file — 모델의 초점을 조정하기 위한 자체 리뷰 시스템 프롬프트(보안 체크리스트, 아키텍처 제약, 팀 규칙). gitl review에서만 사용:

    prompt:
      system_template_file: "./review-policy.md"   # path relative to CWD

    리뷰 시스템 프롬프트 템플릿은 {{ .Commits }}, {{ .Diff }}, {{ .Range }}, {{ .Staged }}에 접근할 수 있습니다(internal/prompt/templates.go 참조).

  • prompt.changelog_system_template_filegitl changelog --ai에서만 사용되는 자체 체인지로그 시스템 프롬프트:

    prompt:
      changelog_system_template_file: "./changelog-policy.md"   # path relative to CWD

    체인지로그 시스템 프롬프트 템플릿은 {{ .Commits }}, {{ .Range }}, {{ .Grouped }}에 접근할 수 있습니다 — {{ .Diff }}는 아님: changelog --ai는 커밋 메타데이터로 작동하며 diff가 없으므로 .Diff를 사용하는 리뷰 형태의 템플릿은 여기서 실패합니다. 이것이 두 키가 분리된 정확한 이유입니다: 각 명령은 자체 키만 읽으며, 둘 중 하나는 다른 것 없이 설정할 수 있습니다.

  • output.template_file — 완성된 리뷰 산출물을 위한 자체 md 형식 렌더 템플릿:

    output:
      template_file: "./review-output.tmpl"   # path relative to CWD

    출력 템플릿은 internal/render/render.go의 렌더 템플릿 함수(render.TemplateFuncs())를 사용할 수 있습니다.

신뢰 참고: prompt.*_template_file/output.template_file 키는 개인 구성뿐만 아니라 저장소 수준의 .gitl.yaml에서도 설정할 수 있습니다 — 따라서 제어하지 않는 클론된 저장소에서 gitl review를 실행하면 같은 저장소 내부의 템플릿을 가리킬 수 있습니다. 이는 팀의 공유 리뷰 정책을 위한 의도된 메커니즘이지 버그가 아닙니다: 여기의 text/template은 임의의 파일을 읽거나 코드를 실행할 수 없지만, 신뢰할 수 없는 저장소의 .gitl.yaml.git/hooks나 빌드 스크립트에 주의를 기울이는 것과 같은 주의로 취급하세요.

GitHub Action

gitl은 GitHub Action으로 연결할 수 있습니다: 풀 리퀘스트의 커밋을 AI 리뷰하고 위험 점수가 포함된 댓글을 게시하며, 선택적으로 임계값 이상에서 병합을 차단합니다. Action은 소스에서 gitl을 빌드합니다(고정 버전에서 go install). GitHub Marketplace에도 등록되어 있으므로 거기서 추가할 수도 있습니다.

저장소에 .github/workflows/gitl-review.yml을 추가하세요:

name: gitl review
on:
  pull_request:

permissions:
  contents: read          # for checkout
  pull-requests: write    # to post the review comment

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0    # required: without full history base..head won't resolve

      - uses: akomyagin/gitl@v0.6.2
        with:
          gitl-api-key: ${{ secrets.GITL_API_KEY }}   # BYOK, see below
          fail-on: high                               # optional: block merge on high risk

보안 모범 사례:

  • 키는 secrets.*로만 제공. gitl-api-keysecrets.GITL_API_KEY에서 가져옵니다(Settings → Secrets and variables → Actions에서 설정). YAML에 하드코딩하거나 커밋하지 마세요. 시크릿이 설정되지 않으면 Action은 결정적 오프라인 모드로 실행됩니다(네트워크 없음, 비용 없음).

  • 최소한의 permissions:. pull-requests: write(댓글 게시)와 contents: read(체크아웃)만 필요합니다 — 더 넓은 권한을 부여하지 마세요.

  • fetch-depth: 0이 필수입니다. GitHub는 pull_request 이벤트에서 base/head SHA를 제공하지만, 얕은 클론으로는 base.sha..head.sha를 해석할 수 없습니다.

  • fail-on 기본값은 never입니다. Action은 댓글만 달 뿐, 명시적으로 선택하지 않는 한(fail-on: high 등) 머지를 차단하지 않습니다 — CLI(--fail-on)와 동일한 "기본은 WARN, 하드 게이트는 명시적 옵트인" 원칙입니다. 게이트가 발동하면 작업은 gitl의 종료 코드 2(리스크 게이트)로 실패합니다 — 실제 도구 오류는 1로 실패하므로, 다운스트림 단계에서 "위험한 변경"과 "gitl 오류"를 구분할 수 있습니다.

  • Diff 프라이버시. CI에서 diff는 설정된 LLM 제공자(기본값: OpenAI 호환 API)로 전송됩니다. 비공개 코드의 경우 자체 호스팅/엔터프라이즈 제공자(Ollama, Azure OpenAI)를 사용하세요 — 위의 Providers 섹션을 참조하세요.

  • 제공자 선택. 기본적으로 Action은 설정 파일의 제공자(설정하지 않으면 OpenAI 호환)를 사용합니다. 네이티브 제공자를 대상으로 하려면 provider:(openai|ollama|azure_openai|anthropic|gemini)를 전달하고, 선택적으로 model:base-url:gitl-api-key:와 함께 전달하세요. 세 가지 모두 선택 사항이며, 생략하면 .gitl.yaml/개인 설정과 gitl의 내장 기본값으로 폴백됩니다 — 위의 Providers 섹션을 참조하세요. 예: provider: anthropic + secrets.GITL_API_KEY의 Claude 키.

  • 시크릿 마스킹. GitHub는 러너 로그에서 secrets.* 값을 자동으로 ***로 마스킹하지만, 그렇다고 워크플로 단계에서 키를 직접 출력해도 된다는 뜻은 아닙니다.

PR 설명 리스크 요약(옵트인)

update-pr-description: true(기본값 false)를 사용하면 Action이 PR 설명 끝에 간결한 리스크 요약 블록(리스크 한 줄 + 전체 리뷰 댓글 링크)을 추가로 유지 관리하며, 실행할 때마다 업데이트합니다:

      - uses: akomyagin/gitl@v0.6.2
        with:
          gitl-api-key: ${{ secrets.GITL_API_KEY }}
          update-pr-description: true

PR 설명을 편집하는 것은 고정 댓글보다 더 침습적이므로 옵트인 방식입니다. 추가 권한은 필요 없습니다 — 댓글에 이미 필요한 pull-requests: write가 PR 본문도 커버합니다. 블록은 <!-- gitl-review-summary --> 마커 쌍으로 구분되며, 마커 사이의 텍스트만 교체됩니다 — 마커 밖에 작성한 내용은 절대 건드리지 않습니다. 현재는 GitHub 전용입니다(Gitea Actions에서는 무시됨).

Gitea Actions(실험적)

동일한 action.ymlGitea Actions에서도 실행됩니다 — Gitea의 러너는 GitHub 스타일 복합 액션을 실행하며, gitl의 액션은 Gitea의 act_runner가 모든 작업에 주입하는 GITEA_ACTIONS=true 변수를 통해 런타임에 플랫폼을 감지합니다. 플랫폼별 유일한 부분인 고정 PR 댓글 게시는 gh CLI 대신 curl로 Gitea의 REST API(POST/PATCH /api/v1/repos/{owner}/{repo}/issues/...)를 통해 수행됩니다. gh CLI는 GitHub API만 지원합니다. GitHub 사용자는 영향받지 않습니다: GITEA_ACTIONS가 없으면 액션은 이전과 동일하게 동작합니다.

저장소에 .gitea/workflows/gitl-review.yml을 추가하세요(전체 주석 예제: 이 저장소의 .gitea/workflows/gitl-review.yml):

name: gitl review
on:
  pull_request:

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: https://github.com/actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: https://github.com/akomyagin/gitl@v0.6.2
        with:
          gitl-api-key: ${{ secrets.GITL_API_KEY }}   # BYOK; omit for offline mode

요구 사항: Actions 활성화, 최신 act_runner(node24 지원), bash, git, curl, jq, node를 제공하는 러너 이미지. GITL_API_KEY는 Gitea의 Actions 시크릿에 넣고, 절대 YAML에 넣지 마세요 — GitHub와 동일한 BYOK 규칙입니다.

검증 상태 — 이 기능에 의존하기 전에 읽어보세요. curl 기반 REST 호출(댓글 목록, 생성, 패치, 고정 감지)은 실제 Gitea 인스턴스(Docker의 gitea/gitea)에서 엔드투엔드로 테스트되었습니다 — 목록-비어있음 → POST-생성 → 재목록-발견 → PATCH-업데이트 → 여전히 정확히 하나의 댓글. 그 부분은 작성된 대로 작동합니다. 아직 검증되지 않은 것은 주변 act_runner CI 컨텍스트입니다: GITEA_ACTIONS/GITHUB_API_URL/PR 이벤트 페이로드가 실제 워크플로 실행에서 가정한 것과 정확히 일치하는지 여부(Gitea/act_runner/act-fork 소스와 교차 확인했지만 실제 작업 내에서 실행되지는 않았습니다). 실제 Gitea Actions에서 누군가 엔드투엔드 그린 실행을 확인할 때까지 CI-트리거 경로를 실험적으로 취급하세요. 실제 인스턴스의 버그 보고는 매우 환영합니다.

GitLab CI(실험적)

gitl은 GitHub Action을 미러링하는 GitLab CI/CD 컴포넌트templates/gitl-review.yml — 도 제공합니다: 고정 버전의 go install로 gitl을 설치하고, 머지 리퀘스트의 범위($CI_MERGE_REQUEST_DIFF_BASE_SHA..$CI_COMMIT_SHA)를 리뷰하며, 공유 플랫폼 중립 ci/comment.sh를 통해 댓글을 렌더링하고, GitLab REST API를 통해 고정 MR 노트를 생성/업데이트합니다(GitHub/Gitea와 동일한 <!-- gitl-review --> 마커). 작업은 머지 리퀘스트 파이프라인에서만 실행됩니다.

컴포넌트는 이 저장소의 릴리스 시점 미러인 gitlab.com/alkom68/gitl을 통해 GitLab CI/CD 카탈로그에 게시됩니다(단방향 GitHub → GitLab, 모든 릴리스 태그에서 푸시). gitlab.com에서는 카탈로그 컴포넌트로 포함하세요:

# .gitlab-ci.yml (gitlab.com)
include:
  - component: gitlab.com/alkom68/gitl/gitl-review@v0.6.2
    inputs:
      fail_on: "never"      # default; set "high" to block risky MRs
      # max_cost_usd: "0.50"
      # gitl_version: "v0.6.2"

자체 호스팅 GitLab 인스턴스에서는 include:component가 같은 인스턴스의 컴포넌트만 해석합니다 — 대신 GitHub에서 직접 include:remote로 템플릿을 사용하세요(입력값은 원격 include에서도 작동합니다):

# .gitlab-ci.yml (self-hosted GitLab)
include:
  - remote: "https://raw.githubusercontent.com/akomyagin/gitl/v0.6.2/templates/gitl-review.yml"
    inputs:
      fail_on: "never"

설정 — 두 개의 CI/CD 변수(Settings → CI/CD → Variables, 둘 다 마스킹, 절대 YAML에 넣지 않음):

  • GITL_API_KEY — BYOK LLM 키. 선택 사항: 없으면 gitl은 결정적 오프라인 리뷰를 실행합니다(네트워크 없음, 비용 없음). 프로젝트 변수를 정의하는 것만으로 충분합니다 — 컴포넌트의 빈 gitl_api_key 입력 기본값보다 우선합니다. 입력을 사용하려면 변수 참조(gitl_api_key: $MY_LLM_KEY)를 전달하고, 리터럴 키는 절대 전달하지 마세요: 입력 값은 파이프라인 구성에 보간됩니다.

  • GITL_GITLAB_TOKEN — MR 노트 게시용 토큰(프로젝트 액세스 토큰 또는 PAT, api 범위, Reporter 이상 역할, PRIVATE-TOKEN으로 전송). 설정하지 않으면 작업은 CI_JOB_TOKEN(JOB-TOKEN 헤더)으로 폴백합니다 — 하지만 대부분의 GitLab 구성에서 CI_JOB_TOKEN은 Notes API에 권한이 없으므로 폴백은 실패할 것으로 예상됩니다(조용한 건너뜀이 아닌 명시적 오류 메시지와 함께). 명시적 GITL_GITLAB_TOKEN이 신뢰할 수 있는 경로입니다.

전체 주석 셀프테스트 파이프라인 — 완전한 사용 예제에 가장 가까운 것 — 은 .gitlab-ci-selftest.yml입니다(이 저장소의 GitLab 미러에서 .gitlab-ci.yml로 실행 가능).

검증 상태 — 이 기능에 의존하기 전에 읽어보세요. GitLab REST 호출(MR 노트 목록 + 고정 마커 감지, POST 생성, PUT 업데이트)과 컴포넌트 YAML 자체(spec:/inputs: 보간, 입력이 있는 include:local, CI Lint API를 통해)는 실제 로컬 GitLab CE 인스턴스(Docker의 gitlab/gitlab-ce 19.2.0)의 실제 머지 리퀘스트에서 엔드투엔드로 검증되었습니다 — 목록-비어있음 → POST-생성 → 재목록-발견 → PUT-업데이트 → 여전히 정확히 하나의 노트 — 템플릿의 정확한 curl/jq 명령을 사용했습니다. 아직 검증되지 않은 것은 실제 파이프라인 실행입니다: 실제 머지 리퀘스트 파이프라인에서 CI_MERGE_REQUEST_DIFF_BASE_SHA/CI_COMMIT_SHA/CI_JOB_URL의 값은 GitLab 문서에서 작성된 것이지 관찰된 것이 아니며, CI_JOB_TOKEN 폴백 거부는 GitLab의 작업 토큰 허용 목록 문서에 따라 문서화된 것이지 재현된 것이 아닙니다. 누군가 그린 엔드투엔드 실행을 확인할 때까지 파이프라인 경로를 실험적으로 취급하세요. 버그 보고 환영합니다.

신뢰 참고. 컴포넌트는 gitl_version에서 GitLab 미러(gitlab.com/alkom68/gitl)의 ci/comment.sh를 다운로드하여 실행합니다 — 체크섬/서명 검사 없이, 바로 위의 go install ...@${gitl_version} 줄과 동일한 신뢰 경계입니다(같은 저장소, 같은 ref). 이 가져오기는 컴포넌트가 어떻게 포함되든 관계없이 발생합니다 — 카탈로그 또는 include:remote — 컴포넌트 include는 컴포넌트 저장소의 파일이 아닌 YAML 템플릿만 제공하므로, 이 가져오기는 기계적으로 피할 수 없습니다. 컴포넌트를 게시하는 동일한 GitLab 인스턴스에서(GitHub가 아닌) 다운로드하면 동일 네임스페이스/동일 ref를 유지하여, 교차 호스트 가져오기보다 더 정직한 신뢰 모델입니다. 위협 모델에 중요하다면 gitl_version을 태그 대신 커밋 SHA로 고정하세요(태그는 이동 가능).

Bitbucket Pipelines(실험적)

Bitbucket 통합은 Pipe로 제공됩니다 — 그리고 pipe는 정의상 Docker 이미지이므로, GitHub/Gitea 액션과 GitLab 컴포넌트(일반 YAML 래퍼)와 달리 이 것은 자체 포함 이미지입니다: bitbucket-pipe/Dockerfile은 정적 gitl 바이너리를 빌드하고 공유 ci/comment.sh 렌더러와 엔트리포인트 bitbucket-pipe/pipe.sh를 포함합니다. pipe는 PR 범위($BITBUCKET_PR_DESTINATION_COMMIT..$BITBUCKET_COMMIT)를 해석하고, gitl review --format=json을 실행하며, Bitbucket Cloud REST API를 통해 고정 PR 댓글을 생성/업데이트합니다(다른 플랫폼과 동일한 <!-- gitl-review --> 마커). 변수 참조: bitbucket-pipe/pipe.yml.

이미지 상태. Docker Hubv0.5.2부터 alkom68/gitl-review-pipe로 게시됨 — 릴리스 워크플로의 docker-publish 작업이 모든 릴리스 태그에서 :<version>:latest를 푸시합니다. 레지스트리에는 0.5.2 이상만 존재합니다: 이전 릴리스는 게시 이전입니다(0.5.0/0.5.1 태그는 푸시된 적 없음), 그러니 그 버전을 고정하지 마세요.

# bitbucket-pipelines.yml
pipelines:
  pull-requests:
    '**':
      - step:
          name: gitl review
          clone:
            depth: full   # the default depth-50 clone may not contain the PR base commit
          script:
            - pipe: docker://alkom68/gitl-review-pipe:0.6.2
              variables:
                GITL_API_KEY: $GITL_API_KEY                    # BYOK; omit for offline review
                GITL_BITBUCKET_TOKEN: $GITL_BITBUCKET_TOKEN    # posts the PR comment
                # FAIL_ON: "high"        # default "never" — comment only, no gate
                # MAX_COST_USD: "0.50"

설정 — 두 개의 보안 저장소/워크스페이스 변수(Repository settings → Pipelines → Repository variables, 항상 $VAR로 참조, YAML에 리터럴 값 금지):

  • GITL_API_KEY — BYOK LLM 키. 선택 사항: 없으면 gitl은 결정적 오프라인 리뷰를 실행합니다(네트워크 없음, 비용 없음).

  • GITL_BITBUCKET_TOKEN — PR 댓글 게시용 자격 증명: pullrequest:write 범위의 저장소/프로젝트/워크스페이스 액세스 토큰, Authorization: Bearer로 전송. 대안: Basic 인증을 위해 GITL_BITBUCKET_USER + GITL_BITBUCKET_APP_PASSWORD(pullrequest:write 범위의 앱 비밀번호)를 설정. 둘 다 설정하지 않으면 pipe는 LLM 예산을 사용하기 전에 명시적 메시지와 함께 빠르게 실패합니다.

공급망 참고(이것이 GitLab 컴포넌트와 다른 이유). pipe는 런타임에 가져온 것을 실행하지 않습니다: gitl 바이너리, ci/comment.sh, 엔트리포인트는 모두 하나의 소스 트리에서 버전이 지정된 이미지에 빌드됩니다. GitLab 컴포넌트는 무결성 검사 없이 네트워크로 ci/comment.sh를 다운로드해야 합니다(위의 신뢰 참고 참조); pipe는 구조적으로 그 격차를 해소합니다.

검증 상태 — 이 내용을 신뢰하기 전에 읽어보세요. 이미지 빌드와 컨테이너 내 전체 흐름은 로컬에서 검증되었습니다: 이 저장소에서 docker build를 실행한 후, 에뮬레이션된 BITBUCKET_* 변수로 실제 테스트 git 저장소에 대해 docker run을 실행했습니다 — 오프라인 리뷰 → 올바른 sticky comment.md → 댓글 생성(POST), sticky 업데이트(PUT, 여전히 정확히 하나의 댓글) 및 --fail-on 종료 코드 전파를 로컬 Bitbucket 댓글 API 목(mock)에 대해 종단 간(end-to-end)으로 테스트했습니다; fail-fast 경로(자격 증명/PR 변수 누락)와 잘못된 범위에 대한 폴백 알림도 컨테이너에서 테스트했습니다. 아직 검증되지 않은 것: 실제 Bitbucket 인프라와 관련된 모든 것 — api.bitbucket.org에 대한 REST 호출(형태는 Atlassian API 문서에서 가져옴), 라이브 PR 파이프라인 내부의 정확한 사전 정의 변수(BITBUCKET_PR_DESTINATION_COMMIT 등은 문서화된 가정이지 관측된 값이 아님), 그리고 Pipelines가 클론을 pipe 컨테이너에 마운트하는 방식. 실제 Bitbucket 워크스페이스에서 녹색 실행이 확인될 때까지 라이브 파이프라인 경로는 실험적인 것으로 간주하세요; 버그 리포트는 환영합니다.

Pre-commit 훅 (로컬)

gitlpre-commit 프레임워크 훅을 제공하여 모든 커밋 전에 gitl review --staged --quiet가 자동으로 실행되도록 합니다 — 로컬에서, 오프라인으로, 기본적으로 비용 없이 실행됩니다(훅 매니페스트에서 --quiet가 기본적으로 켜져 있어 오프라인 알림이 매 커밋마다 다시 출력되지 않습니다).

저장소의 .pre-commit-config.yaml에 다음을 추가하세요:

repos:
  - repo: https://github.com/akomyagin/gitl
    rev: v0.6.2   # pin to a released tag
    hooks:
      - id: gitl-review

그런 다음 pre-commit install을 실행하세요. 프레임워크가 gitl 바이너리를 직접 빌드하고(language: golang) ~/.cache/pre-commit/ 아래에 환경을 캐시하므로 빌드 비용은 매 커밋마다가 아니라 한 번만 지불됩니다.

비용 상한이 있는 차단(blocking) 훅을 선택하려면:

hooks:
  - id: gitl-review
    args: [--fail-on=high, --max-cost-usd=0.05]   # opt-in: block on high risk, cap cost

실제 AI 리뷰를 위해 환경에 GITL_API_KEY를 내보내세요(export); 키가 없으면 훅은 결정적 오프라인 리뷰를 수행합니다(네트워크 없음, 비용 없음).

알아두어야 할 사항:

  • 기본적으로 오프라인. API 키 없음, 네트워크 없음, 커밋당 비용 없음. 실제 AI 리뷰를 선택하려면 GITL_API_KEY를 설정하세요.

  • 기본적으로 비차단(non-blocking). 훅은 리뷰를 출력하지만 커밋을 실패시키지 않습니다 — CLI/Action과 동일한 "기본적으로 WARN, 하드 게이트는 명시적 옵트인" 원칙입니다. 차단하려면 args: [--fail-on=high]를 추가하세요.

  • 지연 시간. 실제 API 리뷰는 몇 초가 걸립니다. 오프라인으로 두어 핫 경로에서 벗어나게 하거나 --max-cost-usd로 상한을 설정하세요.

  • Diff 프라이버시. 실제 키를 사용하면 스테이징된 diff가 설정된 LLM 공급자로 전송됩니다 — 비공개 코드에는 자체 호스팅/엔터프라이즈 공급자(Ollama, Azure OpenAI)를 사용하세요. 위의 Providers 섹션을 참조하세요.

  • 오프라인 알림 억제. 매니페스트는 기본적으로 --quiet를 전달하므로 커밋 시마다 출력되는 "결정적 오프라인 리뷰 사용 중" stderr 알림이 음소거됩니다. 동일한 스위치는 review/changelog에서 --quiet / GITL_QUIET로 사용할 수 있으며, 저장소 전체로는 output.quiet: true를 통해 사용할 수 있습니다(MCP 서버는 output.quiet/GITL_OUTPUT_QUIET만 인식합니다 — 플래그가 없으므로 짧은 GITL_QUIET 별칭은 여기서 적용되지 않습니다). 오류와 리뷰 출력 자체는 영향을 받지 않습니다.

pre-commit 프레임워크 없이

일반 git 훅도 작동합니다:

# .git/hooks/pre-commit  (chmod +x)
#!/usr/bin/env bash
set -euo pipefail
# Offline, non-blocking review of staged changes (WARN by default); --quiet
# suppresses the per-commit offline notice on stderr.
gitl review --staged --quiet || true
# To block the commit on high risk instead, replace the line above with:
#   gitl review --staged --quiet --fail-on=high

MCP 서버

gitl mcp는 gitl을 Model Context Protocol stdio 서버로 실행합니다 — 위의 CLI/CI 사용과는 별개의 추가 채널로, 셸에서 직접 실행하는 대신 에이전트 세션(Claude Desktop, Cursor, Windsurf 등) 내에서 gitl을 대화형으로 사용하기 위한 것입니다. 두 가지 도구를 제공합니다:

  • gitl_reviewgitl review와 동일한 리뷰 엔진: range/pr/staged(정확히 하나), 선택적 호출별 model 재정의. 공급자와 엔드포인트는 설계상 서버 시작 시 고정됩니다: 도구 호출자는 AI 에이전트이며, 리뷰 대상 콘텐츠 내의 프롬프트 인젝션으로 조종될 수 있습니다 — 호출별 base_url은 악의적인 커밋이 요청을 리디렉션하여 실제 API 키를 유출할 수 있게 합니다. 항상 구조화된 JSON 아티팩트를 반환합니다(md/text 렌더링 없음, 스트리밍 없음 — 도구 결과는 원자적입니다). risk.level은 데이터로 반환됩니다. 게이트할 프로세스 종료 코드가 없으므로 MCP 모드에는 --fail-on이 없습니다.

  • gitl_digestgitl digest와 동일: days(기본값 7), 선택적 repos. 명시적인 repos 인자 없이 도구는 서버의 작업 디렉토리만 다이제스트합니다(구성된 경우 .gitl.yamldigest.repos 추가) — 임의의 경로를 자체적으로 탐색하지 않습니다. 명시적인 repos 인자는 그대로 존중됩니다(호출 에이전트는 이미 자체 도구를 통해 파일시스템 접근 권한이 있습니다. 이는 접근 제어 경계가 아니라 "사용자를 놀라게 하지 말자"는 기본값일 뿐입니다).

MCP 클라이언트 구성(Claude Desktop, Cursor 등)에 추가하세요:

{
  "mcpServers": {
    "gitl": {
      "command": "gitl",
      "args": ["mcp"]
    }
  }
}

구성은 일반 명령과 동일한 방식으로 시작 시 한 번 로드됩니다(.gitl.yaml + 개인 구성 + GITL_* 환경 변수, gitl mcp가 실행된 디렉토리에서). 키가 없으면 도구 호출은 CLI와 동일한 결정적 오프라인 모드로 실행됩니다. stdout은 MCP 프로토콜 전용으로 예약되어 있습니다 — 사람이 읽을 수 있는 내용은 절대 출력되지 않습니다; 경고는 stderr로 전달됩니다.

라이선스

MIT.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/akomyagin/gitl'

If you have feedback or need assistance with the MCP directory API, please join our Discord server