GitHub Action — review in CI
CommitBrief/commitbrief-action runs the CLI on every pull request — inline review comments, a severity gate, or a declarative policy gate.
CommitBrief/commitbrief-action is a composite GitHub Action that
runs an LLM code review on every pull request. Add it to a workflow
with uses: CommitBrief/commitbrief-action@v1, give it a provider and
an API key, and it installs the CommitBrief CLI on the runner and
reviews the PR diff in one of three modes: post inline review comments
with a verdict (comment), fail the job on finding severity (gate),
or evaluate a declarative policy file (guard).
It is a thin wrapper — every mode shells out to a CommitBrief command you can run locally, so a CI failure reproduces on your machine.
Quick start
Add .github/workflows/commitbrief.yml to the repo you want reviewed:
name: CommitBrief
on: pull_request
permissions:
contents: read
pull-requests: write # comment mode posts the review
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: CommitBrief/commitbrief-action@v1
with:
provider: anthropic
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
That is the whole setup for comment mode (the default). The Action
installs Go, runs go install github.com/CommitBrief/commitbrief/cmd/commitbrief@latest,
and reviews the pull request.
The checkout step is not optional. The Action does not check out
your repository for you, and none of the three modes work without a
git working tree: comment mode resolves the target repo from the git
remote, and gate / guard diff two commits that have to exist
locally.
Inputs
| Input | Default | Required | What it does |
|---|---|---|---|
provider |
— | yes | anthropic, openai, gemini, deepseek, mistral, cohere, or ollama. Anything else fails the step. |
api-key |
"" |
no | Provider API key. Pass a repository secret. Not needed for ollama. |
model |
"" |
no | Model override. Empty uses the provider’s default. |
mode |
comment |
no | comment, gate, or guard. |
request-changes-on |
"" |
no | comment mode: severity at or above which the verdict becomes request-changes (critical, high, medium, low). Empty — the default — never requests changes. |
fail-on |
high |
no | gate mode: fail the job when a finding meets or exceeds this severity (critical, high, medium, low, info, any). |
policy |
.commitbrief/policy.yml |
no | guard mode: policy file path, relative to the repo root. |
version |
latest |
no | The go install ref for the CLI, e.g. v1.16.0. |
request-changes-on, fail-on, and policy are each read by exactly
one mode and ignored by the other two.
Permissions
| Mode | Required permissions: |
|---|---|
comment |
contents: read and pull-requests: write |
gate |
contents: read |
guard |
contents: read |
comment mode posts through the workflow’s own GITHUB_TOKEN, which
is why it needs pull-requests: write. Grant that only for the mode
that uses it — a gate-only workflow should stay read-only.
Mode: comment
Runs commitbrief remote pr <number>. Each
finding is posted as an inline review comment on the PR, then a
verdict is submitted.
- uses: CommitBrief/commitbrief-action@v1
with:
provider: anthropic
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
mode: comment # default
request-changes-on: high # opt in to a blocking verdict
Without request-changes-on the verdict is only ever approve or
comment — the review never blocks a merge. Setting it to high
turns any high or critical finding into a request-changes review.
The full verdict table, and the comment-volume caps that come with
each threshold, are in
Review a GitHub PR.
The step exits 0 whenever the review submits successfully, verdict
included. comment mode reports through GitHub, not through the exit
code; use gate or guard if you want a red check.
Mode: gate
Runs commitbrief diff <base>...<head> --fail-on=<severity>.
No comments, no PR write access — just a pass/fail check.
- uses: actions/checkout@v4
with:
fetch-depth: 0 # both PR endpoints must be local
- uses: CommitBrief/commitbrief-action@v1
with:
provider: openai
api-key: ${{ secrets.OPENAI_API_KEY }}
mode: gate
fail-on: high
fetch-depth: 0 matters here. On a pull_request event the default
shallow checkout does not contain the base and head commits the Action
diffs, and commitbrief diff fails on the missing objects. What the
severities mean, and which exit code each produces, is in
Severity and CI gating.
Mode: guard
Runs commitbrief guard --diff <base>...<head> --policy <path>.
A per-severity budget rather than a single threshold — useful when a
repo takes a high volume of AI-authored pull requests.
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: CommitBrief/commitbrief-action@v1
with:
provider: anthropic
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
mode: guard
policy: .commitbrief/policy.yml # default
Requires CLI v1.10.0 or newer — pin version: accordingly if you
are not on latest. The policy file has to be committed, and
CommitBrief adds .commitbrief/ to your .gitignore on its first
cache write, so un-ignore the one file explicitly:
.commitbrief/
!.commitbrief/policy.yml
A missing or malformed policy blocks rather than passes — see Policy gate.
Secrets
api-key is the only secret the Action takes. Pass it from a
repository (or organization) secret and let the Action map it to the
environment variable the CLI reads:
provider |
Environment variable set for the CLI |
|---|---|
anthropic |
ANTHROPIC_API_KEY |
openai |
OPENAI_API_KEY |
gemini |
GEMINI_API_KEY |
deepseek |
DEEPSEEK_API_KEY |
mistral |
MISTRAL_API_KEY |
cohere |
COHERE_API_KEY |
ollama |
none — leave api-key empty |
ollama needs no key but does need a reachable server, so it is
practical only on a self-hosted runner or with a service container;
point the CLI at it with OLLAMA_HOST in the workflow’s env:.
The three CLI-backed providers
— claude-cli, gemini-cli, codex-cli — are rejected outright by
the provider input. They drive a locally authenticated host CLI,
which a CI runner does not have.
Pinning versions
Two versions are in play, and they are pinned separately.
- The Action —
uses: CommitBrief/commitbrief-action@v1.v1is a moving tag: it is repointed as the Action changes, so a behavioral fix reaches you without a workflow edit. Pin a commit SHA instead if your organization requires immutable third-party actions. - The CLI — the
version:input, defaultlatest. Pin a released tag (version: v1.16.0) for reproducible CI;latestfollows the newest release and can change what your gate flags from one run to the next.
Each mode has a CLI floor:
| Mode | Needs CLI |
|---|---|
gate |
v0.9.0+ (the diff subcommand) |
comment |
v1.1.0+ (remote pr) |
guard |
v1.10.0+ (commitbrief guard) |
Notes for CI
- Pull requests only. The Action reads the PR number, base SHA,
and head SHA from the
pull_requestevent payload and fails immediately without one. It is not apush-event tool. - Large diffs can abort on the cost preflight. CommitBrief aborts
rather than prompts when it is not on a TTY and the estimated spend
exceeds
cost.warn_threshold_usd(default$0.50). The Action exposes no--no-cost-checkinput; raise or disable the ceiling in a committed.commitbrief/config.yml— the cost key only, never anapi_key— un-ignored the same way as the policy file. See Safety, cost, and cache. - The cache never survives a run. The response cache lives at
.commitbrief/cacheinside the checkout, so every job starts cold and every review is a paid call. COMMITBRIEF.mdis honored. The Action reviews a real checkout, so your committed review rules apply in CI exactly as they do locally.
See also
- Review a GitHub PR — remote pr — the command
behind
commentmode, and how to run it from your own terminal. - Severity and CI gating — the severity scale and
--fail-on, behindgatemode. - Policy gate — guard — the policy file format,
behind
guardmode. - Providers — which provider to pick, and what a review costs.