AI code review in GitHub Actions, without a bot.
Add AI code review to a GitHub Actions workflow with no GitHub App to install: inline PR comments, a severity gate, or a policy gate, using your own provider key.
AI code review in GitHub Actions without a bot means the review runs as a step in your own workflow, on your own runner, with your own provider key, instead of through a third-party GitHub App that you install and grant repository access. CommitBrief ships this as one composite action, CommitBrief/commitbrief-action, and the same commands run on your laptop.
In short: one workflow file, one repository secret. Pick
commentmode for inline review comments,gatemode for a pass/fail check, orguardmode for a per-severity budget.
“Bot” needs a precise reading here. In comment mode the review comments are still posted to the pull request, but by your workflow’s own GITHUB_TOKEN, not by an installed app with its own webhook and its own copy of your diff. Nothing is installed on the repository, and there is no vendor account in the loop beyond the LLM provider you chose. comment mode drives the same remote pr command described in reviewing GitHub PRs from the terminal. For the longer version of that trade-off, see why a CLI and not a GitHub App and the broader comparison of AI code review tools.
The workflow file
Add .github/workflows/commitbrief.yml, and add your provider key as a repository secret (ANTHROPIC_API_KEY in this example):
name: CommitBrief
on:
pull_request:
types: [opened, synchronize, reopened]
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 }}
comment is the default mode. The Action downloads the prebuilt CLI for the runner, checks its SHA-256 against the release’s checksums.txt, and reviews the pull request. The checkout step is not optional: the Action does not check out the repository for you. The Action reference lists every input.
Each finding is posted as an inline comment, then a review verdict is submitted. By default that verdict is only ever approve or comment, and the step exits 0 once the review is submitted, whatever the findings were. Posting comments is not a gate.
Choosing a mode
| Mode | What it runs | Result | Needs |
|---|---|---|---|
comment (default) | commitbrief remote pr <number> | Inline comments plus a verdict | contents: read, pull-requests: write |
gate | commitbrief diff <base>...<head> --fail-on=<severity> | Pass or fail the job | contents: read |
guard | commitbrief guard --diff <base>...<head> --policy <path> | Pass or fail against a per-severity budget | contents: read |
You can run more than one. A common split is comment for the human-readable feedback and gate as a separate job for the merge check.
Make the check fail
- 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. On a pull_request event the default shallow checkout does not contain the base and head commits, and commitbrief diff fails on the missing objects. fail-on: high fails the job on a high or critical finding. The values are critical, high, medium, low, info, and any; Severity and CI gating defines each. The reasoning behind a threshold is in the --fail-on post.
Let the review request changes
- uses: CommitBrief/commitbrief-action@v1
with:
provider: anthropic
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
request-changes-on: high
This turns a high or critical finding into a request-changes review. It does not change the step’s exit code, which stays 0. If you want a red check, use gate.
A budget instead of a threshold
guard mode evaluates a committed .commitbrief/policy.yml, for example zero critical and zero high findings but up to five medium ones. A missing or malformed policy blocks rather than passes. guard needs fetch-depth: 0 on the checkout, like gate, and since CommitBrief adds .commitbrief/ to .gitignore, the policy file must be un-ignored explicitly with a !.commitbrief/policy.yml line or it never reaches the runner. See the CI gating guide, Policy gate, and the policy gate for AI-authored PRs.
Reproducing a CI failure locally
Every mode shells out to a command you can run yourself, so a red check is reproducible without pushing:
commitbrief diff origin/main...HEAD --fail-on=high
Limits to know before you turn it on
- Pull requests only. The Action reads the PR number and the base and head SHAs from the
pull_requestevent and fails without one. It is not apush-event tool. GitHub does not pass repository secrets to the runner for pull requests from forks, and givesGITHUB_TOKENread-only permissions there (GitHub’s event reference), so the review only works on branches in the same repository. - API providers only. The Action accepts
anthropic,openai,gemini,deepseek,mistral,cohere, andollama. The CLI-backed providersclaude-cli,gemini-cli, andcodex-cliare rejected, because a runner has no locally authenticated host CLI.ollamaneeds a reachable server, so it fits a self-hosted runner. - Every review is a paid call. The response cache lives inside the checkout, so each job starts cold.
- Large diffs can abort on the cost preflight. With no TTY, CommitBrief aborts instead of prompting when the estimate exceeds
cost.warn_threshold_usd(default$0.50). The Action has no--no-cost-checkinput; the ceiling is raised in a committed.commitbrief/config.yml, which must never contain anapi_keyand has to be un-ignored the same way as the policy file. See Safety, cost, and cache. - A model that returns unparseable output skips the gate. CommitBrief degrades to plain text and
--fail-onis skipped by design, so a greengaterun is not proof that the diff is clean. - It does not replace a human reviewer. It reads the diff; it does not know why you made the change.
One action
Copy the first workflow into a branch, add the secret, and open a pull request against it. Check what the review posted before you decide whether to add a gate job.
Related reading
- Jun 25, 2026`--fail-on`: turning an LLM review into a CI gate without locking yourself in.
How severity-based exit codes work, why graceful degrade deliberately skips the gate, and what 'fail at critical or worse' actually means inside your pipeline.
- Oct 8, 2026A policy gate for AI-authored PRs: when a single fail-on threshold stops being enough.
commitbrief guard evaluates a review against a declarative .commitbrief/policy.yml — per-severity budgets, an optional total, pass or block. And a consume mode that gates a review someone else already ran, with no second provider call.
- Oct 3, 2026Reviewing a GitHub PR from your terminal: inline comments and a verdict, no bot required.
commitbrief remote pr pulls a PR's diff through gh, runs the review pipeline, and posts each finding as an inline comment with a verdict — request-changes strictly opt-in. A terminal command you own the trigger for, not an App watching your repo.