Skip to content

leek/ai-commit-review

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI Commit Review

GitHub Action that reviews a single commit with Claude, GPT, and Gemini in parallel, deduplicates findings, files them as a GitHub Issue, and optionally opens a draft PR with high-confidence fixes that multiple models agree on.

Designed to be called inside a per-commit matrix on push events. The action reviews one commit per invocation — your workflow handles enumeration.

Quickstart

name: AI Commit Review

on:
  push:
    branches: [main]

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  enumerate:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.commits.outputs.matrix }}
      count: ${{ steps.commits.outputs.count }}
    steps:
      - uses: actions/checkout@v6
        with: { fetch-depth: 0 }
      - id: commits
        env:
          BEFORE: ${{ github.event.before }}
          AFTER: ${{ github.event.after }}
        run: |
          if [[ "$BEFORE" == "0000000000000000000000000000000000000000" ]]; then
            SHAS=$(git log --format='%H' -1 "$AFTER")
          else
            SHAS=$(git log --format='%H' "${BEFORE}..${AFTER}")
          fi
          MATRIX=$(echo "$SHAS" | jq -R -s -c 'split("\n") | map(select(. != "")) | map({sha: .})')
          echo "count=$(echo "$MATRIX" | jq 'length')" >> "$GITHUB_OUTPUT"
          echo "matrix=${MATRIX}" >> "$GITHUB_OUTPUT"

  review:
    needs: enumerate
    if: needs.enumerate.outputs.count != '0'
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      max-parallel: 5
      matrix:
        commit: ${{ fromJson(needs.enumerate.outputs.matrix) }}
    steps:
      - uses: actions/checkout@v6
        with: { fetch-depth: 0 }

      - uses: leek/ai-commit-review@v1
        with:
          commit-sha: ${{ matrix.commit.sha }}
          anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          openai-api-key: ${{ secrets.OPENAI_API_KEY }}
          gemini-api-key: ${{ secrets.GEMINI_API_KEY }}

Any provider whose API key is empty is skipped. Run with one, two, or all three.

CLI auth modes

Claude and OpenAI can also run through their local coding CLIs instead of direct API calls:

  • Claude CLI mode runs claude -p through Claude Code.
  • OpenAI CLI mode runs codex exec through Codex. The provider is still named openai in reports so existing digesting and agreement logic keeps working.
  • Gemini remains API-key only for now.

The default auth mode for Claude and OpenAI is auto, which preserves existing workflows:

  • Claude uses CLI mode when claude-code-oauth-token is set; otherwise it uses anthropic-api-key.
  • OpenAI uses CLI mode when codex-access-token or codex-auth-json is set; otherwise it uses openai-api-key.
  • Set claude-auth or openai-auth to api or cli to force a mode.

The action installs missing claude and codex commands when CLI mode is selected. Set install-cli-tools: false if your runner already has them.

CLI modes run from the caller's checked-out repository and receive the commit-sha explicitly. Use actions/checkout with fetch-depth: 0 so the CLIs can inspect the commit and surrounding repository context. Unlike API mode, CLI mode does not embed the filtered diff in the prompt; Claude and Codex inspect the commit from the checkout themselves. Claude is limited to read/search/git shell tools. Codex defaults to codex-sandbox: danger-full-access because its Linux read-only sandbox depends on user namespaces that may be unavailable on GitHub-hosted runners. The action verifies afterward that the checkout has no tracked changes and no unexpected untracked files.

Codex CLI mode writes project_doc_fallback_filenames = ["CLAUDE.md"] to CODEX_HOME/config.toml, so repositories that use CLAUDE.md instead of AGENTS.md are still picked up by Codex's project-doc discovery.

The default Claude model is claude-opus-4-8. If you set install-cli-tools: false, make sure the runner's Claude Code install supports Opus 4.8.

Example: Claude Code + Codex CLI

- uses: leek/ai-commit-review@v1
  with:
    commit-sha: ${{ matrix.commit.sha }}
    claude-auth: cli
    openai-auth: cli
    claude-code-oauth-token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
    codex-access-token: ${{ secrets.CODEX_ACCESS_TOKEN }}

Example: Codex CLI with auth.json

Use this only on trusted private automation. auth.json contains access tokens.

- uses: leek/ai-commit-review@v1
  with:
    commit-sha: ${{ matrix.commit.sha }}
    openai-auth: cli
    codex-auth-json: ${{ secrets.CODEX_AUTH_JSON }}

Where to get CLI tokens

  • Claude Code: run claude setup-token, then store the printed token as CLAUDE_CODE_OAUTH_TOKEN. Anthropic documents this in Generate a long-lived token.
  • Codex access token: create a token in ChatGPT admin settings and store it as CODEX_ACCESS_TOKEN. OpenAI documents this in Codex access tokens.
  • Codex auth.json: sign in locally with codex login, then seed a trusted runner or CI secret with the file contents. By default the file is at ~/.codex/auth.json; on macOS you can copy it with pbcopy < ~/.codex/auth.json. OpenAI documents the advanced workflow in Maintain Codex account auth in CI/CD.

Do not expose CLI account credentials to public repositories, fork-triggered workflows, or untrusted runners.

Inputs

