25881f3ff8
- Pub/sub broker with fan-out to SSE clients - POST /webhook — receives Gitea push events, optional HMAC verification - GET /events — SSE stream of push events - GET /health — health check endpoint - Zero external dependencies (stdlib only) - Docker-based build via goctl wrapper (golang:1.26-alpine) - systemd unit, README with deployment docs - Tests: broker pub/sub, slow subscriber drop, ref parsing, signature verification - 6.0M static binary
90 lines
3.0 KiB
Markdown
90 lines
3.0 KiB
Markdown
# converge-relay
|
|
|
|
Webhook-to-SSE relay for [converge](https://github.com/jbrechtel/converge). Receives Gitea push webhooks and fans them out to connected converge clients via Server-Sent Events.
|
|
|
|
## How it works
|
|
|
|
```
|
|
┌─────────────┐ POST /webhook ┌──────────────────┐ GET /events (SSE) ┌──────────────────┐
|
|
│ Gitea │ ────────────────> │ converge-relay │ ──────────────────> │ converge (local) │
|
|
│ Server │ (push event) │ (this server) │ event: push │ │
|
|
└─────────────┘ └──────────────────┘ └──────────────────┘
|
|
```
|
|
|
|
1. Configure Gitea to send push webhooks to `https://your-server:8080/webhook`
|
|
2. Run `converge-relay` on a publicly reachable server (or behind nginx)
|
|
3. Point your local `converge` at the relay's SSE endpoint with `--relay-url http://your-server:8080/events`
|
|
|
|
## Build & run (Docker-only, no host Go tools required)
|
|
|
|
```bash
|
|
# Build (formats, tests, compiles) → ./build/converge-relay
|
|
./scripts/build
|
|
|
|
# Run tests only
|
|
./scripts/test
|
|
|
|
# Run in development
|
|
./scripts/run --listen :8080
|
|
|
|
# Run go commands directly
|
|
./goctl go fmt ./...
|
|
./goctl go mod tidy
|
|
```
|
|
|
|
## Configuration
|
|
|
|
| Flag | Env var | Default | Description |
|
|
|------|---------|---------|-------------|
|
|
| `--listen` | `CONVERGE_RELAY_LISTEN` | `:8080` | Address to listen on |
|
|
| `--secret` | `CONVERGE_RELAY_SECRET` | `""` | Shared secret for HMAC webhook verification |
|
|
|
|
## Endpoints
|
|
|
|
### `POST /webhook`
|
|
|
|
Receives Gitea push webhooks. Validates `X-Gitea-Signature` or `X-Hub-Signature-256` against the configured secret. Extracts `repository.full_name` and branch name from `ref`.
|
|
|
|
### `GET /events`
|
|
|
|
SSE stream. Clients connect and receive push events as they arrive:
|
|
|
|
```
|
|
event: push
|
|
data: {"full_name":"myorg/myrepo","branch":"main","ref":"refs/heads/main"}
|
|
```
|
|
|
|
Automatic reconnection with `Last-Event-ID` is supported. When the connection drops, clients reconnect with exponential backoff.
|
|
|
|
### `GET /health`
|
|
|
|
Returns `ok\n` — useful for load balancer health checks.
|
|
|
|
## Deployment
|
|
|
|
```bash
|
|
# Build
|
|
./scripts/build
|
|
|
|
# Install
|
|
sudo cp build/converge-relay /usr/local/bin/
|
|
|
|
# Install and enable the systemd service
|
|
sudo cp converge-relay.service /etc/systemd/system/
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now converge-relay
|
|
```
|
|
|
|
For production, set the `CONVERGE_RELAY_SECRET` environment variable in the service file or drop-in.
|
|
|
|
## Gitea webhook setup
|
|
|
|
1. Go to your repository → Settings → Webhooks → Add Webhook → Gitea
|
|
2. Target URL: `https://your-server:8080/webhook`
|
|
3. Secret: same value as `CONVERGE_RELAY_SECRET`
|
|
4. Events: Push events only
|
|
|
|
## Docker image
|
|
|
|
Built via `golang:1.26-alpine`. No external Go dependencies — stdlib only.
|