This commit is contained in:
1 parent
9f03384bc9
commit
f5f0d3999e
30 files changed
+96
-93
No files matched your search
@@ -1,6 +1,10 @@
|
||||
# Herald
|
||||

|
||||
|
||||
Herald is a Gitea bot that performs automated AI-powered code reviews on pull requests using [OpenRouter](https://openrouter.ai/).
|
||||
# Steep
|
||||
|
||||
*Let your code steep.*
|
||||
|
||||
Steep is a Gitea bot that performs automated AI-powered code reviews on pull requests using [OpenRouter](https://openrouter.ai/).
|
||||
|
||||
## Features
|
||||
|
||||
@@ -10,18 +14,18 @@ Herald is a Gitea bot that performs automated AI-powered code reviews on pull re
|
||||
- Graceful shutdown — in-progress reviews finish before the process exits
|
||||
- Error tracking via Sentry
|
||||
- Prometheus metrics endpoint for monitoring
|
||||
- Tiny memory footprint (~4MB) thanks to Rust
|
||||
- Lightweight, performant Rust service with Prometheus metrics and Sentry error tracking
|
||||
|
||||
## Installation
|
||||
|
||||
**Requirements:** Rust toolchain ([rustup.rs](https://rustup.rs))
|
||||
|
||||
```sh
|
||||
cargo build --release
|
||||
./target/release/herald
|
||||
cargo build --release -p steep-server
|
||||
./target/release/steep-server
|
||||
```
|
||||
|
||||
Herald reads its configuration from environment variables (a `.env` file is supported):
|
||||
Steep reads its configuration from environment variables (a `.env` file is supported):
|
||||
|
||||
| Variable | Description |
|
||||
|---|---|
|
||||
@@ -38,11 +42,11 @@ Herald reads its configuration from environment variables (a `.env` file is supp
|
||||
| `SENTRY_DSN` | *(optional)* Sentry DSN for error tracking |
|
||||
| `RUST_LOG` | *(optional)* Log level, defaults to `info` |
|
||||
| `SANDBOX_MAX_ITERATIONS` | *(optional)* Maximum number of tool-calling iterations per sandboxed review. Defaults to `8` |
|
||||
| `DOCKER_HOST` | *(optional)* Container daemon socket Herald drives, e.g. `unix:///run/user/1000/podman/podman.sock` for a rootless podman. Defaults to `unix:///var/run/docker.sock` |
|
||||
| `DOCKER_HOST` | *(optional)* Container daemon socket Steep drives, e.g. `unix:///run/user/1000/podman/podman.sock` for a rootless podman. Defaults to `unix:///var/run/docker.sock` |
|
||||
|
||||
## Sandboxed reviews
|
||||
|
||||
Herald reviews pull requests inside an ephemeral
|
||||
Steep reviews pull requests inside an ephemeral
|
||||
[Dev Container](https://containers.dev/). For each review it:
|
||||
|
||||
1. clones the pull request head into a temporary directory,
|
||||
@@ -66,14 +70,14 @@ Each comment is tagged with a severity — `bug`, `security`, `performance` or
|
||||
`maintainability` — shown at the start of the comment, and the summary also lists
|
||||
what the pull request does well.
|
||||
|
||||
Herald drives the container daemon through its socket: `DOCKER_HOST` (default
|
||||
Steep drives the container daemon through its socket: `DOCKER_HOST` (default
|
||||
`unix:///var/run/docker.sock`), which covers both docker and podman's
|
||||
Docker-compatible socket. When the repository contains a
|
||||
`.devcontainer/devcontainer.json` (or `.devcontainer.json`), Herald uses it;
|
||||
`.devcontainer/devcontainer.json` (or `.devcontainer.json`), Steep uses it;
|
||||
otherwise it falls back to a default devcontainer that pulls `debian:stable-slim`
|
||||
and runs the review in `/workspace`.
|
||||
|
||||
Herald can therefore run inside a container with only that socket mounted (no
|
||||
Steep can therefore run inside a container with only that socket mounted (no
|
||||
shared workspace directory is required): the clone is streamed to the daemon over
|
||||
the socket, like the build context, instead of being bind-mounted from a host
|
||||
path the daemon would have to see. This is the setup the `Containerfile`
|
||||
@@ -82,7 +86,7 @@ produces, e.g.:
|
||||
```sh
|
||||
podman run --env-file=.env -p 3001:3001 \
|
||||
-v /run/user/$(id -u)/podman/podman.sock:/var/run/docker.sock \
|
||||
herald:latest
|
||||
steep:latest
|
||||
```
|
||||
|
||||
The `runArgs` of that file are ignored: they come from an untrusted pull request,
|
||||
@@ -107,28 +111,28 @@ Open the project and reopen it in the container — the Rust toolchain is pre-in
|
||||
|
||||
```sh
|
||||
rustup toolchain install stable
|
||||
cargo run
|
||||
cargo run -p steep-server
|
||||
```
|
||||
|
||||
Copy `.env.example` to `.env` and fill in your values before running.
|
||||
|
||||
## Metrics
|
||||
|
||||
Herald optionally exposes a Prometheus metrics endpoint, useful for scraping with an [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) or any Prometheus-compatible scraper.
|
||||
Steep optionally exposes a Prometheus metrics endpoint, useful for scraping with an [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) or any Prometheus-compatible scraper.
|
||||
|
||||
Set `METRICS_BIND_ADDR` (e.g. `0.0.0.0:9100`) to enable it. The metrics are then available at `http://<host>:9100/metrics`.
|
||||
Set `METRICS_BIND_ADDR` (e.g. `0.0.0.0:9100`) to enable it. The metrics are then available at `http://<host>:9100/metrics`. The metric namespace changed from `herald_*` to `steep_*`; update any dashboards or alerts that use the old names.
|
||||
|
||||
### Exposed metrics
|
||||
|
||||
| Metric | Type | Description |
|
||||
|---|---|---|
|
||||
| `herald_webhooks_received_total` | counter | Total webhooks received (label: `event_type`) |
|
||||
| `herald_webhooks_duplicate_total` | counter | Webhooks rejected as duplicates (label: `event_type`) |
|
||||
| `herald_webhooks_channel_full_total` | counter | Webhooks dropped because the bot channel was full (label: `event_type`) |
|
||||
| `herald_bot_tasks_active` | gauge | Bot tasks currently in progress |
|
||||
| `herald_bot_tasks_completed_total` | counter | Bot tasks completed successfully (label: `event_type`) |
|
||||
| `herald_bot_tasks_failed_total` | counter | Bot tasks that failed (label: `event_type`) |
|
||||
| `herald_openrouter_cost_cents_total` | counter | Total OpenRouter cost in cents (divide by 100 for USD) |
|
||||
| `steep_webhooks_received_total` | counter | Total webhooks received (label: `event_type`) |
|
||||
| `steep_webhooks_duplicate_total` | counter | Webhooks rejected as duplicates (label: `event_type`) |
|
||||
| `steep_webhooks_channel_full_total` | counter | Webhooks dropped because the bot channel was full (label: `event_type`) |
|
||||
| `steep_bot_tasks_active` | gauge | Bot tasks currently in progress |
|
||||
| `steep_bot_tasks_completed_total` | counter | Bot tasks completed successfully (label: `event_type`) |
|
||||
| `steep_bot_tasks_failed_total` | counter | Bot tasks that failed (label: `event_type`) |
|
||||
| `steep_openrouter_cost_cents_total` | counter | Total OpenRouter cost in cents (divide by 100 for USD) |
|
||||
|
||||
### OTel collector example
|
||||
|
||||
@@ -137,10 +141,10 @@ receivers:
|
||||
prometheus:
|
||||
config:
|
||||
scrape_configs:
|
||||
- job_name: herald
|
||||
- job_name: steep
|
||||
scrape_interval: 15s
|
||||
static_configs:
|
||||
- targets: ["herald:9100"]
|
||||
- targets: ["steep:9100"]
|
||||
|
||||
service:
|
||||
pipelines:
|
||||
|
||||
Reference in new issue
Block a user