diff --git a/github/check/action.yml b/github/check/action.yml new file mode 100644 index 000000000..732d67b3a --- /dev/null +++ b/github/check/action.yml @@ -0,0 +1,48 @@ +name: "opencode GitHub Run" +description: "Run opencode in GitHub Actions workflows" +branding: + icon: "code" + color: "orange" + +inputs: + model: + description: "The model to use with opencode. Takes the format of `provider/model`." + required: true + + prompt: + description: "The prompt to use with opencode." + required: true + + share: + description: "Whether to share the opencode session. Defaults to true for public repositories." + required: false + + token: + description: "Optional GitHub access token for performing operations such as creating comments, committing changes, and opening pull requests. Defaults to the installation access token from the opencode GitHub App." + required: false + +runs: + using: "composite" + steps: + - name: Install opencode + shell: bash + run: curl -fsSL https://opencode.ai/install | bash + + - name: Install bun + shell: bash + run: npm install -g bun + + - name: Install dependencies + shell: bash + run: | + cd ${GITHUB_ACTION_PATH} + bun install + + - name: Run opencode + shell: bash + run: bun ${GITHUB_ACTION_PATH}/index.ts + env: + MODEL: ${{ inputs.model }} + PROMPT: ${{ inputs.prompt }} + SHARE: ${{ inputs.share }} + TOKEN: ${{ inputs.token }} diff --git a/github/check/index.ts b/github/check/index.ts new file mode 100644 index 000000000..587603ba7 --- /dev/null +++ b/github/check/index.ts @@ -0,0 +1,61 @@ +import { $ } from "bun" +import * as core from "@actions/core" +import { Auth } from "../src/auth" +import { Git } from "../src/git" +import { Opencode } from "../src/opencode" +import { Context } from "../src/context" + +try { + Context.assertEventName("pull_request_opened", "pull_request_synchronize") + await check() + process.exit(0) +} catch (e: any) { + console.error(e) + let msg = e + if (e instanceof $.ShellError) msg = e.stderr.toString() + else if (e instanceof Error) msg = e.message + core.setFailed(msg) + // Also output the clean error message for the action to capture + //core.setOutput("prepare_error", e.message); + process.exit(1) +} + +export async function check() { + try { + await Git.configure() + await Opencode.start() + + const filename = "check-failed-reason.json" + const pr = Context.payloadPullRequest() + await Opencode.chat(` +A pull request has been created or updated: '${pr.title}' + + +${pr.number} + + + +${pr.body} + + +Please check: + +${process.env.PROMPT} + + +If the check failed, write the reason to ${filename}. Keep the reason short and concise, only one sentence. + +If the check passed, do not create any file. + `) + + // check file exists + try { + const reason = await Bun.file(filename).text() + if (reason) throw new Error(reason) + } catch (e) {} + } finally { + Opencode.closeServer() + await Auth.revoke() + await Git.restore() + } +}