⚠️ Warning: Research and development only. Not production-ready.
githook is a webhook router for GitHub/GitLab/Bitbucket. It receives events, evaluates rules, and publishes matching events to AMQP/NATS/Kafka. Workers consume events and can fetch SCM clients (GitHub/GitLab/Bitbucket) from the server.
- Unified webhook endpoints for GitHub, GitLab, Bitbucket
- Rule-based routing (
when+emit) with stored rules - Driver configs stored per tenant (AMQP/NATS/Kafka)
- Worker SDKs (Go/TypeScript/Python) using rule IDs
- Optional OAuth2-authenticated API
- Event log storage with headers/body + body hash
brew install relaymesh/homebrew-formula/githookOr from source:
go build -o githook ./main.go- Start the server:
githook serve --config config.yamlMinimal config.yaml:
server:
port: 8080
endpoint: http://localhost:8080
storage:
driver: postgres
dsn: postgres://githook:githook@localhost:5432/githook?sslmode=disable
dialect: postgres
auto_migrate: true- Register a provider instance (YAML):
githook --endpoint http://localhost:8080 providers create \
--provider github \
--config-file github.yamlExample github.yaml:
app:
app_id: 12345
private_key_path: ./github.pem
oauth:
client_id: your-client-id
client_secret: your-client-secret
webhook:
secret: your-webhook-secret- Create a driver config (YAML):
githook --endpoint http://localhost:8080 drivers create \
--name amqp \
--config-file amqp.yamlExample amqp.yaml:
url: amqp://guest:guest@localhost:5672/
exchange: githook.events
routing_key_template: "{topic}"Make sure the exchange exists in your broker.
- Create a rule:
githook --endpoint http://localhost:8080 rules create \
--when 'action == "opened"' \
--emit pr.opened \
--driver-id <driver-id>- Point your provider webhook to:
http://<server-host>/webhooks/github
http://<server-host>/webhooks/gitlab
http://<server-host>/webhooks/bitbucket
- Providers:
providers list|get|create|update|delete - Drivers:
drivers list|get|create|update|delete - Rules:
rules list|get|create|update|delete|match - Namespaces:
namespaces list|updateandnamespaces webhook get|update - Installations:
installations list|get
Go:
wk := worker.New(worker.WithEndpoint("http://localhost:8080"))
wk.HandleRule("<rule-id>", func(ctx context.Context, evt *worker.Event) error {
if evt == nil {
return nil
}
log.Printf("topic=%s provider=%s type=%s", evt.Topic, evt.Provider, evt.Type)
return nil
})
_ = wk.Run(ctx)TypeScript:
import { New, WithEndpoint } from "@relaymesh/githook";
const worker = New(WithEndpoint("http://localhost:8080"));
worker.HandleRule("<rule-id>", async (evt) => {
console.log(evt.topic, evt.provider, evt.type);
});
await worker.Run();Python:
from relaymesh_githook import New, WithEndpoint
wk = New(WithEndpoint("http://localhost:8080"))
wk.HandleRule("<rule-id>", lambda ctx, evt: print(evt.topic, evt.provider, evt.type))
wk.Run()See docs/ for provider setup, OAuth flows, rules, drivers, event logs, and SDK details.