docs: rewrite README for shockbot (Gitea/Ollama setup)
This commit is contained in:
@@ -1,241 +1,107 @@
|
|||||||
<!-- test preview system -->
|
# shockbot
|
||||||
<p align="center">
|
|
||||||
<h1 align="center">
|
|
||||||
<picture>
|
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://pullfrog.com/frog-white-200px.png">
|
|
||||||
<img src="https://pullfrog.com/frog-green-200px.png" width="25px" align="center" alt="Green Pullfrog logo" />
|
|
||||||
</picture><br />
|
|
||||||
Pullfrog
|
|
||||||
</h1>
|
|
||||||
<p align="center">
|
|
||||||
Bring your favorite coding agent into GitHub
|
|
||||||
</p>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<br/>
|
Self-hosted AI code review for Gitea, powered by Ollama. Tag `@shockbot` in a PR comment to trigger a review, or configure it to auto-review on every PR.
|
||||||
|
|
||||||
> **🚀 Pullfrog is now generally available!** [Get started →](https://pullfrog.com/console)
|
Based on [pullfrog](https://github.com/pullfrog/pullfrog) — simplified for self-hosted Gitea + Ollama setups.
|
||||||
|
|
||||||
<br/>
|
## Requirements
|
||||||
|
|
||||||
## What is Pullfrog?
|
- Gitea instance
|
||||||
|
- Ollama instance reachable from your Gitea Actions runner
|
||||||
|
- A Gitea bot account with repo read/write access
|
||||||
|
|
||||||
Pullfrog is a GitHub bot that brings the full power of your favorite coding agents into GitHub. It's open source and powered by GitHub Actions.
|
## Setup
|
||||||
|
|
||||||
- **Tag `@pullfrog`** — Tag `@pullfrog` in a comment anywhere in your repo. It will pull in any relevant context using the action's internal MCP server and perform the appropriate task.
|
### 1. Create a bot account
|
||||||
- **Prompt from the web** — Trigger arbitrary tasks from the Pullfrog dashboard
|
|
||||||
- **Automated triggers** — Configure Pullfrog to trigger agent runs in response to specific events. Each of these triggers can be associated with custom prompt instructions.
|
|
||||||
- issue created
|
|
||||||
- issue labeled
|
|
||||||
- PR created
|
|
||||||
- PR review created
|
|
||||||
- PR review requested
|
|
||||||
- and more...
|
|
||||||
|
|
||||||
Pullfrog is the bridge between your preferred coding agents and GitHub. Use it for:
|
Create a Gitea account for the bot (e.g. `shockbot`) and generate an access token with `read:issue`, `write:issue`, `read:pull_request`, `write:pull_request` scopes.
|
||||||
|
|
||||||
- **🤖 Coding tasks** — Tell `@pullfrog` to implement something and it'll spin up a PR. If CI fails, it'll read the logs and attempt a fix automatically. It'll automatically address any PR reviews too.
|
### 2. Add secrets to your repo
|
||||||
- **🔍 PR review** — Coding agents are great at reviewing PRs. Using the "PR created" trigger, you can configure Pullfrog to auto-review new PRs.
|
|
||||||
- **🤙 Issue management** — Via the "issue created" trigger, Pullfrog can automatically respond to common questions, create implementation plans, and link to related issues/PRs. Or (if you're feeling lucky) you can prompt it to immediately attempt a PR addressing new issues.
|
|
||||||
- **Literally whatever** — Want to have the agent automatically add docs to all new PRs? Cut a new release with agent-written notes on every commit to `main`? Pullfrog lets you do it.
|
|
||||||
|
|
||||||
<!-- Features
|
| Secret | Description |
|
||||||
- **Agent-agnostic** — Switch between agents with the click of a radio button.
|
|--------|-------------|
|
||||||
- ** -->
|
| `BOT_TOKEN` | Gitea access token for the bot account |
|
||||||
|
| `OLLAMA_HOST` | URL of your Ollama instance (e.g. `http://192.168.1.10:11434`) |
|
||||||
|
|
||||||
<!--
|
### 3. Add the workflow
|
||||||
## Get started
|
|
||||||
|
|
||||||
Install the Pullfrog GitHub App on your personal or organization account. During installation you can choose to limit access to a specific repo or repos. After installation, you'll be redirected to the Pullfrog dashboard where you'll see an onboarding flow. This flow will create your `pullfrog.yml` workflow and prompt you to set up API keys. Once you finish those steps (2 minutes) you're ready to rock.
|
Create `.gitea/workflows/shockbot.yml` in the repo you want reviewed:
|
||||||
|
|
||||||
[Add to GitHub ➜](https://github.com/apps/pullfrog/installations/new)
|
|
||||||
|
|
||||||
<details>
|
|
||||||
<summary><strong>Manual setup instructions</strong></summary>
|
|
||||||
|
|
||||||
You can also use the `pullfrog/pullfrog` Action without a GitHub App installation. This is more time-consuming to set up, and it places limitations on the actions your Agent will be capable of performing.
|
|
||||||
|
|
||||||
To manually set up the Pullfrog action, you need to set up two workflow files in your repository: `pullfrog.yml` (the execution logic) and `triggers.yml` (the event triggers).
|
|
||||||
|
|
||||||
#### 1. Create `pullfrog.yml`
|
|
||||||
|
|
||||||
Create a file at `.github/workflows/pullfrog.yml`. This is a reusable workflow that runs the Pullfrog action.
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
# PULLFROG ACTION — DO NOT EDIT EXCEPT WHERE INDICATED
|
name: Shockbot Review
|
||||||
name: Pullfrog
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
prompt:
|
|
||||||
type: string
|
|
||||||
description: 'Agent prompt'
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pullfrog:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
id-token: write
|
|
||||||
contents: read
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
- name: Run agent
|
|
||||||
uses: pullfrog/pullfrog@v0
|
|
||||||
with:
|
|
||||||
prompt: ${{ inputs.prompt }}
|
|
||||||
env:
|
|
||||||
# add API keys for the LLM provider(s) you want to use
|
|
||||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
||||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
||||||
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
|
|
||||||
XAI_API_KEY: ${{ secrets.XAI_API_KEY }}
|
|
||||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
|
||||||
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
|
|
||||||
MOONSHOT_API_KEY: ${{ secrets.MOONSHOT_API_KEY }}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 2. Create `triggers.yml`
|
|
||||||
|
|
||||||
Create a file at `.github/workflows/triggers.yml`. This workflow listens for GitHub events and calls the `pullfrog.yml` workflow with the event data.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
name: Agent Triggers
|
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, ready_for_review]
|
||||||
issue_comment:
|
issue_comment:
|
||||||
types: [created]
|
types: [created]
|
||||||
pull_request_review_comment:
|
|
||||||
types: [created]
|
|
||||||
issues:
|
|
||||||
types: [opened, assigned]
|
|
||||||
pull_request_review:
|
|
||||||
types: [submitted]
|
|
||||||
# add other triggers as needed
|
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
pullfrog:
|
|
||||||
|
|
||||||
# trigger conditions (e.g. only run if @pullfrog is mentioned)
|
|
||||||
if: contains(github.event.comment.body, '@pullfrog') || contains(github.event.issue.body, '@pullfrog')
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
id-token: write
|
|
||||||
contents: read
|
|
||||||
uses: ./.github/workflows/pullfrog.yml
|
|
||||||
with:
|
|
||||||
# pass the full event payload as the prompt
|
|
||||||
prompt: ${{ toJSON(github.event) }}
|
|
||||||
secrets: inherit
|
|
||||||
```
|
|
||||||
|
|
||||||
</details>
|
|
||||||
-->
|
|
||||||
|
|
||||||
## Standalone Usage
|
|
||||||
|
|
||||||
You can also use `pullfrog/pullfrog` as a step in your own workflows. The action exposes a `result` output that can be consumed by subsequent steps.
|
|
||||||
|
|
||||||
### Example: Auto-generate release notes on new tags
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
name: Release
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags: ['v*']
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
review:
|
||||||
|
if: |
|
||||||
|
(github.event_name == 'pull_request' && !github.event.pull_request.draft) ||
|
||||||
|
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@shockbot'))
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Generate release notes
|
- name: Run shockbot (PR trigger)
|
||||||
id: notes
|
if: github.event_name == 'pull_request'
|
||||||
uses: pullfrog/pullfrog@v0
|
uses: https://git.shockvpn.com/ShockVPN/shockbot@main
|
||||||
with:
|
with:
|
||||||
prompt: |
|
prompt: "Review this pull request"
|
||||||
Generate release notes for ${{ github.ref_name }}.
|
|
||||||
Compare commits between this tag and the previous tag.
|
|
||||||
Format as markdown: summary paragraph, then ### Features, ### Fixes, ### Breaking Changes sections.
|
|
||||||
Omit empty sections. Be concise.
|
|
||||||
env:
|
env:
|
||||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||||
|
OLLAMA_HOST: ${{ secrets.OLLAMA_HOST }}
|
||||||
|
GITEA_URL: https://git.shockvpn.com
|
||||||
|
GITEA_PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||||
|
GITEA_PR_TITLE: ${{ github.event.pull_request.title }}
|
||||||
|
|
||||||
# write to file to avoid shell escaping issues with special characters
|
- name: Run shockbot (mention trigger)
|
||||||
- name: Create GitHub release
|
if: github.event_name == 'issue_comment'
|
||||||
run: |
|
uses: https://git.shockvpn.com/ShockVPN/shockbot@main
|
||||||
notesfile="$RUNNER_TEMP/release-notes-$GITHUB_RUN_ID.md"
|
with:
|
||||||
printf '%s' "$NOTES" > "$notesfile"
|
prompt: ${{ github.event.comment.body }}
|
||||||
gh release create ${{ github.ref_name }} --title "${{ github.ref_name }}" --notes-file "$notesfile"
|
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
BOT_TOKEN: ${{ secrets.BOT_TOKEN }}
|
||||||
NOTES: ${{ steps.notes.outputs.result }}
|
OLLAMA_HOST: ${{ secrets.OLLAMA_HOST }}
|
||||||
|
GITEA_URL: https://git.shockvpn.com
|
||||||
|
GITEA_PR_NUMBER: ${{ github.event.issue.number }}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Example: Structured Output with Zod Schema
|
## Configuration
|
||||||
|
|
||||||
You can force the agent to return structured JSON output by providing a JSON schema. This allows you to reliably parse and use the agent's response in subsequent workflow steps.
|
Three values need to be configured — the rest come from the event context (as shown in the workflow example above) or are set automatically by Gitea Actions.
|
||||||
|
|
||||||
You can define your JSON schema directly or uou can use any validation library that converts to JSON Schema. Here's an example using [Zod](https://zod.dev):
|
| Secret / env var | Description |
|
||||||
|
|-----------------|-------------|
|
||||||
|
| `BOT_TOKEN` | Gitea access token for the bot account |
|
||||||
|
| `OLLAMA_HOST` | URL of your Ollama instance |
|
||||||
|
| `GITEA_URL` | URL of your Gitea instance |
|
||||||
|
|
||||||
|
### Model
|
||||||
|
|
||||||
|
Defaults to `qwen3.6:35b`. Override with the `model` input:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
name: Release Check
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [closed]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-release:
|
|
||||||
if: github.event.pull_request.merged == true
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: npm install --no-save --no-package-lock zod @actions/core
|
|
||||||
|
|
||||||
- name: Generate Schema
|
|
||||||
id: schema
|
|
||||||
run: |
|
|
||||||
node -e '
|
|
||||||
import { z } from "zod";
|
|
||||||
import { setOutput } from "@actions/core";
|
|
||||||
const schema = z.object({
|
|
||||||
version: z.string().describe("Semantic version number (e.g. 1.0.0)"),
|
|
||||||
isBreaking: z.boolean().describe("Whether this release contains breaking changes"),
|
|
||||||
changelog: z.array(z.string()).describe("List of changes in this release"),
|
|
||||||
});
|
|
||||||
setOutput("schema", JSON.stringify(z.toJSONSchema(schema)));
|
|
||||||
'
|
|
||||||
|
|
||||||
- name: Analyze PR
|
|
||||||
id: analysis
|
|
||||||
uses: pullfrog/pullfrog@v0
|
|
||||||
with:
|
with:
|
||||||
prompt: |
|
prompt: "Review this pull request"
|
||||||
Analyze this PR and determine semantic versioning impact.
|
model: "llama3.1:70b"
|
||||||
Return a JSON object matching the provided schema.
|
|
||||||
output_schema: ${{ steps.schema.outputs.schema }}
|
|
||||||
env:
|
|
||||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
||||||
|
|
||||||
- name: Process Result
|
|
||||||
run: |
|
|
||||||
# Parse the JSON result using fromJSON()
|
|
||||||
echo "Version: ${{ fromJSON(steps.analysis.outputs.result).version }}"
|
|
||||||
echo "Breaking: ${{ fromJSON(steps.analysis.outputs.result).isBreaking }}"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
- **Auto-review on PR open** — the PR trigger fires automatically on new PRs
|
||||||
|
- **Manual trigger** — comment `@shockbot review` on any PR to trigger a review on demand
|
||||||
|
- **Custom prompt** — any comment mentioning `@shockbot` is passed as the prompt, so `@shockbot review focusing on security` works
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT. Based on [pullfrog/pullfrog](https://github.com/pullfrog/pullfrog), used under the MIT license.
|
||||||
|
|||||||
Reference in New Issue
Block a user