Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
shellcheck tests/setup-opencode.sh
shellcheck tests/run-opencode.sh
shellcheck tests/github-run-opencode.sh
shellcheck tests/review-action.sh
shellcheck tests/test.sh
shellcheck tests/fixtures/fake-installer.sh

Expand Down Expand Up @@ -72,6 +73,16 @@ jobs:
github-token: smoke-gh-token
zhipu-api-key: smoke-zhipu-token

- name: Run review convenience action
uses: ./review
with:
install-url: http://127.0.0.1:8765/fake-installer.sh
cache: false
install-attempts: 1
attempts: 1
github-token: smoke-gh-token
zhipu-api-key: smoke-zhipu-token

- name: Stop fake installer server
if: always()
run: |
Expand Down
19 changes: 13 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This repository is licensed under Apache 2.0.

## What it includes

- `review`: opinionated PR review wrapper with built-in prompt and model defaults
- `github-run-opencode`: one-step wrapper for the common `opencode github run` workflow
- `setup-opencode`: installs OpenCode, restores a dedicated cache, and exports the binary path
- `run-opencode`: runs `opencode` with optional retry logic for flaky GitHub network failures
Expand Down Expand Up @@ -37,6 +38,14 @@ Use this when you want the shortest consumer workflow for `opencode github run`.

`github-run-opencode` also accepts the setup-related inputs from `setup-opencode`, such as `cache`, `cache-key`, `install-attempts`, `install-url`, and `allow-preinstalled`.

## review

Use this when you want the simplest PR review setup.

- built-in `prompt` review template (same as `github-run-opencode`)
- built-in `model` default: `zhipuai-coding-plan/glm-5`
- still allows overriding any input when needed

## setup-opencode

### Inputs
Expand Down Expand Up @@ -85,18 +94,16 @@ In the common same-job case, `setup-opencode` already exports `opencode` to `PAT
Public consumers should reference the subdirectory action path:

```yaml
uses: Svtter/opencode-actions/review@v1
uses: Svtter/opencode-actions/github-run-opencode@v1
uses: Svtter/opencode-actions/setup-opencode@v1
uses: Svtter/opencode-actions/run-opencode@v1
```

```yaml
- name: Run OpenCode review
uses: Svtter/opencode-actions/github-run-opencode@v1
uses: Svtter/opencode-actions/review@v1
with:
model: zhipuai-coding-plan/glm-5.1
prompt: |
Review this pull request (read-only mode, DO NOT modify any code):
github-token: ${{ secrets.GITHUB_TOKEN }}
zhipu-api-key: ${{ secrets.ZHIPU_API_KEY }}
opencode-go-api-key: ${{ secrets.OPENCODE_GO_API_KEY }}
Expand All @@ -122,7 +129,7 @@ This repository includes a CI workflow that:

- runs `shellcheck` on every bundled shell script
- runs the local shell-based regression suite
- smoke-tests all three actions through `uses: ./setup-opencode`, `uses: ./run-opencode`, and `uses: ./github-run-opencode`
- smoke-tests all four actions through `uses: ./setup-opencode`, `uses: ./run-opencode`, `uses: ./github-run-opencode`, and `uses: ./review`

## Release Policy

Expand All @@ -137,7 +144,7 @@ This repository includes a CI workflow that:
2. Verify `CI` passes on `main`.
3. Create a GitHub release with a semver tag such as `v1.0.0`.
4. Confirm the `Update Major Tag` workflow moved `v1` to that release.
5. Use `owner/repo/github-run-opencode@v1` for the shortest path, or `owner/repo/setup-opencode@v1` plus `owner/repo/run-opencode@v1` for more control.
5. Use `owner/repo/review@v1` for the simplest review setup, `owner/repo/github-run-opencode@v1` for generic `github run`, or `owner/repo/setup-opencode@v1` plus `owner/repo/run-opencode@v1` for more control.

The initial release-notes template lives at `docs/releases/v1.0.0.md`.

Expand Down
15 changes: 1 addition & 14 deletions examples/opencode-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,8 @@ jobs:
ref: ${{ github.event.pull_request.head.ref }}

- name: Run OpenCode review
uses: Svtter/opencode-actions/github-run-opencode@v1
uses: Svtter/opencode-actions/review@v1
with:
model: zhipuai-coding-plan/glm-5.1
prompt: |
Review this pull request (read-only mode, DO NOT modify any code):

