Automated, Google Gemini-based Pull Request reviews and Issue Triaging for all your GitHub repositories and CI/CD pipelines.
See the supporting blog post about this action here.
- Features Overview
- Author
- License
- How It Works
- The "Clean Slate" Advantage
- Setup & Use
- Authentication with Gemini API Key
- Google Developer Knowledge MCP Integration (Optional)
- On-Demand Agent Skills (Coding Guidelines)
- PR Comment History & Discussion Thread Tracking
- Setup Using Install-Gemini-Code-Review-Action Skill (Recommended)
- Alternative Manual Setup: PR Review Action Definition
- Seeing It In Action
- Issues Triage Action Definition
- Configuration
- Understanding the Token Usage & Cost Efficiency Report
- Pipeline Architecture & Execution
- Alternative Authentication
- Development & Releases
- Cost Attribution & Estimation
- AI-Powered Code Reviews: Automated, constructive line-specific feedback on Pull Requests using Google Gemini models (Gemini 3.7 Flash by default).
- Automated Issue Triage: Dynamically labels, prioritises, and triages incoming issues.
- PR Comment & Discussion Thread History: Automatically retrieves inline review threads and general PR conversation comments, enabling Gemini to track issue resolution, respect developer justifications/disagreements, and avoid repeating resolved suggestions across commits.
- Billing Labels for Cost Attribution (Vertex AI only): Tags every request with Cloud Billing labels (
component,repo), so spend per repository is a group-by in the billing export rather than a sum of numbers in review comments. - Tokenomics & Cost Telemetry Report: Appends a collapsible token usage and estimated dollar cost summary to each review, with the rate that was applied stated alongside it.
- Drop-in Migration: Fully compatible as a direct, drop-in replacement for the deprecated
run-gemini-cliaction. - Structured Outputs: Error-free JSON response formatting using Pydantic schema validation.
- Hybrid Codebase Context: Automatically includes codebase context based on the overall size of the codebase. If the codebase isn't huge, the entire repo is loaded into context; but if it is huge, the agent reads the overall directory tree and judiciously includes a subset of the repo. (Note that it always reads markdown files, dependency files, packaging files, etc.)
- Interactive Suggestions: Formats code recommendations inside native GitHub
```suggestionblocks for one-click merge applications. - Triggers: The action triggers automatically in response to PR events. It can also be triggered by posting a comment in the PR starting with
/gemini-review. - Fast-Execution Composite Action: Avoids containerisation build/pull latency (no slow
docker buildon every execution) by running as a native composite action. - Cross-Platform Support: Runs natively on Linux, macOS, and Windows runners (both GitHub-hosted and self-hosted).
- Modern SDK Execution: Leverages the modern Google GenAI SDK (
google-genai). - Enterprise-Grade Security: Authentication via either Google Gemini API Keys or Google Cloud Workload Identity Federation (WIF).
- Customisable Prompts: Supports repository-specific overrides for both reviews and triaging via simple TOML config files.
- Reviewer Personas: Customise the personality, tone, and review style of the agent with pre-built persona overlays (
straight,dazbo,palpatine,rick). - Google Developer Knowledge Integration: Automatically queries official Google developer documentation (Google Cloud, Firebase, Android, etc.) via MCP to cross-reference your changes against up-to-date best practices.
- On-Demand Agent Skills: Dynamically discovers and loads project-specific formatting guidelines and coding standards from
.agents/skillson-demand, keeping prompt contexts lightweight and relevant (bundled with defaults for Google Cloud, Gemini APIs and agentic development). - Gemini Context Caching: Native, automatic integration with Gemini Context Caching, delivering up to 90% cost reduction on input tokens for repositories over 32k tokens.
- Multi-Turn & Cross-PR Cache Reuse: Reuses active server-side context cache handles across multi-turn tool/skill calls and successive PR pushes within the TTL window (1h default), eliminating prompt re-tokenisation and server overhead. This is a huge efficiency and cost saving between successive reviews.
Developed and maintained by Darren 'Dazbo' Lester (GitHub: @derailed-dash).
This project is licensed under the MIT License - see the LICENSE file for details.
- Change Discovery: The action scans the Pull Request diff. It uses a robust extension and path exclusion list to automatically filter out binary, encrypted, or locked files (like
.png,.enc,uv.lock,.env, etc.). - Hybrid Context Enrichment: In addition to surrounding modified file content, the action gathers context from the rest of the repository. It measures the total size of all other tracked text files:
- Full Context Mode: If the codebase is under the configured size threshold (default: 1.5 MB), the full contents of all other text files are included.
- Sparse Context Mode: If the codebase exceeds the threshold, it includes a structured text-based file tree of the entire project, plus the full contents of key configuration and documentation files (like
*.md,pyproject.toml,package.json,go.mod, etc.).
- Gemini Context Caching & Multi-Turn Reuse: For repository contexts exceeding ~32,768 tokens (100,000+ characters), the action automatically checks for an active server-side cache (
repo-cache-{repo}-{model}-{persona}) viaclient.caches.list(). This mechanism is completely stateless—no local databases or runner caches are needed between PR reviews, as active handles are looked up dynamically on Google's API servers. Caches are securely isolated to your API key tenant. Billed input tokens receive a 90% discount, and subsequent multi-turn tool/skill calls reference the cached context handle without re-billing the codebase context. - Structured Review Generation: The action sends the diff and file contexts to Gemini. It uses Gemini's native Structured Outputs (
response_schema) to force the model to respond in a strict JSON format. - Interactive suggestions: Change recommendations are wrapped in native GitHub
```suggestionblocks, allowing reviewers to apply the changes directly on the PR with one click. - Resilient Comment Posting: The review is posted atomically via the GitHub Pull Request Review API. If the API call fails (e.g. if the model hallucinates an invalid line number in the diff), the script catches the error and falls back to posting comments individually, ensuring your CI status check stays green while still delivering all valid feedback.
One key benefit of running code reviews via this CI/CD-based GitHub Action is the complete absence of session bias.
When interacting with a local AI assistant during development, the model is inevitably influenced by your ongoing conversation, intermediate code drafts, and the developmental history of your changes. While this conversational context is incredibly helpful for writing code, it can also bias the local assistant, causing it to accept compromises or overlook subtle regressions because it understands your intent so well.
This action acts as a stateless, independent reviewer with a clean slate. It has no knowledge of how you arrived at the solution or what you discussed locally. By reviewing the raw pull request diff against the repository context, it is far more likely to identify gaps, edge cases, and safety issues that your local assistant might have missed or forgiven.
This one-time setup (per repo) is required to allow the action to authenticate to Google Gemini.
By default, this action uses a repository secret called gemini_api_key. You can create this key, for example, in Google AI Studio.
Add this variable to your repo:
- Navigate to Settings > Secrets and variables > Actions.
- Click New repository secret.
- Name the secret
GEMINI_API_KEYand paste your API key as the value. - Reference it in your workflow file as
${{ secrets.GEMINI_API_KEY }}.
Note
The secrets.GITHUB_TOKEN is automatically created and populated by GitHub for every workflow run. You do not need to add it to your repository secrets manually. You only need to ensure the correct permissions are defined in the workflow file, as shown in the examples.
If you prefer to authenticate using a combination of Google Cloud Workload Identity Federation (WIF) and Application Default Credentials (ADC) with Gemini Enterprise Agent Platform (formerly known as Vertex AI), you can omit gemini_api_key. This allows the action to authenticate securely with Google Cloud without storing a long-lived service account key JSON file in your repository.
Alternatively, we can use WIF and ADC to authenticate. In this approach, we do not use persistent Gemini API key. This will be shown later.
This action natively supports the Google Developer Knowledge MCP API. If available under your GEMINI_API_KEY (or Google Cloud Application Default Credentials), the PR reviewer agent can dynamically query official, up-to-date documentation for services like Google Cloud, Firebase, and Android to ensure your code follows best practices.
To enable this capability, see Google Developer Knowledge Setup Guide.
This action supports On-Demand Skills Discovery. Instead of cramming all your repository's formatting rules, coding guidelines, and API specs directly into the prompt context (which wastes tokens and confuses the model), the reviewer agent queries a list of available guidelines and loads the relevant instructions dynamically as needed.
The action comes pre-packaged with a comprehensive set of default skills that are automatically available for every run. These cover:
- Google Enterprise & Agent Development: Best practices for Google ADK (Agent Development Kit), Gemini Agents API, serving endpoint management, prompt orchestration, and model tuning.
- Google Cloud Best Practices: Official architecture patterns, operational excellence, reliability, performance, security, and GCS/Cloud Run/GKE setup.
- Data Analytics: BigQuery query optimization, BigFrames, property graphs, and time-series forecasting.
To add project-specific coding standards or team rules that your PR reviewer should check against:
- Create a folder named
.agents/skills/at the root of your repository. - Add a subdirectory for your skill, and create a
SKILL.mdfile inside it (e.g..agents/skills/my-react-rules/SKILL.md). - Format the file with a YAML frontmatter header containing its name and description:
--- name: "My Project Style Guide" description: "Rules for component structure, CSS modules, and custom hooks" --- # Instructions Write your detailed rules here...
- Commit and push these files. The PR review agent will automatically detect your project's custom guidelines and invoke them when reviewing relevant code changes.
When reviewing pull requests that have undergone multiple iterations or team discussions, Gemini automatically retrieves prior inline review threads (pulls/{pr_number}/comments) and general PR conversation comments (issues/{pr_number}/comments) using automatic pagination loops.
-
Thread Grouping: Root review comments and developer replies are structured into conversational threads mapped to specific files and line numbers.
-
Developer Workflow Rules for Follow-Up Reviews: Gemini evaluates prior comment history against the incoming diff patch and enforces an opinionated developer workflow matrix:
- a) Addressed / Resolved: The developer applies the requested code fix. Gemini detects that the diff patch addresses the suggestion, omits the duplicate inline comment, and lists it under
### ✅ Resolved Items from Prior Reviews. - b) Deferred: The developer defers the work (e.g. by linking a follow-up issue or noting it in comments). Gemini respects the deferral and refrains from repeating the suggestion.
- c) Disagreed / Ignored with Explanation: The developer responds explaining why the suggested change was not made (e.g. architectural design choice or performance trade-off). Gemini respects the explanation and refrains from repeating the critique.
[!IMPORTANT] No Silent Drops: A PR suggestion is never ignored without justification. If the code remains unchanged AND the developer has provided no explanation or reply, or if the developer agreed in comment threads but has not yet pushed the code fix, Gemini will default to re-flagging and restating the unresolved suggestion in the follow-up review.
- a) Addressed / Resolved: The developer applies the requested code fix. Gemini detects that the diff patch addresses the suggestion, omits the duplicate inline comment, and lists it under
-
Resolved Items Reporting: When Gemini identifies that previously raised feedback has been fixed in the latest push, it includes a dedicated section in the PR review summary:
### ✅ Resolved Items from Prior Reviews - Added exception handling in `src/main.py` (Line 45) - Standardised type annotations in `utils.py` (Line 12)
If you are using an agentic coding environment like Google Antigravity, you can install and configure this action and its triage workflow automatically using Dazbo's skill from derailed-dash/dazbo-agent-skills.
Important
Prerequisite: Regardless of whether you use the automatic skill setup or the manual setup, you must configure authentication (either a Gemini API Key or Workload Identity Federation) as described in the Authentication section above.
The install-gemini-code-review-action skill automatically handles:
- Detecting and removing conflicting legacy workflows (e.g.,
run-gemini-cliorgemini-code-assist). - Asking for your preferences (e.g., installing PR Review, Issue Triage, or both, plus your preferred language and model).
- Writing the workflow YAML files and default TOML prompt configurations.
- Commit and push of the new workflow files.
To install the skill locally, run:
npx skills add https://github.com/derailed-dash/dazbo-agent-skills -y -g --skill install-gemini-code-review-actionOnce installed, simply ask your agent:
"Install the Gemini code review action"
One-time step: add this GitHub Action to your repository, by copying the starter example workflow gemini-review.yml to .github/workflows/gemini-review.yml in your repo (or use the inline template below):
name: "🔎 Dazbo's Gemini Code Review"
on:
pull_request:
branches:
- main
# Optional: restrict trigger paths (supports inclusions & exclusions)
# paths:
# - 'src/**'
# - '!src/generated/**' # Exclude generated files
# - 'pyproject.toml'
issue_comment:
types: [created]
jobs:
review:
# Run on internal PR updates (same repo), OR on issue comment starting with /gemini-review by repo owners/members
if: |
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
(
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
startsWith(github.event.comment.body, '/gemini-review') &&
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)
)
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write
statuses: write
checks: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
# Automatically checks out the head ref for PR events,
# and pulls the PR head branch for comment-based triggers
ref: ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', github.event.issue.number) }}
- name: Run Gemini Review Action
uses: derailed-dash/gemini-review-action@v1
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
gemini_model: 'gemini-3.7-flash'
language: 'English (UK)' # Optional (e.g. English (UK), French, Spanish)
# persona: 'straight' # Optional: straight (default), dazbo, palpatine, rick
# timeout: '60' # Optional API timeout in seconds
# include_comment_history: 'true' # Optional: include prior PR comment history (default: true)
# skip_inline_suggestions: 'true' # Optional: skip re-reviews on commits created via GitHub UI inline fixes (default: true)After adding the workflow to your repository, it should look something like this:
The examples above use floating tags (@v1, @v6) because they are easier to read. For anything beyond a personal repo, pin to a full commit SHA instead:
- uses: derailed-dash/gemini-review-action@<40-char-sha> # v1.6.0This action's job holds pull-requests: write and, on the WIF path, id-token: write, and it runs against untrusted pull request head content. A tag is a movable reference, so a re-tagged release executes in that job without anyone reviewing the change. A SHA is not movable. The same applies to actions/checkout and google-github-actions/auth in the same job.
Dependabot understands SHA pins with a trailing version comment and will raise a PR when a new release lands, so you still get updates, just deliberately.
Not in the examples, but a natural addition to avoid paying for three reviews when someone pushes three times in a minute. Put it under the job, not at workflow level:
jobs:
review:
concurrency:
group: gemini-review-${{ github.event.pull_request.number || github.event.issue.number }}-${{ github.event_name }}
cancel-in-progress: trueWorkflow-level concurrency is evaluated when a run is queued, before any job if is evaluated. An issue_comment payload has no top-level pull_request, so a key like ${{ github.event.pull_request.number || github.event.issue.number }} falls through to the issue number, which for a pull request is the same number. Both trigger types then share one group.
The result is that any comment on the PR cancels a review that is still running, before the job gets to check whether the comment was a /gemini-review command at all. Keeping it at job level, and including github.event_name in the key, avoids both halves.
-
Create a PR in the repository:
-
Watch the workflow run. The action will automatically start a review process:
-
Once complete, you will see a review comment with recommendations:
By default, GitHub Actions will trigger the code review workflow on a pull_request event for changes to any files in the repository. You can restrict which files trigger the workflow by configuring paths or paths-ignore under the trigger configuration.
To only review files under certain directories or with specific file extensions, use the paths key:
on:
pull_request:
paths:
- 'src/**'
- 'tests/**'
- 'pyproject.toml'You can define exclusions in two ways:
-
Exclusions within inclusions (
!prefix): If you want to review a directory but exclude specific subdirectories or file types, prefix the pattern with!. Note that negative patterns must follow at least one positive pattern.on: pull_request: paths: - 'src/**' - '!src/generated/**' # Exclude generated files
-
Excluding paths globally (
paths-ignore): If you want to run the review for all files except for certain folders (like documentation or configurations), usepaths-ignore:on: pull_request: paths-ignore: - 'docs/**' - '**.md'
Note
Regardless of your workflow's paths trigger, the underlying Python script automatically filters out binary, locked, and encrypted files (such as .png, .enc, package-lock.json, and uv.lock) before sending the code context to Google Gemini.
If the workflow is configured to allow triggering via comments (e.g. with the issue_comment trigger as shown in the example above), you can trigger a code review manually at any time by posting a comment on the Pull Request:
- Simply comment
/gemini-reviewon the PR. - Security & Access Control: To prevent unauthorised runs and control costs, the action will only trigger if the commenter is an
OWNER,MEMBER, orCOLLABORATORof the repository.
Add this GitHub Action to your repository, by copying the starter example workflow gemini-triage.yml to .github/workflows/gemini-triage.yml in your repo (or use the inline template below):
name: "🏷️ Dazbo's Gemini Issue Triage"
on:
issues:
types: [opened, reopened]
jobs:
triage:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Run Gemini Triage Action
uses: derailed-dash/gemini-review-action@v1
with:
command: 'triage'
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
gemini_model: 'gemini-3.7-flash'
language: 'English (UK)' # Optional| Input | Description | Required | Default |
|---|---|---|---|
gemini_api_key |
Your Gemini Developer API Key (from Google AI Studio). | Yes (unless using WIF) | N/A |
github_token |
Repository GITHUB_TOKEN (automatically provided by GitHub; no manual secret creation required). |
Yes | N/A |
gemini_model |
The Gemini model version to target for code review and dynamic context selection. | No | gemini-3.7-flash |
command |
The mode/command to run: review (for PR reviews) or triage (for issue triaging). |
No | review |
include_comment_history |
Whether to fetch prior inline review threads and conversation comments from GitHub. | No | 'true' |
language |
The language to use for the review comments (e.g. English (UK), English (US), French, Spanish). |
No | English (UK) |
persona |
Reviewer persona overlay (straight, dazbo, palpatine, rick). |
No | straight |
skip_inline_suggestions |
Whether to skip automated re-reviews when a commit is created by accepting an inline suggestion via GitHub UI. | No | 'true' |
timeout |
Timeout for API requests in seconds. | No | 60 |
By default, the action uses an intelligent hybrid context engine to feed relevant repository context to the model during review:
- max_context_bytes (Default:
1500000/ 1.5 MB): The total size of all other text files in the repository. At ~375,000 tokens, 1.5 MB safely fits within Gemini's 1M+ token window while leaving plenty of headroom for the PR diff/patch and structured reviews. If the repository is smaller than this limit, the action runs in Full Context Mode and includes all files. If the repository exceeds this limit, it switches to Sparse Context Mode. - max_core_context_bytes (Default:
500000/ 500 KB): In Sparse Context Mode, limits the maximum cumulative size of static core documentation and manifest files attached to the prompt. Any core files beyond this budget are deferred to Dynamic Context Selection. - Dynamic Context Selection: In Sparse Context Mode, the action uses the configured Gemini model (e.g.
gemini-3.7-flash) to evaluate modified files/diffs against a 4-tier architectural prioritization framework and select up to 8 of the most relevant candidate repository files (such as imported modules, sister classes, shared utilities, domain/algorithmic precedents, or tests) to attach directly into the review prompt alongside the file tree. - core_file_patterns: A list of glob patterns matching project manifests, build definitions, root documentation, templates, and shared utilities (e.g.
README*,CONTRIBUTING*,ARCHITECTURE*,DESIGN*,SPEC*,DEPLOYMENT*,INSTALL*,PRODUCT*,SDD*,TDD*,TODO*,GEMINI.md,*template*,*shared*,*util*,*common*,*core*,pyproject.toml,package.json) that are prioritized in Sparse Context Mode.
You can configure these settings by adding the following keys to your custom .github/commands/gemini-review.toml configuration (or via GEMINI_MAX_CONTEXT_BYTES and GEMINI_MAX_CORE_CONTEXT_BYTES):
# Codebase Context Configuration (Optional)
max_context_bytes = 1500000 # Threshold in bytes to trigger Sparse Mode (default 1.5 MB)
max_core_context_bytes = 500000 # Max bytes for static core docs/manifests/utils in Sparse Mode (default 500 KB)
core_file_patterns = [
"README*", "CONTRIBUTING*", "ARCHITECTURE*", "DESIGN*", "SPEC*", "DEPLOYMENT*", "INSTALL*", "PRODUCT*", "SDD*", "TDD*", "TODO*", "GEMINI.md",
"*template*", "*shared*", "*util*", "*common*", "*core*",
"pyproject.toml", "package.json", "go.mod", "Cargo.toml", "pom.xml", "build.gradle"
]You can customise the personality and feedback style of the reviewer agent using the persona action input in your workflow YAML file (e.g. .github/workflows/gemini-review.yml).
Available personas:
straight(Default): Standard, objective code reviewer with no persona overlay applied.dazbo: Warm, approachable software engineer tone with clear technical explanations and mild cheekiness. If recommendations from previous review iterations are unaddressed or ignored without explanation, it exhibits increasing levels of dry humor, sarcasm, and mild exasperation!palpatine: Emperor Palpatine (Star Wars) persona with grand imperial authority, dark side quotes ("Do it.", "Unlimited power!", "I find your lack of compliance disturbing"), demanding ruthless code perfectionism.rick: Rick Sanchez (Rick and Morty) persona — hyper-intelligent, cynical multiverse genius ("burp", "Wubba Lubba Dub-Dub!", "Jerry-tier code"). Demands galaxy-brain engineering perfection and treats sloppy bugs as pathetic Jerry-level amateur work!
Example Output (Emperor Palpatine Persona):
Example Output (Rick Sanchez Persona):
Configuring via workflow file (gemini-review.yml):
- uses: derailed-dash/gemini-review-action@v1
with:
gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
persona: 'rick' # Options: straight (default), dazbo, palpatine, rickThis action bundles high-quality default prompt configurations for both review and triage:
- Default Review Prompt: starter-examples/gemini-review.toml
- Default Triage Prompt: starter-examples/gemini-triage.toml
You can customize or completely override the prompt instructions given to the review or triage reviewers on a repository-by-repository basis:
- To override the Code Review prompt: Create a file at
.github/commands/gemini-review.tomlin your calling repository. - To override the Issue Triage prompt: Create a file at
.github/commands/gemini-triage.tomlin your calling repository.
Note
Parameter Configuration Scope: All operational configuration parameters (such as skip_inline_suggestions, include_comment_history, persona, language, timeout) MUST be configured via Action inputs in your workflow .yml file. The gemini-review.toml file is strictly reserved for prompt text templates and custom prompt overrides.
Your custom TOML file must contain a prompt key enclosing your system instructions in markdown format:
description = "Reviews a pull request with Gemini"
prompt = """
## Role
You are a world-class code review assistant.
## Primary Directive
Review the diff and full file contents to identify performance, security, and logic bugs.
## Rules
- Focus comments strictly on lines added or modified (lines starting with `+` or `-`).
- Use English (UK) spelling for all review feedback text.
- Do not make comments on formatting unless it is an egregious style guide violation.
- **GitHub Repository**: !{echo $REPOSITORY}
- **Pull Request Number**: !{echo $PULL_REQUEST_NUMBER}
"""The action parses the TOML files and dynamically substitutes the following expressions:
-
Code Review placeholders:
!{echo $REPOSITORY}: Replaced with the current repository name (e.g.derailed-dash/my-repo).!{echo $PULL_REQUEST_NUMBER}: Replaced with the number of the Pull Request being triaged.!{echo $ADDITIONAL_CONTEXT}: Replaced with empty space or triggering comment arguments.
-
Issue Triage placeholders:
!{echo $AVAILABLE_LABELS}: Replaced with a comma-separated list of available labels.!{echo $ISSUE_TITLE}: Replaced with the title of the issue.!{echo $ISSUE_BODY}: Replaced with the body text of the issue.!{echo $GITHUB_ENV}: Replaced with the file path to append output environment variables.
Whenever a review run finishes, the action provides token telemetry in two places:
-
Pull Request Review Output: A collapsible
<details>section appended directly to the bottom of the posted PR review comment on GitHub:📊 Token Usage & Cost Efficiency
Metric Value Input Tokens (uncached) 14,414 Input Tokens (cached) 250,985 (⚡ 94.4% cached) PR Comments History Tokens 450 Output Tokens 210 Total Session Tokens 267,701 Cost (uncached input) $0.0111 Cost (cached input) $0.0188 Cost (output) $0.0008 Estimated Total Cost $0.0307 Gemini 3.7 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31. Context-cache STORAGE is billed per token-hour and is not reported here, so the figure runs slightly low on repositories reviewed infrequently.
-
Workflow Execution Logs: A concise single-line token summary log printed to the runner
stderr:
Token Usage: 14,414 input tokens (94.4% cached), 210 output tokens. Total: 267,701 tokens. Estimated cost: $0.0307.
- Total Input (Prompt) Tokens: The total size (in LLM tokens) of the context sent to Gemini (full repository codebase files, system instructions, PR comment history, and PR diff patch).
- Cached Context Tokens (
├── Cached Context Tokens): The portion of input tokens stored in Gemini's server-side context cache. Context caching applies exclusively to input tokens, providing an automatic 90% rate discount on cached input tokens. - PR Comments History Tokens (
├── PR Comments History Tokens): The exact token count consumed by historical inline review threads and conversation comments fetched via the GitHub API and included in the dynamic review context. - Un-cached Fresh Tokens (
└── Un-cached Fresh Tokens): The newly introduced PR diff lines and dynamic skill instructions, billed at standard input rates. - Output (Candidates) Tokens: The number of tokens generated by Gemini in its structured review response JSON. Context caching does not apply to output tokens, which are billed at standard model output rates.
- Total Session Tokens: The combined total of prompt and output tokens processed during the review.
- Estimated Total Cost: The token counts above priced at the model's published rate. A model with no entry in the rate table reports tokens and no cost rather than borrowing another model's rate, because a missing number is obvious and a wrong one is not. Where a model has a time-boxed introductory rate, the end date is part of the table, so the figure stays correct on both sides of it and a note says which rate was applied.
- Cost caveats: Rendered as quoted lines under the table rather than left to documentation — the introductory-rate note, and the fact that context-cache storage (billed per token-hour) is not counted, so the estimate runs slightly low.
- Trigger: A developer opens or pushes an update to a Pull Request, or opens/reopens an Issue. GitHub Actions detects this webhook event and starts a runner to execute the review or triage action.
- Context Gathering:
- The action retrieves the Pull Request diff from the GitHub API.
- It performs exclusion filtering to automatically ignore non-text files and configured paths (like lock files or binaries).
- For all remaining modified files, it reads the full text from the local workspace filesystem to provide surrounding file context.
- Gemini AI Analysis: The action packs the diff, the full-file surrounding context, and the system prompt instructions (loaded from gemini-review.toml or gemini-triage.toml) into a payload and sends it to the Google Gemini API. The model performs in-depth analysis (assessing code quality, identifying bugs or improvements, and scanning for security concerns).
- Automated Feedback:
- The model generates a structured assessment guaranteed to follow the Pydantic schema constraints (such as ReviewResult).
- The action parses this structured response and automatically posts comments (including severity markers and interactive suggestions) or labels back to the GitHub PR or Issue.
- Resilience: If a PR comment contains a line range mismatch, the resilient handler falls back to publishing comments individually so that valid reviews are not lost and the workflow status stays green.
Gemini uses a strict Pydantic schema to generate reviews. Every submitted review contains:
- 📋 Review Summary: A 2-3 sentence assessment of the pull request's overall objective and quality.
- 🔍 General Feedback: A bulleted list of high-level observations and positive highlights.
- 💬 Inline Comments: Line-specific comments containing:
- Severity icons:
🔴(Critical),🟠(High),🟡(Medium),🟢(Low). - Constructive explanation written in English (UK) spelling.
- Interactive code replacement suggestion blocks (optional).
- Severity icons:
All standard output (stdout) and error logs (stderr) produced by the action's execution (such as API call progress, validation warnings, or error details) are printed directly to the console.
You can view these logs by opening the specific workflow run in the Actions tab of your GitHub repository, selecting the active job (e.g. review or triage), and expanding the Run Script step.
Using Google Workload Identity Federation (WIF) and Application Default Credentials (ADC)
For this authentication approach, you must configure the following in your calling workflow:
- OIDC Permissions: Grant the workflow job
id-token: writepermission so GitHub can request OIDC credentials. - Authenticate Step: Run the
google-github-actions/authstep prior to running this action to exchange GitHub's OIDC token for Google Cloud credentials. - Environment Variables: Pass the required Google Cloud environment variables (
GOOGLE_GENAI_USE_VERTEXAI,GOOGLE_CLOUD_PROJECT, andGOOGLE_CLOUD_LOCATION) to the review action.
To keep your infrastructure details private, you should save the following as GitHub repository secrets:
GCP_SERVICE_ACCOUNT: The email address of your Google Cloud service account.WIF_POOL_ID: The ID of your Workload Identity Pool (e.g.my-pool).WIF_PROVIDER_ID: The ID of your Workload Identity Provider (e.g.my-provider).
Example workflow job configured to run the review action with WIF authentication:
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
id-token: write # Required for WIF OIDC token exchange
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha || format('refs/pull/{0}/head', github.event.issue.number) }}
- name: Authenticate to Google Cloud via WIF
uses: google-github-actions/auth@v2
with:
workload_identity_provider: 'projects/123456789012/locations/global/workloadIdentityPools/${{ secrets.WIF_POOL_ID }}/providers/${{ secrets.WIF_PROVIDER_ID }}'
service_account: '${{ secrets.GCP_SERVICE_ACCOUNT }}'
- name: Run Gemini Review Action
uses: derailed-dash/gemini-review-action@v1
env:
GOOGLE_GENAI_USE_VERTEXAI: "True"
GOOGLE_CLOUD_PROJECT: "my-project-id"
GOOGLE_CLOUD_LOCATION: "global" # Or your preferred model endpoint region
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
gemini_model: 'gemini-3.7-flash'Note
When GOOGLE_GENAI_USE_VERTEXAI is set to "True", the underlying google-genai SDK uses Application Default Credentials (ADC) to automatically locate and use the short-lived credentials configured on the runner by the google-github-actions/auth step.
Here is an overview of the directory tree and the purpose of each file:
.
├── .github/ # GitHub workflows (used for dogfooding our own action)
├── assets/ # Documentation assets (banners, images)
├── docs/ # Technical documentation and architecture guides
├── gemini_review/ # Modular review engine package
│ ├── __init__.py # Package exports & public API facade bindings
│ ├── config.py # Configuration loader and default settings
│ ├── developer_knowledge.py # Google Developer Knowledge API integration
│ ├── github.py # GitHub REST API interactions & review submission
│ ├── schemas.py # Pydantic schemas (InlineComment, ReviewResult)
│ ├── prompts.py # Prompt builders and system instruction loader
│ ├── skills.py # Workspace skill discovery & instruction loader
│ └── utils.py # File filtering, diff parsing, token counter & git utils
├── starter-examples/ # Starter workflow files and default prompt templates
├── tests/ # Unit tests
├── action.yml # GitHub Action definition (inputs, environment, and steps)
├── CONTRIBUTING.md # Collaboration guidelines for developers
├── gemini_issue_triage.py # Python script to triage and label incoming issues
├── gemini_pr_review.py # Entrypoint script for PR reviews (re-exports gemini_review APIs)
├── pyproject.toml # Python project config, dependencies
└── README.md # Project documentation, setup guide, and usage examples
Note
The .github/ folder in this repository contains the workflows we use to dogfood our own action on this project. If you are installing this action in your own repository, you do not need to care about or copy this folder; you only need to reference uses: derailed-dash/gemini-review-action in your own workflow files.
For a detailed guide on how the inner workings, prompt generations, and codebase parsing logic are implemented, see our Architecture & Code Walkthrough.
This project uses uv for python environment and dependency management. To configure your local environment and run the test suite:
-
Install Dependencies: Run
uv syncto create a virtual environment (.venv) and install all runtime and development packages.uv sync
-
Linting & Code Formatting: We enforce strict syntax, formatting, and spelling checks using
ruffandcodespell. Run these from the project root:uvx codespell@latest -s uvx ruff@latest check --fix . -
Running the Unit Tests: Run the unit test suite with
pytest:uv run pytest
GitHub Actions are versioned by Git tags. When other repositories consume this action, they reference a specific tag (e.g. uses: derailed-dash/gemini-review-action@v1). To release new changes so that they are picked up by consuming repositories, you need to publish a release and update the major version tag.
Follow this step-by-step workflow:
Update the version number in pyproject.toml to reflect the new release (e.g. 1.3.1). Then, synchronise your lockfile to match the updated version:
# After modifying pyproject.toml
uv syncEnsure all your local tests pass successfully, then commit and push your changes to the main branch:
git add pyproject.toml uv.lock
git commit -m "chore(release): bump version to v1.3.1"
git push origin mainTo let users lock to specific versions (like v1.3.1) while still allowing others to automatically receive updates via the major version tag (v1), create or move these tags on your local machine and push them:
- Create the minor/patch tag (e.g.
v1.3.1):git tag -fa v1.3.1 -m "Release version v1.3.1" - Move the major version tag (
v1) to point to this new release:git tag -fa v1 -m "Update v1 tag to point to v1.3.1" - Push the tags to GitHub (you must use the
--forceflag to update the existingv1tag on the remote server):git push origin v1.3.1 git push origin v1 --force
To make the new version officially available, update the changelog, and ensure it is visible on the GitHub Marketplace:
- Open the repository on GitHub.
- In the right-hand sidebar, locate the Releases section and click Draft a new release (or click the gear icon and select Create a release).
- Click the Choose a tag dropdown:
- Type in the version you just pushed (e.g.
v1.3.1). - Select it from the dropdown.
- Type in the version you just pushed (e.g.
- Under Release title, enter a title for the version (e.g.
v1.3.1 - MCP and Workspace Skills Integration). - Publish to the Marketplace:
- Tick the checkbox next to Publish this Action to the GitHub Marketplace.
- If this is your first time publishing this action: Accept the GitHub Developer Agreement, select a primary category (e.g.
Code qualityorUtilities), and customise the colour and icon for the marketplace listing card.
- Write a summary of changes in the description box, or click Generate release notes to automatically construct them from your commit logs.
- Click Publish release.
Here is a full example of checking tag status, bumping the version, pushing tags, and ensuring the Marketplace listing is updated:
-
Check current tag status: Find the closest tag and see how many commits the branch is ahead by:
git describe --tags # Example output: v1.4.4-3-g1223a88 (3 commits ahead of v1.4.4) -
Bump the version in pyproject.toml and synchronise the lockfile: Ensure the version is set to
1.4.5inpyproject.toml, then run:uv lock git commit -am "chore(release): bump version to v1.4.5" git push origin main -
Create the patch tag and update the floating major version tag locally:
git tag -fa v1.4.5 -m "Release v1.4.5: Line Range Accuracy, Re-Review Suppression & Input Parameter Standards" git tag -fa v1 -m "Release v1"
-
Push tags to remote (using
--forceto update the existingv1tag on GitHub):git push origin v1.4.5 --force git push origin v1 --force
-
Publish & Sync to GitHub Marketplace:
- Option A (GitHub Web UI): Go to Releases > Draft a new release (or edit
v1.4.5), ensure ☑️ Publish this Action to the GitHub Marketplace is checked, select category (Code review/Code quality), and click Publish release (or Update release). - Option B (GitHub CLI): Create the release via
gh release create:gh release create v1.4.5 -t "v1.4.5: Line Range Accuracy, Re-Review Suppression & Input Parameter Standards" -F release_notes.md
[!IMPORTANT] Marketplace Metadata Synchronization: Whenever metadata in
action.yml(such asname,description, or inputs) is modified, you MUST update/re-save the GitHub Release for the current tag. This forces GitHub Marketplace to re-readaction.ymland immediately update the listing title, keywords, and search index. - Option A (GitHub Web UI): Go to Releases > Draft a new release (or edit
This action is free and open-source. Although there is no license cost for using this mechanism in your repo, making use of Google Gemini models (like any AI models) is not necessarily zero cost. But it is indeed very cheap! See worked examples below.
- Billing Attribution: All API calls generated by this action are billed directly to the Google Cloud Project (or Google AI Studio account) associated with the
GEMINI_API_KEY(or the Google Cloud project specified when using Workload Identity Federation / ADC). No costs are billed through GitHub. - Token Breakdown: Costs are calculated strictly based on token consumption reported in the execution logs (
Gemini Token Usage):- Input Tokens (Prompt): Combines the system prompt instructions, PR diff/patch, and the repository file context (up to
max_context_bytes). - Output Tokens (Candidates): The structured JSON response containing the review summary, feedback, and line-specific suggestions.
- Input Tokens (Prompt): Combines the system prompt instructions, PR diff/patch, and the repository file context (up to
For a typical repository with 0.5 MB (~500 KB) of tracked text files running under Full Context Mode:
| Metric | Estimated Volume | Description |
|---|---|---|
| Input Tokens | ~130,000 – 140,000 tokens | ~125,000 tokens for 0.5 MB repo context + ~10,000 tokens for PR diff & system prompt. |
| Output Tokens | ~500 – 1,500 tokens | Structured JSON review summary & line recommendations. |
Rates for gemini-3.7-flash, which the action now applies for you and prints in the review:
- Input: $0.75 per 1,000,000 tokens (uncached) — introductory rate through 2026-12-31, then $1.50
- Output: $3.75 per 1,000,000 tokens — then $7.50
- Cached input: 0.1x the input rate
Calculated Cost Per PR Review (at today's introductory rate):
- Input Cost: 140,000 x ($0.75 / 1,000,000) = $0.105
- Output Cost: 1,500 x ($3.75 / 1,000,000) = $0.006
- Total Estimated Cost: ~$0.11 per PR review, doubling to ~$0.22 once the introductory rate lapses
Since most input tokens will be cached, the actual cost is typically far lower again — a real review of a ~4 MB repository in Sparse Context Mode with 85% cache hits came in at $0.02.
The telemetry block tells you what one review cost. Labels answer the other question: what have code reviews cost on this repository this month, from the billing data itself.
On Vertex, every request is tagged and the labels arrive in the Cloud Billing export, so cost becomes a group-by:
component = gemini-review-action
repo = owner_repo
(/ is not legal in a label value, so owner/repo is written owner_repo. Values are lowercased and restricted to [a-z0-9_-], max 63 characters.)
Add your own with the billing_labels input, merged over the defaults, or none to switch it off:
- uses: derailed-dash/gemini-review-action@v1
with:
billing_labels: 'team=platform,cost_centre=engineering'The pull request number is deliberately not a default label, because it would make every PR its own dimension in the billing export. Add it yourself if you want that granularity.
Note
This is a Vertex AI capability, not a choice made by this action. The Gemini Developer API's GenerateContentRequest has no labels field at all, and the SDK raises labels parameter is only supported in Gemini Enterprise Agent Platform mode rather than sending one. On the API-key path the field is simply omitted, so nothing breaks and nothing changes. To attribute cost there, the usual approach is a separate Cloud project per repository.
The table holds list price at the standard tier. If you are on batch/flex, priority, or a negotiated enterprise rate — or you are running a model the table does not list yet — set both of:
GEMINI_RATE_INPUTandGEMINI_RATE_OUTPUT(environment), orrate_inputandrate_outputin.github/commands/gemini-review.toml
Environment wins over the config file. Both are per 1,000,000 tokens. If either is missing or invalid, the built-in table is used instead.
For official, up-to-date pricing details across all Gemini model tiers and regions:










