diff options
Diffstat (limited to 'github')
| -rw-r--r-- | github/README.md | 133 | ||||
| -rw-r--r-- | github/action.yml | 29 | ||||
| -rwxr-xr-x | github/script/publish | 15 | ||||
| -rwxr-xr-x | github/script/release | 41 |
4 files changed, 218 insertions, 0 deletions
diff --git a/github/README.md b/github/README.md new file mode 100644 index 000000000..7e9a8906b --- /dev/null +++ b/github/README.md @@ -0,0 +1,133 @@ +# opencode GitHub Action + +A GitHub Action that integrates [opencode](https://opencode.ai) directly into your GitHub workflow. + +Start your comment with `hey opencode`, and opencode will take action via your GitHub Actions runner. + +## Features + +#### Triage and explain issues + +``` +hey opencode, explain this issue +``` + +#### Fix or implement issues - opencode will create a PR with the changes. + +``` +hi opencode, fix this +``` + +- Review PRs and make changes + +``` +Delete the attachment from S3 when the note is removed @opencode-agent +``` + +## Installation + +Run the following command in the terminal from your GitHub repo: + +``` +opencode github install +``` + +This will walk you through installing the GitHub app, configuring the workflow, and setting up secrets. + +### Manual Setup + +1. Install the GitHub app https://github.com/apps/opencode-agent. Make sure it is installed on the target repository. +2. Add the following workflow file to `.github/workflows/opencode.yml` in your repo. Set the appropriate `model` and required API keys in `env`. + +```yml +name: opencode + +on: + issue_comment: + types: [created] + +jobs: + opencode: + if: | + startsWith(github.event.comment.body, 'opencode') || + startsWith(github.event.comment.body, 'hi opencode') || + startsWith(github.event.comment.body, 'hey opencode') || + contains(github.event.comment.body, '@opencode-agent') + runs-on: ubuntu-latest + permissions: + id-token: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Run opencode + uses: sst/opencode/github@latest + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + with: + model: anthropic/claude-sonnet-4-20250514 +``` + +3. Store the API keys in secrets. In your organization or project **settings**, expand **Secrets and variables** on the left and select **Actions**. Add the required API keys. + +## Support + +This is an early release. If you encounter issues or have feedback, please create an issue at https://github.com/sst/opencode/issues. + +## Development + +To test locally: + +1. Navigate to a test repo (e.g. `hello-world`): + +``` +cd hello-world +``` + +2. Run: + +``` +MODEL=anthropic/claude-sonnet-4-20250514 \ + ANTHROPIC_API_KEY=sk-ant-api03-1234567890 \ + GITHUB_RUN_ID=dummy \ + bun /path/to/opencode/packages/opencode/src/index.ts github run \ + --token 'github_pat_1234567890' \ + --event '{"eventName":"issue_comment",...}' +``` + +- `MODEL`: The model used by opencode. Same as the `MODEL` defined in the GitHub workflow. +- `ANTHROPIC_API_KEY`: Your model provider API key. Same as the keys defined in the GitHub workflow. +- `GITHUB_RUN_ID`: Dummy value to emulate GitHub action environment. +- `/path/to/opencode`: Path to your cloned opencode repo. `bun /path/to/opencode/packages/opencode/src/index.ts` runs your local version of `opencode`. +- `--token`: A GitHub persontal access token. This token is used to verify you have `admin` or `write` access to the test repo. Generate a token [here](https://github.com/settings/personal-access-tokens). +- `--event`: Mock GitHub event payload (see templates below). + +#### Issue comment event + +``` + --event '{"eventName":"issue_comment","repo":{"owner":"sst","repo":"hello-world"},"actor":"fwang","payload":{"issue":{"number":4},"comment":{"id":1,"body":"hey opencode, summarize thread"}}}' +``` + +Replace: + +- `"owner":"sst"` with repo owner +- `"repo":"hello-world"` with repo name +- `"actor":"fwang"` with the GitHub username of commentor +- `"number":4` with the GitHub issue id +- `"body":"hey opencode, summarize thread"` with comment body + +#### Issue comment with image attachment. + +``` + --event '{"eventName":"issue_comment","repo":{"owner":"sst","repo":"hello-world"},"actor":"fwang","payload":{"issue":{"number":4},"comment":{"id":1,"body":"hey opencode, what is in my image "}}}' +``` + +Replace the image URL `https://github.com/user-attachments/assets/xxxxxxxx` with a valid GitHub attachment (you can generate one by commenting with an image in any issue). + +#### PR comment event + +``` + --event '{"eventName":"issue_comment","repo":{"owner":"sst","repo":"hello-world"},"actor":"fwang","payload":{"issue":{"number":4,"pull_request":{}},"comment":{"id":1,"body":"hey opencode, summarize thread"}}}' +``` diff --git a/github/action.yml b/github/action.yml new file mode 100644 index 000000000..2f9c952b0 --- /dev/null +++ b/github/action.yml @@ -0,0 +1,29 @@ +name: "opencode GitHub Action" +description: "Run opencode in GitHub Actions workflows" +branding: + icon: "code" + color: "orange" + +inputs: + model: + description: "Model to use" + required: false + + share: + description: "Share the opencode session (defaults to true for public repos)" + required: false + +runs: + using: "composite" + steps: + - name: Install opencode + shell: bash + run: curl -fsSL https://opencode.ai/install | bash + + - name: Run opencode + shell: bash + id: run_opencode + run: opencode github run + env: + MODEL: ${{ inputs.model }} + SHARE: ${{ inputs.share }} diff --git a/github/script/publish b/github/script/publish new file mode 100755 index 000000000..ac0e09eff --- /dev/null +++ b/github/script/publish @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# Get the latest Git tag +latest_tag=$(git tag --sort=committerdate | grep -E '^github-v[0-9]+\.[0-9]+\.[0-9]+$' | tail -1) +if [ -z "$latest_tag" ]; then + echo "No tags found" + exit 1 +fi +echo "Latest tag: $latest_tag" + +# Update latest tag +git tag -d latest +git push origin :refs/tags/latest +git tag -a latest $latest_tag -m "Update latest to $latest_tag" +git push origin latest
\ No newline at end of file diff --git a/github/script/release b/github/script/release new file mode 100755 index 000000000..35180b454 --- /dev/null +++ b/github/script/release @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +# Parse command line arguments +minor=false +while [ "$#" -gt 0 ]; do + case "$1" in + --minor) minor=true; shift 1;; + *) echo "Unknown parameter: $1"; exit 1;; + esac +done + +# Get the latest Git tag +git fetch --force --tags +latest_tag=$(git tag --sort=committerdate | grep -E '^github-v[0-9]+\.[0-9]+\.[0-9]+$' | tail -1) +if [ -z "$latest_tag" ]; then + echo "No tags found" + exit 1 +fi + +echo "Latest tag: $latest_tag" + +# Split the tag into major, minor, and patch numbers +IFS='.' read -ra VERSION <<< "$latest_tag" + +if [ "$minor" = true ]; then + # Increment the minor version and reset patch to 0 + minor_number=${VERSION[1]} + let "minor_number++" + new_version="${VERSION[0]}.$minor_number.0" +else + # Increment the patch version + patch_number=${VERSION[2]} + let "patch_number++" + new_version="${VERSION[0]}.${VERSION[1]}.$patch_number" +fi + +echo "New version: $new_version" + +# Tag +git tag $new_version +git push --tags
\ No newline at end of file |
