GitHub Action Experimental
Run Bubo on a pull request from GitHub Actions. The Action scopes discovery to the triggering PR, waits for the review to finish, and posts evidence-backed findings through the GitHub REST API. It runs on GitHub-hosted Linux and macOS runners or pre-provisioned self-hosted runners with Bash. The hardened reviewer requires a host that permits its filesystem sandbox: installing Bubblewrap alone is insufficient on Linux. Current ubuntu-latest CI rejected UID mapping; use a validated host without weakening its security policy. Credential-free Codex 0.154.0/Bubblewrap filesystem nesting passes CI on Ubuntu 22.04; authenticated Linux reviewer execution still needs validation. These requirements apply to the upcoming hardened runner, not retroactively to the released example tag.
Quick start
# .github/workflows/bubo.yml
name: Bubo review
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-22.04
steps:
- uses: mountainowl/bubo@v0.28.0
with:
llm-api-key: ${{ secrets.OPENAI_API_KEY }}
dry-run: "true"
install-agent: "true"
tone: "collaborative"Start with dry-run: "true". The review still runs to completion but does not
post comments. Inspect its transcript before changing the input to "false".
Use the latest Marketplace release if it is newer than the example tag.
Why run-once exists
bubo-poller service remains the only supported long-running scheduler. The
Action instead invokes bubo-poller run-once, which runs the configured PR
synchronously and returns a failure status when the review worker fails. This
keeps GitHub’s check alive until Bubo has actually finished.
When the Action is referenced by an exact semver tag, it installs the matching
Bubo PyPI version by default. This prevents an older Action from silently using
a newer incompatible CLI. Set bubo-version only when intentionally testing a
different release.
Inputs
| Input | Default | What it does |
|---|---|---|
llm-api-key | (required) | Review-model key. Pass a GitHub Actions secret. |
llm-model | gpt-6.1-sol | Codex model supplied through trusted review configuration. |
claude-model | claude-opus-5-5 | Claude model supplied through trusted review configuration; used when reviewer-command runs Claude Code. |
llm-model-effort | medium | Reasoning effort: low, medium, or high. |
llm-base-url | (unset) | Custom Responses-compatible endpoint. |
llm-api-key-env | (deprecated) | Legacy additional key environment variable. |
github-token | ${{ github.token }} | Reads the PR and posts comments; requires pull-requests: write. |
reviewer-command | (Codex) | Supported Codex or Claude command; arbitrary commands fail closed. |
dry-run | true | Complete the review without posting. |
tone | terse | terse, collaborative, socratic, formal, or casual. |
min-confidence | (Bubo default) | Discard findings below this value. |
max-findings | (Bubo default) | Maximum findings for this PR. |
bubo-version | (matching Action tag) | Explicit PyPI version override. Non-semver Action refs use latest. |
install-agent | false | Best-effort Codex installation. |
Self-hosted runners
Pre-provision the agent CLI, authentication, uv, and git, then leave install-agent: false. Repository data and the review
process remain on the runner; the configured model endpoint still receives the
model request.
Execution flow
- Resolve the compatible Bubo version and install it from PyPI.
- Optionally install Codex on a hosted runner.
- Restore Bubo’s anonymous analytics install id with
actions/cache, keyed by the repository ID, so a repository’s runs count as one install. The cached files hold only random IDs, and nothing about the repository is sent. - Initialize an ephemeral Bubo root below
${{ runner.temp }}. - Write a configuration containing one GitHub repository and the triggering
PR number as
target_merge_request_iid. - Validate the installation with
bubo doctor. - Run
bubo-poller run-onceand wait for the review result.
Experimental. Validate with dry-run: "true" on a real pull request before
allowing comments. Do not use pull_request_target for untrusted fork code with
repository secrets. The review agent must be installed and authenticated on the
runner.