Skip to main content
Glama

gitl

Action self-test

AIを活用したCLIおよびCI向けgit履歴レビュアー。 gitl(git-log-lens)はリポジトリのgit履歴を読み取り、LLMを介して構造化されたエンジニアリング成果物に変換します:

  • gitl review <range> — コミット範囲/PRのAIレビュー。機械可読なリスクスコア(low|medium|high)を出力し、CIゲーティング(--fail-on=high → 終了コード2)に対応。トークンをリアルタイムでターミナルにストリーミング。オンディスクのLLM応答キャッシュと、CI用のオプション共有リモートキャッシュを備える。カスタムシステムプロンプトテンプレート対応。--staged は git commit 前のステージ済み(未コミット)変更をレビュー(pre-commitフックとしても利用可能)。

  • gitl changelog [<range>] — Keep a Changelogスタイルのチェンジログを、conventional commitsでグループ化して生成(デフォルトは最後のタグ → HEAD)。デフォルトでは決定的で、--ai を指定するとモデルが読みやすいリリースノート散文に書き換えます。

  • gitl digest [--days=N] [--repos=a,b,c] — 著者/トピック/ファイル別のアクティビティサマリー。複数リポジトリを並列処理。インタラクティブなTUIビューア(--tui)付き。

クリーンなCLIバイナリとGitHub Actionラッパー。サーバー、データベース、ホステッドキーストレージは不要。BYOK(bring your own key)で、OpenAI互換API、Ollama(ローカル/セルフホスト)、Azure OpenAI、ネイティブAnthropic(Claude)、Google Geminiなど複数プロバイダーに対応。テレメトリなし。

ステータス: v0.6.2 リリース済み — 3つのコマンドすべてが実リポジトリで動作し、3つの出力形式(md|text|json)に対応。ActionはAIレビューをスティッキーなPRコメントとして投稿し、リスクスコアでゲートします。リリースバイナリはクロスコンパイルされ、cosign署名、SLSA L3ビルド来歴でカバーされています(VERIFY.md参照)。

クイックスタート

Go 1.22+ と git が PATH に必要です。

# 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 で別の場所に書き込めます)。このセクションからコピーペーストする代わりに、それを編集してください — 以下は完全なリファレンスです。

2つのレベルがあり、優先度でマージされます: フラグ > 環境変数 > .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 プロバイダーでは、gitl は output.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)。同一の差分は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_version は 1 のまま。それ以前のコンシューマーは同じドキュメントに2つの新しいキーが追加されたものを見ます):

{
  "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エンドポイントにより、あるランナーが同じ差分の別のランナーのレビューを再利用できます。

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} → 200 でJSONエントリ本体、または 404 = ミス。その他のステータス、ネットワークエラー、タイムアウトはミスとして扱われます。

  • PUT {url}/{key} でJSONエントリをリクエストボディとして送信(Content-Type: application/json)→ 任意の 2xx = 保存成功。

  • token_env が非空の値を持つ環境変数を指定している場合、両方のリクエストに Authorization: Bearer <token> が含まれます。トークン自体は設定ファイルから読み取られることはありません(GITL_API_KEY と同じ規律)。

  • キーは64文字の16進SHA-256文字列。値はサーバーにとって不透明です。

安全契約: リモートの障害(タイムアウト、5xx、到達不能なエンドポイント)は、ローカルキャッシュ/キャッシュなしに静かに劣化します — レビューを失敗させることはありません。保存されたエントリにはモデルの応答のみが含まれ、不透明なハッシュでキー付けされます:差分やプロンプトテキストがリモートキャッシュに到達することはありません。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日)」 セクションを表示します — レベル別のレビュー数、高リスクの方向(ウィンドウの前半と後半の比較)、直近のいくつかのレビュー。--format=json ではオプションの risk_trend フィールドとして表示されます(schema_version は 1 のまま。それ以前のコンシューマーは以前と同じドキュメントを見ます)。履歴のないリポジトリはセクションを省略します。

