Skip to content
Open
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
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,34 @@ jobs:
github-token: smoke-gh-token
zhipu-api-key: smoke-zhipu-token

- name: Prepare fake kimi binary
run: |
cp tests/fixtures/fake-kimi.sh /usr/local/bin/kimi
chmod +x /usr/local/bin/kimi

- name: Setup Kimi CLI via local action
uses: ./setup-kimi-cli
with:
cache: false
env:
FAKE_KIMI_VERSION: 1.0.0-smoke

- name: Run Kimi CLI via local action
uses: ./run-kimi-cli
with:
prompt: smoke kimi prompt
model: smoke-kimi-model
attempts: 1

- name: Run review with Kimi CLI
uses: ./review
with:
cli: kimi-cli
cache: false
attempts: 1
prompt: kimi review prompt
model: kimi-review-model

- name: Stop fake installer server
if: always()
run: |
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/test-kimi-cli.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Test Kimi CLI

on:
push:
branches: [feat/add-kimi-cli-support]

permissions:
contents: read

jobs:
smoke-kimi-cli:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Prepare fake kimi binary
run: |
cp tests/fixtures/fake-kimi.sh /usr/local/bin/kimi
chmod +x /usr/local/bin/kimi

- name: Setup Kimi CLI via local action
uses: ./setup-kimi-cli
with:
cache: false
env:
FAKE_KIMI_VERSION: 1.0.0-smoke

- name: Run Kimi CLI via local action
uses: ./run-kimi-cli
with:
prompt: smoke kimi prompt
model: smoke-kimi-model
attempts: 1

- name: Run review with Kimi CLI
uses: ./review
with:
cli: kimi-cli
cache: false
attempts: 1
prompt: kimi review prompt
model: kimi-review-model

- name: Run feature-missing with Kimi CLI
uses: ./feature-missing
with:
cli: kimi-cli
cache: false
attempts: 1
prompt: kimi feature prompt
model: kimi-feature-model

- name: Run spec-coverage with Kimi CLI
uses: ./spec-coverage
with:
cli: kimi-cli
cache: false
attempts: 1
prompt: kimi spec prompt
model: kimi-spec-model
36 changes: 33 additions & 3 deletions feature-missing/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ name: OpenCode Feature Missing
description: Compares PR implementation against the linked issue spec to find missing or incomplete features before merge.

inputs:
cli:
description: CLI tool to use. Allowed values are opencode, kimi-cli.
required: false
default: opencode
install-url:
description: Installer URL used to bootstrap OpenCode.
required: false
Expand Down Expand Up @@ -164,6 +168,7 @@ runs:
exit 1

- id: paths
if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
INPUT_INSTALL_DIR: ${{ inputs.install-dir }}
Expand All @@ -185,6 +190,7 @@ runs:
printf 'xdg_cache_home=%s\n' "$xdg_cache_home" >>"$GITHUB_OUTPUT"

- id: key
if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
INPUT_INSTALL_URL: ${{ inputs.install-url }}
Expand All @@ -194,6 +200,7 @@ runs:
printf 'install_url_hash=%s\n' "$install_url_hash" >>"$GITHUB_OUTPUT"

- id: version
if: ${{ inputs.cli == 'opencode' }}
shell: bash
run: |
set -euo pipefail
Expand All @@ -215,15 +222,16 @@ runs:
printf 'version=%s\n' "$effective" >>"$GITHUB_OUTPUT"

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

- shell: bash
- if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
OPENCODE_INSTALL_DIR: ${{ steps.paths.outputs.install_dir }}
XDG_CACHE_HOME: ${{ steps.paths.outputs.xdg_cache_home }}
Expand All @@ -233,7 +241,8 @@ runs:
OPENCODE_MIN_VERSION: ${{ steps.version.outputs.version }}
run: ${{ github.action_path }}/../setup-opencode/install-opencode.sh

- shell: bash
- if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
GITHUB_RUN_OPENCODE_WORKING_DIRECTORY: ${{ inputs.working-directory }}
GITHUB_RUN_OPENCODE_ATTEMPTS: ${{ inputs.attempts }}
Expand Down Expand Up @@ -261,3 +270,24 @@ runs:
exit 1
fi
python3 ${{ github.action_path }}/../github-run-opencode/run-github-opencode.py

- if: ${{ inputs.cli == 'kimi-cli' }}
id: setup-kimi
uses: ./setup-kimi-cli
with:
cache: ${{ inputs.cache }}
cache-key: ${{ inputs.cache-key }}

- if: ${{ inputs.cli == 'kimi-cli' }}
uses: ./run-kimi-cli
with:
prompt: ${{ inputs.prompt }}
model: ${{ inputs.model }}
working-directory: ${{ inputs.working-directory }}
attempts: ${{ inputs.attempts }}
retry-profile: ${{ inputs.retry-profile }}
retry-on-regex: ${{ inputs.retry-on-regex }}
retry-delay-seconds: ${{ inputs.retry-delay-seconds }}
timeout-seconds: ${{ inputs.timeout-seconds }}
kimi-cli-path: ${{ steps.setup-kimi.outputs.kimi-cli-path }}
extra-env: ${{ inputs.extra-env }}
36 changes: 33 additions & 3 deletions review/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ name: OpenCode Review
description: Opinionated review wrapper with built-in defaults for `opencode github run`.

