Skip to content

Latest commit

 

History

History
223 lines (168 loc) · 8.42 KB

ci-integration.md

File metadata and controls

223 lines (168 loc) · 8.42 KB

CI Integration (GitHub Actions)

Use tinycode run directly in GitHub Actions for CI-driven agent loops. There is no official GitHub Action package — install the binary and invoke tinycode run in workflow YAML. That keeps CI local-first: your workflow owns the model, secrets, and permissions.

For full run-mode flags and NDJSON event types, see Run Mode in the user guide.

Prerequisites

  • A model tinycode can reach from the runner (cloud API or a reachable OpenAI-compatible endpoint)
  • Repository secrets for API keys and the model id (see Secrets)
  • A Linux or macOS runner (ubuntu-latest is typical)

Install the binary once per job (same installer as local use):

- name: Install tinycode
  run: |
    curl -fsSL https://raw.githubusercontent.com/bobbyjohnstx/tinycode/main/install.sh | sh
    echo "$HOME/.local/bin" >> "$GITHUB_PATH"

Basic PR workflow

Review a pull request when it opens or updates. Redirect stdin from /dev/null so the job does not hang waiting for input.

name: tinycode PR review

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install tinycode
        run: |
          curl -fsSL https://raw.githubusercontent.com/bobbyjohnstx/tinycode/main/install.sh | sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"

      - name: Run tinycode
        env:
          OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
        run: |
          # Default build agent already allows ordinary shell/edit/read.
          # Add --dangerously-skip-permissions only if the job must auto-approve
          # residual Ask classes (webfetch, .env*, destructive/secret-shell, external_directory).
          tinycode run --format json \
            -m "${{ secrets.MODEL }}" \
            "Review this PR for issues. Summarize findings clearly." \
            < /dev/null \
            | tee tinycode-out.ndjson

Ordinary shell / edit / read work under the default build agent without --dangerously-skip-permissions. Headless auto-reject applies only to residual Ask classes: webfetch, read .env*, destructive-shell, secret-shell, and external_directory.

The question tool is fail-closed in tinycode run: asks are rejected immediately as unsupported in non-interactive mode (no stdin wait).

Comment-triggered /tinycode

Respond when someone posts a PR comment that starts with /tinycode:

name: tinycode comment

on:
  issue_comment:
    types: [created]

permissions:
  contents: read
  pull-requests: write
  issues: write

jobs:
  run:
    if: >
      github.event.issue.pull_request &&
      startsWith(github.event.comment.body, '/tinycode')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: refs/pull/${{ github.event.issue.number }}/head

      - name: Install tinycode
        run: |
          curl -fsSL https://raw.githubusercontent.com/bobbyjohnstx/tinycode/main/install.sh | sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"

      - name: Run tinycode from comment
        env:
          OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
          PROMPT: ${{ github.event.comment.body }}
        run: |
          # Strip the leading /tinycode token; rest is the prompt
          PROMPT_TEXT="${PROMPT#/tinycode}"
          PROMPT_TEXT="${PROMPT_TEXT# }"
          if [ -z "$PROMPT_TEXT" ]; then
            PROMPT_TEXT="Review this pull request and summarize findings."
          fi

          tinycode run --format json \
            -m "${{ secrets.MODEL }}" \
            "$PROMPT_TEXT" \
            < /dev/null \
            | tee tinycode-out.ndjson

      - name: Post reply from JSON output
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          # Concatenate model text deltas into one comment body
          REPLY=$(jq -r 'select(.type == "text") | .text // empty' tinycode-out.ndjson | tr -d '\n')
          if [ -z "$REPLY" ]; then
            REPLY=$(jq -r 'select(.type == "error") | .message // "tinycode produced no text output"' tinycode-out.ndjson | tail -n1)
          fi
          gh pr comment "${{ github.event.issue.number }}" --body "$REPLY"

The workflow calls tinycode run only — no custom Action marketplace package.

Secrets

Store credentials and the model id in GitHub Actions secrets (Settings → Secrets and variables → Actions). Do not hardcode keys in YAML.

Secret Purpose
OPENROUTER_API_KEY Enables OpenRouter discovery/auth (common cloud path)
MODEL Model id passed to -m (for example openrouter/anthropic/claude-sonnet-4)

Other providers:

Env / secret Notes
TINYCODE_OLLAMA_HOST / OLLAMA_HOST Reachable Ollama base URL (self-hosted runner or network path)
TINYCODE_VLLM_HOST vLLM OpenAI-compatible endpoint
TINYCODE_LMSTUDIO_HOST LM Studio endpoint
TINYCODE_MAAS_API_KEY MaaS auth when using that provider

Wire secrets into the step env: block so tinycode can discover the provider at startup:

env:
  OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}

Model selection:

tinycode run -m "${{ secrets.MODEL }}" "…"

Or pin a literal model in the workflow if it is not sensitive (prefer a secret when the id encodes a paid route).

--dangerously-skip-permissions caveats

The default build agent already allows ordinary shell, edit, and read without this flag. Use --dangerously-skip-permissions when you intentionally want unattended auto-approval of residual Ask-class permissions (and anything else that would prompt): webfetch, .env* reads, destructive/secret shell, and paths outside the project.

Risks with the flag:

  • Ask-class tools (network fetch, secret-file shell, destructive shell, external dirs) run without a human gate
  • Compromised prompts (for example from untrusted PR content or comments) can drive those higher-risk tools
  • Secrets available to the job process may be readable by tools the agent invokes

Mitigations:

  • Omit the flag for ordinary edit/shell CI work; add it only when Ask-class tools must succeed unattended
  • Scope permissions: tightly (contents: read unless the job must push)
  • Restrict which events and actors can trigger agent jobs (for example require a collaborator comment)
  • Prefer --safe-mode when plugins/MCP/user agents are not needed
  • Cap cost with --max-tokens and --max-iterations
  • Run on pull_request from forks only with secrets policies you understand (fork PRs often cannot access repository secrets)

Default headless behavior without the flag: build allows ordinary shell/edit/read; residual Ask requests are auto-rejected. Interactive (-i) and JSON permission protocols are a poor fit for most Actions jobs.

JSON output parsing

--format json emits NDJSON (one JSON object per line). Useful event types for CI:

type Use in CI
session Capture sessionID for logs or follow-up runs
text Append text deltas to build the assistant reply
tool_begin / tool_end Optional progress / failure diagnostics
done Success when ok is true; ok: false means a tool returned isError (exit 1). Use --no-fail-on-tool-error to keep exit 0 / ok: true
error Failure message (processor/turn failure; cancel is exit 130)

Example: collect the reply and fail the job if the run did not finish cleanly:

tinycode run --format json \
  -m "${{ secrets.MODEL }}" \
  "Summarize the diff risk in this checkout." \
  < /dev/null \
  | tee tinycode-out.ndjson

REPLY=$(jq -r 'select(.type == "text") | .text // empty' tinycode-out.ndjson | tr -d '\n')
OK=$(jq -r 'select(.type == "done") | .ok' tinycode-out.ndjson | tail -n1)

echo "$REPLY"
if [ "$OK" != "true" ]; then
  jq -r 'select(.type == "error") | .message // empty' tinycode-out.ndjson >&2
  exit 1
fi

Post that reply with gh pr comment (as in the comment-triggered example) or gh api if you prefer raw REST.

Text format (--format default, the default) is fine for logs; prefer --format json whenever another step must parse the answer.

Further reading

  • Run Mode — flags, permissions, multi-turn NDJSON protocol
  • Install — installer env vars and platforms
  • Cheatsheet — short tinycode run examples