レビューは 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_file — 独自のチェンジログシステムプロンプト。gitl changelog --ai でのみ使用されます:

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

    チェンジログシステムプロンプトテンプレートは {{ .Commits }}、{{ .Range }}、{{ .Grouped }} にアクセスできます — {{ .Diff }} ではありません:changelog --ai はコミットメタデータから動作し、差分はなく、.Diff を使用するレビュー形式のテンプレートはここでは失敗します。これがまさに2つのキーが分離されている理由です:各コマンドは自分のキーのみを読み取り、どちらか一方だけを設定できます。

  • 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として配線できます:PRのコミットを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-key は secrets.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 の故障」を区別できます。

  • 差分のプライバシー。 CI では、差分は設定された LLM プロバイダー(デフォルト: OpenAI 互換 API)に送信されます。プライベートコードの場合は、セルフホスト/エンタープライズプロバイダー(Ollama、Azure OpenAI)を使用してください — 上記の Providers を参照。

  • プロバイダーの選択。 デフォルトでは、Action は設定ファイルのプロバイダー(未設定の場合は OpenAI 互換)を使用します。ネイティブプロバイダーを対象にするには、provider:(openai|ollama|azure_openai|anthropic|gemini)を渡し、必要に応じて model: と base-url: を gitl-api-key: と一緒に渡します。3 つとも任意で、省略した場合は .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.yml が Gitea Actions でも実行されます — Gitea のランナーは GitHub スタイルのコンポジットアクションを実行し、gitl のアクションは Gitea の act_runner がすべてのジョブに注入する GITEA_ACTIONS=true 変数を通じて実行時にプラットフォームを検出します。プラットフォーム固有の部分 — スティッキー PR コメントの投稿 — は、GitHub の API しか話せない gh CLI の代わりに、curl で Gitea の REST API(POST/PATCH /api/v1/repos/{owner}/{repo}/issues/...)を通じて行われます。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 更新 → それでもコメントはちょうど 1 つ。その部分は書かれたとおりに動作します。まだ検証されていないのは、周囲の act_runner CI コンテキストです: GITEA_ACTIONS/GITHUB_API_URL/PR イベントペイロードがライブのワークフロー実行内で想定どおりに見えるかどうか(これは Gitea/act_runner/act-fork のソースと照合されましたが、実際のジョブ内で実行されたわけではありません)。実際の Gitea Actions 内でエンドツーエンドのグリーン実行が確認されるまで、CI トリガーパスは実験的として扱ってください。実際のインスタンスからのバグ報告は大歓迎です。

GitLab CI(実験的)

gitl は GitLab CI/CD コンポーネントも同梱しています — templates/gitl-review.yml — GitHub Action をミラーリングしたものです: 固定バージョンで 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)(一方向 GitHub → GitLab、すべてのリリースタグでプッシュ)を通じて GitLab CI/CD Catalog に公開されています。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 でテンプレートを利用してください(inputs はリモートインクルードでも機能します):

# .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"

セットアップ — 2 つの 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: 補間、inputs 付き include:local、CI Lint API 経由)は、実際のローカル GitLab CE インスタンス(Docker 内の gitlab/gitlab-ce 19.2.0)上の実際のマージリクエストに対してエンドツーエンドで検証されました — 一覧が空 → POST 作成 → 再一覧で検出 → PUT 更新 → それでもノートはちょうど 1 つ — テンプレートの正確な 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)。このフェッチは、コンポーネントがどのように含まれるかに関係なく発生します — Catalog でも include:remote でも — コンポーネントインクルードは 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 を組み込みます。パイプは PR 範囲($BITBUCKET_PR_DESTINATION_COMMIT..$BITBUCKET_COMMIT)を解決し、gitl review --format=json を実行し、Bitbucket Cloud REST API を通じてスティッキー PR コメントを作成/更新します(他のプラットフォームと同じ <!-- gitl-review --> マーカー)。変数リファレンス: bitbucket-pipe/pipe.yml。

イメージステータス。 Docker Hub に alkom68/gitl-review-pipe として v0.5.2 から公開されています — リリースワークフローの 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"

セットアップ — 2 つの保護されたリポジトリ/ワークスペース変数(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 付きアプリパスワード)を設定します。どちらも設定されていない場合、パイプは LLM 予算を使う前に、明示的なメッセージで即座に失敗します。

サプライチェーンに関する注意(これが GitLab コンポーネントと異なる理由)。 パイプは実行時にフェッチされたものを実行しません: gitl バイナリ、ci/comment.sh、エントリポイントはすべて、1 つのソースツリーからバージョン付きイメージに組み込まれています。GitLab コンポーネントは整合性チェックなしで ci/comment.sh をネットワーク経由でダウンロードする必要があります(上記の信頼に関する注意を参照)。パイプはそのギャップを構造的に埋めます。

