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
14 changes: 12 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,18 @@ jobs:
uses: dceoy/gh-actions-for-devops/.github/workflows/github-actions-lint-and-scan.yml@main # zizmor: ignore[unpinned-uses]
with:
search-path: .github/workflows
go-version: stable
python-version: 3.x
use-yamllint: false
yaml-lint:
if: >
github.event_name == 'push'
|| github.event_name == 'pull_request'
|| github.event_name == 'workflow_dispatch'
permissions:
contents: read
uses: dceoy/gh-actions-for-devops/.github/workflows/yaml-lint.yml@main # zizmor: ignore[unpinned-uses]
with:
search-path: .
yamllint-config-data: '{"extends": "relaxed", "rules": {"line-length": "disable"}}'
github-major-version-tag:
if: >
(github.event_name == 'release' && github.event.action == 'released')
Expand Down
22 changes: 8 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,30 @@

## Project Structure & Module Organization

This repository publishes a composite GitHub Action for running OpenCode from GitHub Actions. The main action definition is `action.yml`; keep all action inputs, environment mappings, and composite steps there. User-facing setup and examples live in `README.md`. CI and repository automation are under `.github/`, including `.github/workflows/ci.yml`, Dependabot, and Renovate configuration. Agent helper skills are stored under `.agents/skills/`. There is currently no application source tree or test fixture directory.
This repository publishes a composite GitHub Action for running OpenCode in GitHub Actions. The action contract, inputs, outputs, environment mappings, install steps, and `opencode github run` delegation live in `action.yml`. User-facing setup, examples, inputs, outputs, and secret requirements live in `README.md`. GitHub automation is under `.github/`, including `.github/workflows/ci.yml`, `.github/workflows/opencode.yml`, Dependabot, and Renovate configuration. Agent helper skills are under `.agents/skills/`. There is no application source tree, package manager project, or dedicated test fixture directory.

## Build, Test, and Development Commands

There is no package manager build step. Validate changes with the same checks used by CI:
There is no build step. Validate local changes with the repository QA script:

```bash
test -f action.yml
grep -q '^runs:' action.yml
grep -q 'using: composite' action.yml
grep -q 'opencode github run' action.yml
test -f README.md
grep -q 'dceoy/opencode-action@main' README.md
grep -q 'model:' README.md
.agents/skills/local-qa/scripts/qa.sh
```

For local end-to-end testing, reference this checkout from a temporary workflow or use the README example with `uses: dceoy/opencode-action@main` after pushing changes to a branch.
The script checks core action metadata and README examples, including the composite action declaration, `opencode github run`, and documented usage. For end-to-end testing, run the action from a temporary workflow or push a branch and reference it from a test repository workflow.

## Coding Style & Naming Conventions

Use YAML for action and workflow configuration with two-space indentation. Prefer clear, snake_case input names matching existing inputs such as `use_github_token` and `oidc_base_url`. Keep shell snippets compatible with `bash` and use strict mode in workflows where possible (`bash -euo pipefail`). Pin third-party actions by full commit SHA in workflows when practical, and annotate the intended version in a comment.
Use YAML with two-space indentation for action and workflow files. Keep action inputs in `snake_case`, matching existing names such as `use_github_token`, `oidc_base_url`, and `cache_hit`. Prefer explicit `bash -euo pipefail` shell declarations for composite steps. Keep third-party actions pinned by full commit SHA when practical, with a comment naming the intended upstream version.

## Testing Guidelines

Tests are metadata and documentation checks rather than unit tests. When changing `action.yml`, verify that required inputs, defaults, environment variables, and the `opencode github run` delegation remain documented in `README.md`. When editing workflows, ensure `.github/workflows/ci.yml` still passes the reusable GitHub Actions lint and scan workflow.
Treat metadata and documentation checks as the primary test suite. When changing `action.yml`, update `README.md` in the same change if inputs, outputs, defaults, permissions, or secrets change. Run the QA script before submitting. When editing workflows, verify `.github/workflows/ci.yml` still covers the relevant checks.

## Commit & Pull Request Guidelines

Recent commits use short, imperative, lowercase subjects, for example `add opencode github action`. Follow that style and keep each commit focused. Pull requests should explain the action behavior changed, list any input or documentation updates, and link related issues when applicable. Include workflow screenshots or run links when changing CI behavior.
Recent commits use short, focused, imperative subjects such as `improve action inputs and version handling`. Follow that style and keep each commit scoped to one behavior or documentation change. Pull requests should describe the action behavior changed, list any input or README updates, link related issues when available, and include workflow run links for CI or action-behavior changes.

## Security & Configuration Tips

Do not commit provider API keys or GitHub tokens. Document required secrets in `README.md` and pass them through workflow `env`. Keep the default token path explicit: `use_github_token: true` requires `GITHUB_TOKEN` and suitable workflow permissions.
Do not commit provider API keys, GitHub tokens, or generated credentials. Document required secrets in `README.md` and pass them through workflow `env`. If `use_github_token: true` is used, ensure the workflow grants the minimum required `GITHUB_TOKEN` permissions for the requested task.
75 changes: 34 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,77 @@
# opencode-action

OpenCode GitHub agent for GitHub Actions.
Enhanced GitHub Action to run OpenCode GitHub agent

This repository provides a composite GitHub Action based on the upstream OpenCode GitHub Action implementation at <https://github.com/anomalyco/opencode/tree/dev/github>. The action installs the latest OpenCode CLI, caches the binary, and delegates execution to:

```bash
opencode github run
```
[![CI](https://github.com/dceoy/opencode-action/actions/workflows/ci.yml/badge.svg)](https://github.com/dceoy/opencode-action/actions/workflows/ci.yml)

## Usage

Create `.github/workflows/opencode.yml` in the repository where you want OpenCode to respond to issue and pull request comments:
Create `.github/workflows/opencode.yml` in the repository where you want OpenCode to respond to issue and pull request comments.
By default, the action exchanges the workflow OIDC token for an OpenCode GitHub App token, so the workflow must grant `id-token: write`.

```yaml
name: opencode

---
name: OpenCode
on:
issue_comment:
types: [created]
types:
- created
pull_request_review_comment:
types: [created]

types:
- created
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
jobs:
opencode:
if: |
contains(github.event.comment.body, '/oc') ||
contains(github.event.comment.body, '/opencode')
if: contains(github.event.comment.body, '/oc') || contains(github.event.comment.body, '/opencode')
runs-on: ubuntu-latest
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v7
with:
fetch-depth: 1
persist-credentials: false

- name: Run OpenCode
uses: dceoy/opencode-action@main
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
model: anthropic/claude-sonnet-4-20250514
use_github_token: true
model: opencode-go/glm-5.2
```

Then comment `/opencode` or `/oc` on an issue, pull request, or pull request review comment.

## Inputs

| Input | Required | Default | Description |
| ------------------ | -------- | ------- | --------------------------------------------------------------------- |
| `model` | Yes | | Model to use, in `provider/model` format. |
| `agent` | No | | OpenCode primary agent to use. |
| `share` | No | | Share the OpenCode session. Defaults to true for public repositories. |
| `prompt` | No | | Custom prompt to override the default prompt. |
| `use_github_token` | No | `false` | Use `GITHUB_TOKEN` directly instead of OpenCode App token exchange. |
| `mentions` | No | | Comma-separated trigger phrases. Defaults to `/opencode,/oc`. |
| `variant` | No | | Provider-specific model variant, such as `high`, `max`, or `minimal`. |
| `oidc_base_url` | No | | Custom OIDC token exchange API base URL. |
| Input | Required | Default | Description |
| ------------------ | -------- | ------------------------- | ------------------------------------------------------------------------------------------------- |
| `model` | Yes | | Model to use, in `provider/model` format. |
| `agent` | No | `build` | OpenCode primary agent to use. Falls back to `default_agent` from config or `build` if not found. |
| `share` | No | `false` | Whether to share the OpenCode session. |
| `prompt` | No | | Custom prompt to override the default prompt. |
| `use_github_token` | No | `false` | Use `GITHUB_TOKEN` directly instead of OpenCode App token exchange. |
| `mentions` | No | `/opencode,/oc` | Comma-separated trigger phrases, matched case-insensitively. |
| `variant` | No | | Provider-specific model variant for reasoning effort, such as `high`, `max`, or `minimal`. |
| `oidc_base_url` | No | `https://api.opencode.ai` | Base URL for OIDC token exchange. Override only for a custom GitHub App installation. |
| `version` | No | `latest` | OpenCode version to install, such as `v1.2.3`; `latest` resolves the latest upstream release. |

## Outputs

| Output | Description |
| ------------------ | ----------------------------------------------- |
| `opencode_version` | OpenCode version resolved for the workflow run. |
| `cache_hit` | Whether the OpenCode binary cache was restored. |
| `opencode-version` | OpenCode version resolved for the workflow run. |
| `cache-hit` | Whether the OpenCode binary cache was restored. |

## Secrets

Set the API key required by the selected model provider, for example:

- `OPENCODE_API_KEY` for OpenCode models
- `OPENROUTER_API_KEY` for OpenRouter models
- `ANTHROPIC_API_KEY` for Anthropic models
- `OPENAI_API_KEY` for OpenAI models

Expand Down Expand Up @@ -105,7 +102,3 @@ Request a change on specific code lines from the pull request Files tab:
```text
/oc add error handling here
```

## License

AGPL-3.0
57 changes: 38 additions & 19 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,45 @@ branding:
color: orange
inputs:
model:
description: Model to use, in provider/model format
required: true
description: Model to use, in provider/model format
agent:
description: Agent to use. Must be a primary agent. Falls back to default_agent from config or build if not found.
required: false
description: Agent to use. Must be a primary agent. Falls back to default_agent from config or 'build' if not found.
default: build
share:
description: Share the OpenCode session. Defaults to true for public repositories.
required: false
description: Whether to share the opencode session
default: 'false'
Comment thread
dceoy marked this conversation as resolved.
prompt:
description: Custom prompt to override the default prompt
required: false
description: Custom prompt to override the default prompt
default: ''
use_github_token:
description: Use GITHUB_TOKEN directly instead of OpenCode App token exchange. When true, skips OIDC and uses the GITHUB_TOKEN env var.
required: false
default: false
description: Whether to use GITHUB_TOKEN directly instead of OpenCode App token exchange. When true, skips OIDC and uses the GITHUB_TOKEN env var.
default: 'false'
mentions:
description: Comma-separated list of trigger phrases, case-insensitive. Defaults to /opencode,/oc.
required: false
description: Comma-separated list of trigger phrases (case-insensitive)
default: /opencode,/oc
variant:
description: Model variant for provider-specific reasoning effort, for example high, max, or minimal.
required: false
description: Model variant for provider-specific reasoning effort (e.g., high, max, minimal)
default: ''
oidc_base_url:
description: Base URL for OIDC token exchange API. Only required when running a custom GitHub App install. Defaults to https://api.opencode.ai.
required: false
description: Base URL for OIDC token exchange API. Only required when running a custom GitHub App install.
default: https://api.opencode.ai
version:
required: false
description: OpenCode version to install (e.g., v1.2.3)
default: latest
outputs:
opencode_version:
opencode-version:
description: OpenCode version resolved for this run.
value: ${{ steps.version.outputs.version }}
cache_hit:
value: ${{ steps.version.outputs.opencode-version }}
cache-hit:
description: Whether the OpenCode binary cache was restored.
value: ${{ steps.cache.outputs.cache-hit }}
runs:
Expand All @@ -43,27 +53,36 @@ runs:
- name: Get OpenCode version
id: version
shell: bash -euo pipefail {0}
env:
INPUT_VERSION: ${{ inputs.version }}
run: |
VERSION=$(curl -sf https://github.com/ghapi/repos/anomalyco/opencode/releases/latest | grep -o '"tag_name": *"[^"]*"' | cut -d'"' -f4)
echo "version=${VERSION:-latest}" >> "${GITHUB_OUTPUT}"
if [[ "${INPUT_VERSION}" == "latest" ]]; then
OPENCODE_VERSION="$(curl -fsSL https://github.com/ghapi/repos/anomalyco/opencode/releases/latest | jq -r '.tag_name')"
else
OPENCODE_VERSION="${INPUT_VERSION}"
fi
echo "opencode-version=$(tr -d v <<< "${OPENCODE_VERSION}")" | tee -a "${GITHUB_OUTPUT}"
- name: Cache OpenCode
id: cache
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.opencode/bin
key: opencode-${{ runner.os }}-${{ runner.arch }}-${{ steps.version.outputs.version }}
key: opencode-${{ runner.os }}-${{ runner.arch }}-${{ steps.version.outputs.opencode-version }}
- name: Install OpenCode
if: steps.cache.outputs.cache-hit != 'true'
if: >
steps.cache.outputs.cache-hit != 'true'
shell: bash -euo pipefail {0}
env:
OPENCODE_VERSION: ${{ steps.version.outputs.opencode-version }}
run: >
curl -fsSL https://opencode.ai/install | bash
curl -fsSL https://opencode.ai/install | bash -s -- --version "${OPENCODE_VERSION}"
- name: Add OpenCode to PATH
shell: bash -euo pipefail {0}
run: >
echo "${HOME}/.opencode/bin" >> "${GITHUB_PATH}"
echo "${HOME}/.opencode/bin" | tee -a "${GITHUB_PATH}"
- name: Run OpenCode
shell: bash -euo pipefail {0}
id: run_opencode
shell: bash -euo pipefail {0}
env:
MODEL: ${{ inputs.model }}
AGENT: ${{ inputs.agent }}
Expand Down