converge-relay: phase 1 — webhook-to-SSE relay server in Go
- 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
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user