AI code review for your pull requests, run by OpenCode in your own GitHub Actions.
Every time someone opens or updates a pull request, OpenCode reads the change, follows it through your repo, and leaves one short comment with the defects the change introduces. A second pass tries to prove each finding wrong before you see it. The comment is edited on every push, never duplicated.
Here is a real one:
1. Add your model key as a secret. In your repo: Settings, Secrets and variables, Actions, New repository secret. Name it OPENROUTER_API_KEY. Get a key at openrouter.ai/keys.
2. Add this file as .github/workflows/opencode-review.yml:
name: OpenCode review
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
permissions: {}
concurrency:
group: >-
opencode-review-${{ github.event_name == 'pull_request'
&& format('pr-{0}', github.event.pull_request.number)
|| format('comment-{0}', github.event.comment.id) }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
opencode:
if: github.event_name == 'pull_request' || startsWith(github.event.comment.body, '/oc')
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
pull-requests: write
issues: write
steps:
- uses: aloki-alok/opencode-review@v0
with:
model: openrouter/deepseek/deepseek-v4.1-flash
api-key: ${{ secrets.OPENROUTER_API_KEY }}
That's it. Open a pull request and a review appears in a few minutes. :D
Two things to know:
/oc commands start working once this file is on your default branch. GitHub runs comment triggers from there only.aloki-alok/opencode-review@*.Want it smarter about your repo? Copy templates/guide.md to .github/opencode-review/guide.md and write a few lines about what the project is and the rules that matter. The reviewer reads it first. It also reads your AGENTS.md, both from the base branch, so a pull request can't rewrite the rules for its own review.
Comment on any issue or pull request:
| Comment | Does |
|---|---|
/oc why does this retry twice? | Answers in the thread with file:line references. On a pull request it reads the PR's code and diff. |
/oc review | Runs the review again and updates the review comment. |
Only repo owners, members and collaborators can use commands. Bots and pull requests from forks are ignored.
Time is sized to the change: 90 seconds up to 20 changed code lines, and 240 for anything bigger. If a pass runs out of time, OpenCode is stopped and asked for what it found so far, so work is not thrown away. A new push cancels the review of the old commit.
| Starts with | Means |
|---|---|
Changes needed: 2 things. :/ | Defects found and double-checked. Each names the file, the line and a fix. |
Nothing blocking found. :) | The review finished and found nothing worth blocking on. |
... Stopped at the time limit | It ran out of time but kept what it found. |
Review did not finish ... -_- | Out of time with nothing to show. Comment /oc review to retry. |
Review failed for ... :( | Something is set up wrong, like a dead API key. The reason says what. |
opencode.json and .opencode/ folder are removed before OpenCode starts.Full details in SECURITY.md.
All optional except model and api-key.
| Input | Default | What it does |
|---|---|---|
model | required | OpenCode model as provider/model. |
api-key | required | Key for the model's provider. |
guide-path | .github/opencode-review/guide.md | Repo guide, read from the base branch. |
max-findings | 5 | Most findings in one comment. |
review-budget | auto | Sized to the change, or turns:seconds. |
ask-budget | 16:240 | turns:seconds for an answer. |
allowed-associations | OWNER,MEMBER,COLLABORATOR | Who may use commands. |
opencode-path | Use an opencode already on the runner. |
Every input is in the README. To use another provider, change two lines:
with:
model: anthropic/claude-sonnet-5-5
api-key: ${{ secrets.ANTHROPIC_API_KEY }}
The action is free and MIT licensed. You pay your model provider for the tokens each review uses, and GitHub for runner minutes if your plan charges for them.
No. The model can only read files. It has no edit, shell or web tools, and the action only posts comments. It never approves or blocks a merge.
Any model OpenCode supports, set as provider/model. OpenRouter is the default, and Anthropic, OpenAI, Google and others work with their own key.
No. Fork pull requests are skipped so your model key never reaches code from outside your team.
Yes, for private repos. The runner needs python3 3.11 or later, git and npm. Give reviews their own label so they don't wait behind builds. On a public repo the action refuses to run on a self-hosted runner unless you opt in.
The repo ships a bench that replays real bug-introducing pull requests several times each and reports the catch rate, false alarms, timing and the spread between runs. 17 public cases from httpx, click and flask are included.
Found a wrong finding or a bug? Sign the guestbook (open an issue). ;)
Changes needed: 1 thing. :/
1. add() subtracts instead of adds (
app/calc.py:2). Restorereturn a + bOpenCode review of 48d310a98, advisory. Reply if a finding is wrong.