GitHub Action

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

InputDefaultWhat it does
llm-api-key(required)Review-model key. Pass a GitHub Actions secret.
llm-modelgpt-6.1-solCodex model supplied through trusted review configuration.
claude-modelclaude-opus-5-5Claude model supplied through trusted review configuration; used when reviewer-command runs Claude Code.
llm-model-effortmediumReasoning 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-runtrueComplete the review without posting.
toneterseterse, 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-agentfalseBest-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

  1. Resolve the compatible Bubo version and install it from PyPI.
  2. Optionally install Codex on a hosted runner.
  3. 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.
  4. Initialize an ephemeral Bubo root below ${{ runner.temp }}.
  5. Write a configuration containing one GitHub repository and the triggering PR number as target_merge_request_iid.
  6. Validate the installation with bubo doctor.
  7. Run bubo-poller run-once and 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.

MountainOwlMountainOwl
Bubo · MIT licensed · © 2026