// blog

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 comment mode for inline review comments, gate mode for a pass/fail check, or guard mode 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

ModeWhat it runsResultNeeds
comment (default)commitbrief remote pr <number>Inline comments plus a verdictcontents: read, pull-requests: write
gatecommitbrief diff <base>...<head> --fail-on=<severity>Pass or fail the jobcontents: read
guardcommitbrief guard --diff <base>...<head> --policy <path>Pass or fail against a per-severity budgetcontents: 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_request event and fails without one. It is not a push-event tool. GitHub does not pass repository secrets to the runner for pull requests from forks, and gives GITHUB_TOKEN read-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, and ollama. The CLI-backed providers claude-cli, gemini-cli, and codex-cli are rejected, because a runner has no locally authenticated host CLI. ollama needs 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-check input; the ceiling is raised in a committed .commitbrief/config.yml, which must never contain an api_key and 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-on is skipped by design, so a green gate run 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


← all posts