ci: add opencode GitHub code review with Muse Spark model - #162
Conversation
- Auto-review non-draft PRs using opencode-go/muse-spark-1.2-contributor - On-demand runs via /oc or /opencode comments - Uses the runner GITHUB_TOKEN (use_github_token) so no GitHub App install is required; model API key comes from the OPENCODE_API_KEY secret
The anomalyco/opencode/github action requires GITHUB_TOKEN env when use_github_token: true, otherwise it fails with: 'GITHUB_TOKEN environment variable is not set.' GitHub Actions does not inject GITHUB_TOKEN into env automatically; it must be passed explicitly via secrets.GITHUB_TOKEN.
|
APIError: This model collects data used to improve its quality and requires explicit opt in: https://opencode.ai/workspace/wrk_01KF3S6SYD5YNMYQWYD6S6340A/go |
muse-spark-1.2-contributor requires training-data opt-in (DataPolicyError), conflicts with the no-training data privacy preference. deepseek-v4-flash is available on the same provider without opt-in.
|
APIError: The latest version of this model is only available hosted in China and requires explicit opt in: https://opencode.ai/workspace/wrk_01KF3S6SYD5YNMYQWYD6S6340A/go |
opencode-go/* models are China-hosted and require opt-in (RegionError). opencode/deepseek-v4-flash resolves via the zen gateway without opt-in.
|
APIError: Insufficient balance. Manage your billing here: https://opencode.ai/workspace/wrk_01KF3S6SYD5YNMYQWYD6S6340A/billing |
|
APIError: Insufficient balance. Manage your billing here: https://opencode.ai/workspace/wrk_01KF3S6SYD5YNMYQWYD6S6340A/billing |
opencode workspace has insufficient balance (CreditsError) and the China-hosted opencode-go models need opt-in. muse-spark-1.2-contributor-free is the free tier of the originally intended reviewer model.
Review:
|
opencode-review.yml is now a thin dispatcher that delegates to
opencode-review-reusable.yml (workflow_call), so any repo can reuse
the review logic via:
uses: vuon9/devtoolbox/.github/workflows/opencode-review-reusable.yml@main
secrets:
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
Reusable workflow defaults to free-tier model (no billing, no opt-in).
workflow_call inputs do not support multi-line default values (startup failure). Move the default review prompt to a job-level env var and pick it in a prepare step instead.
GITHUB_OUTPUT rejects multi-line values written as plain echo. Use the heredoc delimiter form (value<<PROMPT_EOF ... PROMPT_EOF) so the default multi-line review prompt passes through correctly.
GitHub rejects if: conditions on jobs that call reusable workflows (startup_failure even with if: true). Move the pr/comment gating into the reusable workflow's job-level if, selected via a mode input. Also fix multi-line prompt output: GITHUB_OUTPUT requires the heredoc delimiter form for multi-line values.
- Default model switched to opencode-go/hy3 per request (no billing) - Pin anomalyco/opencode/github@v1.18.20: @latest is not resolvable inside a reusable workflow and causes startup_failure - Remove temporary isolation test workflows
The anomalyco/opencode/github composite action cannot be resolved inside a reusable workflow (startup_failure regardless of @latest or pinned tag). Inline its exact steps (version lookup, cache, install, PATH, run) as plain shell steps so the reusable workflow parses and runs.
GitHub caches workflow definitions by file path. The opencode-review.yml path was cached with a broken definition (if-on-uses-job, composite action inside reusable), so every edit kept failing with startup_failure. New paths ai-code-review.yml + ai-code-review-reusable.yml parse fresh: - default model opencode-go/hy3 - mode input gates pr vs /oc on-demand inside the reusable job - opencode run inlined as shell steps (composite action not resolvable inside reusable workflows) - multi-line prompt via GITHUB_OUTPUT heredoc form
Root cause of repeated startup_failure: a permissions block inside a reusable workflow (workflow_call) job is rejected by GitHub Actions. Move permissions to the caller jobs (review-pr, on-demand); the reusable job now inherits them. Confirmed by isolation test: identical caller+reusable pair succeeds with permissions on caller, fails with permissions inside reusable.
|
I've read both workflow files. Note this is a rewrite of the earlier Review:
|
From the hy3 review on PR #162: - Fix on-demand gating: support both issue_comment and pull_request_review_comment event payload shapes, word-boundary /oc match, PR-only guard, author_association guard, exclude bot - Least privilege: drop unused id-token, issues: write -> read - Pin actions: checkout@v6.0.3, cache@v5.0.5 (match ci.yml)
- concurrency group per PR/event with cancel-in-progress: a new push cancels the previous run instead of stacking more runs/comments - timeout-minutes: 10 on the review job so a slow/hung model run fails fast instead of hanging ~50 minutes
|
I've reviewed the two workflow files. Here is my structured review. Code Review:
|
Minimum allowed line rate is |



Summary
opencode-go/muse-spark-1.2-contributor(Muse Spark via OpenCode Go)/ocor/opencodeon any PR/issueGITHUB_TOKEN(use_github_token: true), so no GitHub App install is requiredOPENCODE_API_KEYrepo secret (already set)Notes
workflowOAuth scopeTest Plan
OPENCODE_API_KEYsecret set on repo (value from local opencode auth, not exposed)N/A