inputs:
cli:
description: CLI tool to use. Allowed values are opencode, kimi-cli.
required: false
default: opencode
install-url:
description: Installer URL used to bootstrap OpenCode.
required: false
Expand Down Expand Up @@ -155,6 +159,7 @@ runs:
exit 1

- id: version
if: ${{ inputs.cli == 'opencode' }}
shell: bash
run: |
set -euo pipefail
Expand All @@ -176,6 +181,7 @@ runs:
printf 'version=%s\n' "$effective" >>"$GITHUB_OUTPUT"

- id: paths
if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
INPUT_INSTALL_DIR: ${{ inputs.install-dir }}
Expand All @@ -197,6 +203,7 @@ runs:
printf 'xdg_cache_home=%s\n' "$xdg_cache_home" >>"$GITHUB_OUTPUT"

- id: key
if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
INPUT_INSTALL_URL: ${{ inputs.install-url }}
Expand All @@ -206,15 +213,16 @@ runs:
printf 'install_url_hash=%s\n' "$install_url_hash" >>"$GITHUB_OUTPUT"

- id: cache
if: ${{ inputs.cache == 'true' }}
if: ${{ inputs.cli == 'opencode' && 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 }}-${{ steps.version.outputs.version }}-${{ inputs.cache-key }}

- shell: bash
- if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
OPENCODE_INSTALL_DIR: ${{ steps.paths.outputs.install_dir }}
XDG_CACHE_HOME: ${{ steps.paths.outputs.xdg_cache_home }}
Expand All @@ -224,7 +232,8 @@ runs:
OPENCODE_MIN_VERSION: ${{ steps.version.outputs.version }}
run: ${{ github.action_path }}/../setup-opencode/install-opencode.sh

- shell: bash
- if: ${{ inputs.cli == 'opencode' }}
shell: bash
env:
GITHUB_RUN_OPENCODE_WORKING_DIRECTORY: ${{ inputs.working-directory }}
GITHUB_RUN_OPENCODE_ATTEMPTS: ${{ inputs.attempts }}
Expand Down Expand Up @@ -253,3 +262,24 @@ runs:
exit 1
fi
python3 ${{ github.action_path }}/../github-run-opencode/run-github-opencode.py

- if: ${{ inputs.cli == 'kimi-cli' }}
id: setup-kimi
uses: ./setup-kimi-cli
with:
cache: ${{ inputs.cache }}
cache-key: ${{ inputs.cache-key }}

- if: ${{ inputs.cli == 'kimi-cli' }}
uses: ./run-kimi-cli
with:
prompt: ${{ inputs.prompt }}
model: ${{ inputs.model }}
working-directory: ${{ inputs.working-directory }}
attempts: ${{ inputs.attempts }}
retry-profile: ${{ inputs.retry-profile }}
retry-on-regex: ${{ inputs.retry-on-regex }}
retry-delay-seconds: ${{ inputs.retry-delay-seconds }}
timeout-seconds: ${{ inputs.timeout-seconds }}
kimi-cli-path: ${{ steps.setup-kimi.outputs.kimi-cli-path }}
extra-env: ${{ inputs.extra-env }}
71 changes: 71 additions & 0 deletions run-kimi-cli/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Run Kimi CLI
description: Execute Kimi CLI with optional retry logic.

inputs:
prompt:
description: Prompt passed to the Kimi CLI agent.
required: false
default: ""
model:
description: Model passed to Kimi CLI via --model or KIMI_MODEL_NAME env.
required: false
default: ""
working-directory:
description: Optional working directory before running kimi.
required: false
default: ""
attempts:
description: Total number of attempts before failing.
required: false
default: "1"
retry-on-regex:
description: Retry only when stderr or stdout matches this regex.
required: false
default: ""
retry-profile:
description: Built-in retry profile, for example github-network.
required: false
default: ""
retry-delay-seconds:
description: Base delay between retries in seconds.
required: false
default: "15"
timeout-seconds:
description: Maximum execution time in seconds. Set 0 to disable.
required: false
default: "600"
kimi-cli-path:
description: Optional explicit path to the kimi binary.
required: false
default: kimi
extra-env:
description: >-
Extra environment variables to pass to kimi runtime.
Multi-line KEY=VALUE pairs, one per line. Empty lines and lines
starting with '#' are ignored.
required: false
default: ""

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

- shell: bash
run: |
export KIMI_PROMPT='${{ inputs.prompt }}'
export KIMI_MODEL='${{ inputs.model }}'
export KIMI_WORKING_DIRECTORY='${{ inputs.working-directory }}'
export KIMI_ATTEMPTS='${{ inputs.attempts }}'
export KIMI_RETRY_ON_REGEX='${{ inputs.retry-on-regex }}'
export KIMI_RETRY_PROFILE='${{ inputs.retry-profile }}'
export KIMI_RETRY_DELAY_SECONDS='${{ inputs.retry-delay-seconds }}'
export KIMI_TIMEOUT_SECONDS='${{ inputs.timeout-seconds }}'
export KIMI_BIN_PATH='${{ inputs.kimi-cli-path }}'
export KIMI_EXTRA_ENV='${{ inputs.extra-env }}'
${{ github.action_path }}/run-kimi-cli.sh
Loading