diff --git a/.github/scripts/install-opencode.sh b/.github/scripts/install-opencode.sh new file mode 100644 index 0000000..b0f514a --- /dev/null +++ b/.github/scripts/install-opencode.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash + +set -euo pipefail + +OPENCODE_BIN_DIR="${OPENCODE_INSTALL_DIR:-${RUNNER_TOOL_CACHE:-$HOME/.cache}/opencode/bin}" +OPENCODE_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}" +INSTALL_URL="${OPENCODE_INSTALL_URL:-https://opencode.ai/install}" +MAX_ATTEMPTS="${OPENCODE_INSTALL_ATTEMPTS:-3}" + +mkdir -p "$OPENCODE_BIN_DIR" +mkdir -p "$OPENCODE_CACHE_DIR" + +export OPENCODE_INSTALL_DIR="$OPENCODE_BIN_DIR" +export XDG_CACHE_HOME="$OPENCODE_CACHE_DIR" +export PATH="$OPENCODE_BIN_DIR:$PATH" + +link_opencode_bin() { + local source_bin="$1" + + if [ -x "$source_bin" ] && [ "$source_bin" != "$OPENCODE_BIN_DIR/opencode" ]; then + ln -sf "$source_bin" "$OPENCODE_BIN_DIR/opencode" + fi +} + +if command -v opencode >/dev/null 2>&1; then + echo "OpenCode already installed at: $(command -v opencode)" + opencode --version || true + exit 0 +fi + +attempt=1 +while [ "$attempt" -le "$MAX_ATTEMPTS" ]; do + echo "Installing OpenCode (attempt ${attempt}/${MAX_ATTEMPTS})" + + if curl \ + --fail \ + --silent \ + --show-error \ + --location \ + --retry 5 \ + --retry-all-errors \ + --retry-delay 2 \ + "$INSTALL_URL" | bash; then + break + fi + + if [ "$attempt" -eq "$MAX_ATTEMPTS" ]; then + echo "OpenCode installation failed after ${MAX_ATTEMPTS} attempts" >&2 + exit 1 + fi + + sleep $((attempt * 5)) + attempt=$((attempt + 1)) +done + +if [ ! -x "$OPENCODE_BIN_DIR/opencode" ] && [ -x "$HOME/.opencode/bin/opencode" ]; then + link_opencode_bin "$HOME/.opencode/bin/opencode" +fi + +if ! command -v opencode >/dev/null 2>&1; then + echo "OpenCode install script finished, but 'opencode' is still unavailable" >&2 + exit 1 +fi + +echo "OpenCode installed at: $(command -v opencode)" +opencode --version || true diff --git a/.github/workflows/opencode-review.yml b/.github/workflows/opencode-review.yml new file mode 100644 index 0000000..2419b77 --- /dev/null +++ b/.github/workflows/opencode-review.yml @@ -0,0 +1,52 @@ +name: OpenCode PR Review + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + review: + name: AI Code Review + if: github.event.pull_request.draft == false + runs-on: [self-hosted, builder] + permissions: + id-token: write + contents: read + pull-requests: write + issues: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: true + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Prepare OpenCode cache paths + run: | + echo "OPENCODE_INSTALL_DIR=${RUNNER_TOOL_CACHE:-$HOME/.cache}/opencode/bin" >> "$GITHUB_ENV" + echo "XDG_CACHE_HOME=${XDG_CACHE_HOME:-$HOME/.cache}" >> "$GITHUB_ENV" + echo "${RUNNER_TOOL_CACHE:-$HOME/.cache}/opencode/bin" >> "$GITHUB_PATH" + + - name: Install OpenCode if needed + shell: bash + run: bash ./.github/scripts/install-opencode.sh + + - name: Run OpenCode Review + env: + MODEL: zhipuai-coding-plan/glm-5 + 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. + USE_GITHUB_TOKEN: "true" + ZHIPU_API_KEY: ${{ secrets.ZHIPU_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: opencode github run