Input Default Description
commit-sha required Commit SHA to review. Caller must actions/checkout with fetch-depth: 0.
anthropic-api-key empty Anthropic API key. Provider runs only when set.
openai-api-key empty OpenAI API key.
gemini-api-key empty Gemini API key.
claude-auth auto Claude provider auth mode: auto, api, or cli.
openai-auth auto OpenAI provider auth mode: auto, api, or cli.
claude-code-oauth-token empty Claude Code OAuth token from claude setup-token. Enables Claude CLI mode in auto.
codex-access-token empty Codex access token passed as CODEX_ACCESS_TOKEN. Enables Codex CLI mode in auto.
codex-auth-json empty Contents of a Codex auth.json file for Codex CLI mode. Use only on trusted private runners.
codex-home empty Optional CODEX_HOME path for Codex CLI mode. Useful for self-hosted runners with persistent auth.
install-cli-tools true Install missing Claude Code or Codex CLI tools when a CLI mode is selected.
claude-cli-path claude Claude Code CLI command path used in Claude CLI mode.
codex-cli-path codex Codex CLI command path used in OpenAI CLI mode.
codex-sandbox danger-full-access Codex sandbox mode used in OpenAI CLI mode. Use read-only only on runners where Codex's Linux sandbox can create user namespaces.
claude-model claude-opus-4-8 Anthropic model id.
openai-model gpt-5.5 OpenAI model id.
gemini-model gemini-3.5-flash Gemini model id.
claude-context-file empty Project context file injected into the Claude prompt.
openai-context-file empty Project context file injected into the OpenAI prompt.
gemini-context-file empty Project context file injected into the Gemini prompt.
prompt-file empty Path to a custom prompt template. Overrides the bundled generic prompt.
exclude-paths empty Newline-separated git pathspecs excluded from the diff. Use the :!path syntax.
max-diff-lines 5000 Skip review if filtered diff exceeds this many added/changed lines.
skip-message-patterns Merge* Newline-separated bash globs matched against the commit subject.
skip-author-patterns empty Newline-separated bash globs matched against the commit author name.
min-severity-for-issue warning One of critical, warning, info.
min-models-for-fix-pr 2 Number of providers that must agree on a high-confidence fix before a fix PR is opened. 0 disables.
issue-label ai-review Label applied to created issues.
issue-title-prefix [AI Review] Issue title prefix.
fix-pr-title-prefix [AI Fix] Suggested fixes for Fix PR title prefix.
fix-branch-prefix ai-fix/ Fix branch prefix. Short SHA is appended.
base-branch main Base branch for fix PRs.
github-token ${{ github.token }} Token used to create issues, comments, branches, and PRs.
node-version 20 Node.js version.

Outputs

Output Description
reviewed true if the commit was reviewed, false if skipped.
skip-reason Reason the commit was skipped, if any.
diff-line-count Added/changed line count of the filtered diff.
critical-count Critical findings after dedup.
warning-count Warning findings after dedup.
info-count Info findings after dedup.
issue-url URL of the created issue, if any.
fix-pr-url URL of the created draft fix PR, if any.
provider-failures Comma-separated provider names that failed to produce a valid review.
provider-successes Comma-separated provider names that produced a valid review.
provider-skips Comma-separated provider names skipped because credentials or supported auth modes were not provided.

Example: project-tuned

- uses: leek/ai-commit-review@v1
  with:
    commit-sha: ${{ matrix.commit.sha }}
    anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
    openai-api-key: ${{ secrets.OPENAI_API_KEY }}
    gemini-api-key: ${{ secrets.GEMINI_API_KEY }}
    claude-context-file: CLAUDE.md
    openai-context-file: AGENTS.md
    gemini-context-file: GEMINI.md
    prompt-file: .github/ai-review-prompt.txt
    exclude-paths: |
      :!package-lock.json
      :!yarn.lock
      :!vendor/
      :!node_modules/
      :!tests/
    skip-message-patterns: |
      Merge*
      build(deps)*
      *skip-review*
      *skip-ci*
      *fix code style*
      *Fix Code Style*
      ai-review:*
    skip-author-patterns: |
      *dependabot*

Pattern syntax: skip-message-patterns and skip-author-patterns are bash glob patterns. Avoid [...] — bash treats it as a character class, not a literal substring. Write *skip-review*, not *[skip-review]*.

How it works

  1. Skip check — matches the commit subject and author against your skip patterns.
  2. Diff filtergit diff sha~1 sha with your exclude-paths applied. Skips if larger than max-diff-lines.
  3. Provider fan-out — runs Claude, GPT/OpenAI, and Gemini in sequence. Claude and OpenAI can use either direct API calls or their CLI modes. Each provider receives the bundled (or custom) prompt, optional project context, and the diff.
  4. Digest — merges findings, dedupes by file + line proximity + severity, builds a markdown report, files it as an issue. Optionally opens a draft fix PR for high-confidence findings that multiple models agree on.

Permissions

The workflow needs:

permissions:
  contents: write       # for the fix PR branch
  issues: write         # for finding issues
  pull-requests: write  # for the fix PR

Notes

  • The action does not enumerate commits. Drive the matrix from your workflow so failures isolate per-commit.
  • Existing issues for the same short SHA are detected and creation is skipped.
  • All API calls have two retries on 5xx responses.
  • CLI modes normalize their output through the same findings parser and self-retraction filter as API modes.
  • Selected providers that fail to produce valid review JSON are reported in provider-failures and logged as warnings when at least one other provider succeeds. The action fails only when no selected provider produces a valid review.

License

MIT

About

GitHub Action that reviews a single commit with Claude, GPT, and Gemini in parallel

Resources

License

Stars

4 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors