diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6300ee4..c62ecd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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') diff --git a/AGENTS.md b/AGENTS.md index 25a5c82..569676d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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. diff --git a/README.md b/README.md index ef31679..f941a6b 100644 --- a/README.md +++ b/README.md @@ -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 . 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 @@ -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 diff --git a/action.yml b/action.yml index c274c0f..442486f 100644 --- a/action.yml +++ b/action.yml @@ -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' 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: @@ -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://api.github.com/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://api.github.com/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 }}