Please check:
- Code quality issues
- Potential bugs or logic errors
- Code style consistency
- Security concerns
- Performance issues
- Suggest improvements

Please respond in Chinese. DO NOT modify any code, only provide review comments.
github-token: ${{ secrets.GITHUB_TOKEN }}
zhipu-api-key: ${{ secrets.ZHIPU_API_KEY }}
opencode-go-api-key: ${{ secrets.OPENCODE_GO_API_KEY }}
175 changes: 175 additions & 0 deletions review/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
name: OpenCode Review
description: Opinionated review wrapper with built-in defaults for `opencode github run`.

inputs:
install-url:
description: Installer URL used to bootstrap OpenCode.
required: false
default: https://opencode.ai/install
install-dir:
description: Directory where the opencode binary should be installed.
required: false
default: ""
xdg-cache-home:
description: Dedicated XDG cache directory for OpenCode.
required: false
default: ""
cache:
description: Cache the install and XDG cache directories with actions/cache.
required: false
default: "true"
cache-key:
description: Cache key suffix used to invalidate installer-based caches.
required: false
default: v1
install-attempts:
description: Number of installer retry attempts.
required: false
default: "3"
allow-preinstalled:
description: Reuse an existing opencode found on PATH instead of forcing installer bootstrap.
required: false
default: "false"
working-directory:
description: Optional working directory before running opencode.
required: false
default: ""
attempts:
description: Total number of attempts before failing.
required: false
default: "3"
retry-profile:
description: Built-in retry profile, defaults to github-network for common GitHub usage.
required: false
default: github-network
retry-on-regex:
description: Retry only when stderr or stdout matches this regex.
required: false
default: ""
retry-delay-seconds:
description: Base delay between retries in seconds.
required: false
default: "15"
model:
description: Value exported as MODEL before running `opencode github run`.
required: false
default: zhipuai-coding-plan/glm-5
prompt:
description: Value exported as PROMPT before running `opencode github run`.
required: false
default: |
Review this pull request (read-only mode, DO NOT modify any code):

Please check:
- Code quality issues
- Potential bugs or logic errors
- Code style consistency
- Security concerns
- Performance issues
- Suggest improvements

Please respond in Chinese. DO NOT modify any code, only provide review comments.
The first line of your response must be exactly one of:
- 可合并
- 有条件合并
- 不可合并

Decision rules:
- Use "可合并" only when there are no blocking issues.
- Use "有条件合并" when merge is acceptable only after specific issues are fixed.
- Use "不可合并" when there are blocking risks, correctness issues, or major concerns that should stop the merge.

Output format:
- First line: the decision only
- Then a short summary
- Then "阻塞项" listing required fixes for merge; if none, write "阻塞项:无"
- Then "建议项" listing non-blocking improvements; if none, write "建议项:无"
use-github-token:
description: Value exported as USE_GITHUB_TOKEN before running `opencode github run`.
required: false
default: "true"
github-token:
description: Value exported as GITHUB_TOKEN before running `opencode github run`.
required: false
default: ""
zhipu-api-key:
description: Value exported as ZHIPU_API_KEY before running `opencode github run`.
required: false
default: ""
opencode-go-api-key:
description: Value exported as OPENCODE_GO_API_KEY before running `opencode github run`.
required: false
default: ""

runs:
using: composite
steps:
- if: ${{ runner.os != 'Linux' }}
shell: bash
run: |
set -euo pipefail
printf 'review currently supports Linux runners only\n' >&2
exit 1

- id: paths
shell: bash
env:
INPUT_INSTALL_DIR: ${{ inputs.install-dir }}
INPUT_XDG_CACHE_HOME: ${{ inputs.xdg-cache-home }}
run: |
set -euo pipefail
install_dir="$INPUT_INSTALL_DIR"
xdg_cache_home="$INPUT_XDG_CACHE_HOME"

if [[ -z "$install_dir" ]]; then
install_dir="${RUNNER_TOOL_CACHE:-$HOME/.cache}/opencode/bin"
fi

if [[ -z "$xdg_cache_home" ]]; then
xdg_cache_home="${RUNNER_TOOL_CACHE:-$HOME/.cache}/opencode/cache"
fi