検証ステータス — 参照する前にお読みください。 イメージのビルドと コンテナ内のフルフローはローカルで検証済みです: このリポジトリからの docker build、 その後、エミュレートされた BITBUCKET_* 変数を使った実際のテスト用 git リポジトリに対する docker run — オフラインレビュー → 正しいスティッキー comment.md → コメント作成 (POST)、スティッキー更新 (PUT、依然として正確に1つのコメント) と --fail-on 終了コードの伝播を、Bitbucket コメント API のローカルモックに対して エンドツーエンドで実行しました。フェイルファストパス (認証情報/PR 変数の欠落) と 不正なレンジに対するフォールバック通知もコンテナ内で実行しました。 まだ検証されていないもの: 実際の Bitbucket インフラに触れるもの — api.bitbucket.org に対する REST 呼び出し (形状は Atlassian の API ドキュメントから取得)、 ライブ PR パイプライン内の正確な定義済み変数 (BITBUCKET_PR_DESTINATION_COMMIT などは 文書化された仮定であり、観測された値ではありません)、および Pipelines がパイプコンテナに クローンをマウントする方法。実際の Bitbucket ワークスペースでグリーンランが確認されるまで、 ライブパイプライン のパスは実験的として扱ってください。バグ報告は歓迎します。

Pre-commit フック (ローカル)

gitl には pre-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/ の下にキャッシュするため、 ビルドコストはコミットごとではなく一度だけ支払われます。

コスト上限付きのブロッキングフックをオプトインするには:

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 をエクスポートしてください。これがない場合、 フックは決定的なオフラインレビューを実行します (ネットワークなし、コストなし)。

知っておくべきこと:

  • デフォルトでオフライン。 API キーなし、ネットワークなし、コミットごとのコストなし。 GITL_API_KEY を設定すると、実際の AI レビューをオプトインできます。

  • デフォルトで非ブロッキング。 フックはレビューを表示しますが、コミットを失敗させません — CLI/Action と同じ「デフォルトでは WARN、ハードゲートは明示的なオプトイン」の原則です。 ブロックするには args: [--fail-on=high] を追加します。

  • レイテンシ。 実際の API レビューには数秒かかります。オフラインのままにしてホットパスから 外すか、--max-cost-usd で上限を設定してください。

  • 差分のプライバシー。 実際のキーを使用すると、ステージングされた差分は設定した LLM プロバイダーに送信されます — プライベートコードにはセルフホスト/エンタープライズプロバイダー (Ollama、Azure OpenAI) を使用してください。上記のプロバイダーを参照してください。

  • オフライン通知の抑制。 マニフェストはデフォルトで --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 を使用するためのものです。 2つのツールを公開します:

  • gitl_review — gitl review と同じレビューエンジン: range/pr/staged (いずれか 1つのみ)、オプションの呼び出しごとの model オーバーライド。プロバイダーとエンドポイントは 設計上、サーバー起動時に固定されます: ツール呼び出し元は AI エージェントであり、レビュー対象の コンテンツ内のプロンプトインジェクションによって誘導される可能性があります — 呼び出しごとの base_url を許可すると、悪意のあるコミットがリクエストをリダイレクトして実際の API キーを 漏洩させる可能性があります。常に構造化された JSON アーティファクトを返します (md/text レンダリングなし、 ストリーミングなし — ツールの結果はアトミックです)。risk.level はデータとして返されます。 ゲートするプロセス終了コードがないため、MCP モードには --fail-on はありません。

  • gitl_digest — gitl digest と同じ: days (デフォルト 7)、オプションの repos。 明示的な repos 引数がない場合、ツールはサーバーの作業ディレクトリのみをダイジェストします (設定されていれば .gitl.yaml の digest.repos も追加)。独自の判断で任意のパスを走査することは ありません。明示的な repos 引数はそのまま尊重されます (呼び出し元のエージェントは独自のツールを 通じてファイルシステムアクセスをすでに持っています。これはアクセス制御の境界ではなく、 「ユーザーを驚かせない」ためのデフォルトにすぎません)。

MCP クライアント設定 (Claude Desktop、Cursor など) に追加してください:

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

設定はプレーンなコマンドと同じ方法で起動時に一度だけ読み込まれます (.gitl.yaml + 個人設定 + GITL_* 環境変数、gitl mcp が起動されたディレクトリから)。キーがない場合、 ツール呼び出しは CLI と同じ決定的なオフラインモードで実行されます。stdout は MCP プロトコル用に 予約されています — 人間が読めるものはそこに書き込まれることはありません。警告は stderr に送られます。

ライセンス

MIT。

Related MCP Connectors

Related MCP Servers