printf 'install_dir=%s\n' "$install_dir" >>"$GITHUB_OUTPUT"
printf 'xdg_cache_home=%s\n' "$xdg_cache_home" >>"$GITHUB_OUTPUT"

- id: key
shell: bash
env:
INPUT_INSTALL_URL: ${{ inputs.install-url }}
run: |
set -euo pipefail
install_url_hash="$(printf '%s' "$INPUT_INSTALL_URL" | sha256sum | cut -d' ' -f1)"
printf 'install_url_hash=%s\n' "$install_url_hash" >>"$GITHUB_OUTPUT"

- id: cache
if: ${{ inputs.cache == 'true' }}
uses: actions/cache@v5
with:
path: |
${{ steps.paths.outputs.install_dir }}
${{ steps.paths.outputs.xdg_cache_home }}
key: review-opencode-${{ runner.os }}-${{ runner.arch }}-${{ steps.key.outputs.install_url_hash }}-${{ inputs.cache-key }}

- shell: bash
env:
OPENCODE_INSTALL_DIR: ${{ steps.paths.outputs.install_dir }}
XDG_CACHE_HOME: ${{ steps.paths.outputs.xdg_cache_home }}
OPENCODE_INSTALL_URL: ${{ inputs.install-url }}
OPENCODE_INSTALL_ATTEMPTS: ${{ inputs.install-attempts }}
OPENCODE_ALLOW_PREINSTALLED: ${{ inputs.allow-preinstalled }}
run: ${{ github.action_path }}/../setup-opencode/install-opencode.sh

- shell: bash
env:
GITHUB_RUN_OPENCODE_WORKING_DIRECTORY: ${{ inputs.working-directory }}
GITHUB_RUN_OPENCODE_ATTEMPTS: ${{ inputs.attempts }}
GITHUB_RUN_OPENCODE_RETRY_PROFILE: ${{ inputs.retry-profile }}
GITHUB_RUN_OPENCODE_RETRY_ON_REGEX: ${{ inputs.retry-on-regex }}
GITHUB_RUN_OPENCODE_RETRY_DELAY_SECONDS: ${{ inputs.retry-delay-seconds }}
GITHUB_RUN_OPENCODE_MODEL: ${{ inputs.model }}
GITHUB_RUN_OPENCODE_PROMPT: ${{ inputs.prompt }}
GITHUB_RUN_OPENCODE_USE_GITHUB_TOKEN: ${{ inputs.use-github-token }}
GITHUB_RUN_OPENCODE_GITHUB_TOKEN: ${{ inputs.github-token }}
GITHUB_RUN_OPENCODE_ZHIPU_API_KEY: ${{ inputs.zhipu-api-key }}
GITHUB_RUN_OPENCODE_OPENCODE_GO_API_KEY: ${{ inputs.opencode-go-api-key }}
run: ${{ github.action_path }}/../github-run-opencode/run-github-opencode.sh
39 changes: 39 additions & 0 deletions tests/review-action.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/usr/bin/env bash

set -euo pipefail

repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

extract_prompt_default() {
local action_file="$1"
awk '
/^ prompt:$/ {in_prompt=1; next}
in_prompt && /^ default: \|$/ {in_default=1; next}
in_default {
if ($0 ~ /^ [a-zA-Z0-9_-]+:$/) {
exit
}
sub(/^ /, "")
print
}
' "$action_file"
}

github_run_prompt_file="$(mktemp)"
review_prompt_file="$(mktemp)"
trap 'rm -f "$github_run_prompt_file" "$review_prompt_file"' EXIT

extract_prompt_default "$repo_root/github-run-opencode/action.yml" >"$github_run_prompt_file"
extract_prompt_default "$repo_root/review/action.yml" >"$review_prompt_file"

if ! diff -u "$github_run_prompt_file" "$review_prompt_file" >/dev/null; then
printf 'review/action.yml prompt default must match github-run-opencode/action.yml\n' >&2
exit 1
fi

if ! grep -Eq '^ default: zhipuai-coding-plan/glm-5$' "$repo_root/review/action.yml"; then
printf 'review/action.yml model default is not zhipuai-coding-plan/glm-5\n' >&2
exit 1
fi

printf 'review action metadata test passed\n'
1 change: 1 addition & 0 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ set -euo pipefail
bash tests/setup-opencode.sh
bash tests/run-opencode.sh
bash tests/github-run-opencode.sh
bash tests/review-action.sh