Skip to content

Commit 2ff8bd4

Browse files
sthings userclaude
andcommitted
feat: config-driven stream routing with allowlist and matchers
Add an opt-in routing layer: when ROUTES_CONFIG points at a YAML file, omni-pitcher resolves a destination Redis stream per request based on an ordered rule list (endpoint / system / author / tag_contains / title_contains substrings, AND-within-rule, first-match-wins). Misses fall back to default_stream. The streams allowlist is validated at startup, so typos in route targets fail fast instead of silently mis-routing. Threaded the resolved stream through Pitcher.Pitch as a variadic override, consuming homerun-library v3.1.0's streamOverride parameter. With ROUTES_CONFIG unset, behavior is unchanged — every message goes to REDIS_STREAM as before. Closes #105 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 44201b4 commit 2ff8bd4

20 files changed

Lines changed: 634 additions & 66 deletions

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,46 @@ helmfile apply -f \
276276

277277
</details>
278278

279+
## Stream routing
280+
281+
By default omni-pitcher writes every message to a single Redis stream (`REDIS_STREAM`, default `messages`). Set the `ROUTES_CONFIG` env var to a YAML file path to route messages to different streams based on which endpoint received them or what they contain.
282+
283+
```yaml
284+
# routes.yaml
285+
streams: # allowlist of valid destination streams
286+
- messages
287+
- github-events
288+
- grafana-alerts
289+
- releases
290+
default_stream: messages # fallback when no rule matches; must be in `streams`
291+
routes: # ordered; first match wins, AND inside a rule
292+
- match: { endpoint: /pitch/github }
293+
stream: github-events
294+
- match: { system: grafana }
295+
stream: grafana-alerts
296+
- match: { tag_contains: release }
297+
stream: releases
298+
```
299+
300+
Available matchers (all substring, no regex):
301+
302+
| Matcher | Matches against |
303+
|---|---|
304+
| `endpoint` | Request URL path (e.g. `/pitch/github`) |
305+
| `system` | `Message.System` |
306+
| `author` | `Message.Author` |
307+
| `tag_contains` | `Message.Tags` |
308+
| `title_contains` | `Message.Title` (list — any match wins) |
309+
310+
Rules are evaluated top-to-bottom; **first match wins**. Inside a rule, all declared matchers must match (**AND**). If no rule matches, the message goes to `default_stream`.
311+
312+
Misconfiguration fails startup. Specifically:
313+
- `streams` must be non-empty and unique
314+
- `default_stream` and every `routes[*].stream` must be in `streams`
315+
- every rule must declare at least one matcher
316+
317+
When `ROUTES_CONFIG` is unset, the legacy single-stream behavior is preserved (everything goes to `REDIS_STREAM`). See [`examples/routes.yaml`](examples/routes.yaml) for a full example.
318+
279319
## PR preview environments
280320

281321
Every open PR against `main` gets an ephemeral preview environment on `homerun2-dev` — omni-pitcher + redis-stack in an isolated namespace, reachable end-to-end so reviewers can pitch test events against the PR build.

docs/api-usage.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ Returns `200 OK` when the service is running.
170170
| `PORT` | `8080` | HTTP server port |
171171
| `REDIS_ADDR` | `redis-stack.homerun2.svc.cluster.local` | Redis server address |
172172
| `REDIS_PORT` | `6379` | Redis server port |
173-
| `REDIS_STREAM` | `messages` | Redis stream name |
173+
| `REDIS_STREAM` | `messages` | Redis stream name (used when `ROUTES_CONFIG` is unset) |
174+
| `ROUTES_CONFIG` | (empty) | Path to YAML stream-routing config; see [Stream routing](../README.md#stream-routing) in the README |
174175
| `REDIS_SEARCH_INDEX` | (empty) | RediSearch index name (enables dual-write) |
175176
| `GITHUB_WEBHOOK_SECRET` | (empty) | HMAC secret for GitHub webhook validation |
176177
| `AUTH_TOKEN` | (required) | Bearer token for auth |

examples/routes.yaml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Example routing config consumed by omni-pitcher when ROUTES_CONFIG is set.
2+
# See README.md "Stream routing" for the full schema and semantics.
3+
4+
# Allowlist of valid destination streams. Any route or default targeting a
5+
# stream not in this list fails startup.
6+
streams:
7+
- messages
8+
- github-events
9+
- grafana-alerts
10+
- releases
11+
12+
# Fallback stream when no rule matches. Must be in `streams`.
13+
default_stream: messages
14+
15+
# Ordered rule list — first match wins. All matchers within a single rule
16+
# must match (AND semantics). All matchers are substring (no regex).
17+
routes:
18+
# GitHub webhook traffic — routed by the URL path the request landed on.
19+
- match:
20+
endpoint: /pitch/github
21+
stream: github-events
22+
23+
# Grafana alerts — webhook payload sets Message.System = receiver name.
24+
- match:
25+
system: grafana
26+
stream: grafana-alerts
27+
28+
# Release announcements — any tag containing "release".
29+
- match:
30+
tag_contains: release
31+
stream: releases
32+
33+
# Combined matchers (AND) — only push events that mention errors land here.
34+
# Falls through to default_stream if any matcher misses.
35+
- match:
36+
endpoint: /pitch/github
37+
title_contains: [error, failure]
38+
stream: grafana-alerts

go.mod

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/golang-jwt/jwt/v5 v5.3.1
1010
github.com/redis/go-redis/v9 v9.19.0
1111
github.com/stuttgart-things/homerun-library/v3 v3.1.0
12+
gopkg.in/yaml.v3 v3.0.1
1213
)
1314

1415
require (
@@ -86,7 +87,6 @@ require (
8687
github.com/coreos/go-semver v0.3.1 // indirect
8788
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
8889
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
89-
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
9090
github.com/dustin/go-humanize v1.0.1 // indirect
9191
github.com/emirpasic/gods v1.18.1 // indirect
9292
github.com/envoyproxy/go-control-plane v0.13.1 // indirect
@@ -227,6 +227,5 @@ require (
227227
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
228228
gopkg.in/warnings.v0 v0.1.2 // indirect
229229
gopkg.in/yaml.v2 v2.4.0 // indirect
230-
gopkg.in/yaml.v3 v3.0.1 // indirect
231230
sigs.k8s.io/yaml v1.4.0 // indirect
232231
)

go.sum

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,8 @@ c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd h1:ZLsPO6WdZ5zatV4UfVpr7oAw
1010
c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd/go.mod h1:SrHC2C7r5GkDk8R+NFVzYy/sdj0Ypg9htaPXQq5Cqeo=
1111
cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4=
1212
cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
13-
charm.land/bubbletea/v2 v2.0.2 h1:4CRtRnuZOdFDTWSff9r8QFt/9+z6Emubz3aDMnf/dx0=
14-
charm.land/bubbletea/v2 v2.0.2/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ=
15-
charm.land/bubbletea/v2 v2.0.5 h1:TQlLFqxo39AAHSVuOhJ5D3nH7O9Nk8JGinsfWQ4y1U4=
16-
charm.land/bubbletea/v2 v2.0.5/go.mod h1:dvbsYZD+MHkdIZl+Z67D212hEvB+GII2tfH8f9SnoDw=
1713
charm.land/bubbletea/v2 v2.0.6 h1:UHN/91OyuhaOFGSrBXQ/hMZD8IO1Uc4BvHlgHXL2WJo=
1814
charm.land/bubbletea/v2 v2.0.6/go.mod h1:MH/D8ZLlN3op37vQvijKuU29g3rqTp+aQapURFonF9g=
19-
charm.land/lipgloss/v2 v2.0.2 h1:xFolbF8JdpNkM2cEPTfXEcW1p6NRzOWTSamRfYEw8cs=
20-
charm.land/lipgloss/v2 v2.0.2/go.mod h1:KjPle2Qd3YmvP1KL5OMHiHysGcNwq6u83MUjYkFvEkM=
2115
charm.land/lipgloss/v2 v2.0.3 h1:yM2zJ4Cf5Y51b7RHIwioil4ApI/aypFXXVHSwlM6RzU=
2216
charm.land/lipgloss/v2 v2.0.3/go.mod h1:7myLU9iG/3xluAWzpY/fSxYYHCgoKTie7laxk6ATwXA=
2317
cloud.google.com/go v0.117.0 h1:Z5TNFfQxj7WG2FgOGX1ekC5RiXrYgms6QscOm32M/4s=
@@ -175,18 +169,10 @@ github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91
175169
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
176170
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
177171
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
178-
github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY=
179-
github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8=
180172
github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q=
181173
github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q=
182-
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA=
183-
github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8/go.mod h1:SQpCTRNBtzJkwku5ye4S3HEuthAlGy2n9VXZnWkEW98=
184-
github.com/charmbracelet/ultraviolet v0.0.0-20260413211237-bd52878bcec2 h1:mRAlb/WARLaCnCwAEBa8Zfk965GrYc414MhJamV4anw=
185-
github.com/charmbracelet/ultraviolet v0.0.0-20260413211237-bd52878bcec2/go.mod h1:bAAz7dh/FTYfC+oiHavL4mX1tOIBZ0ZwYjSi3qE6ivM=
186174
github.com/charmbracelet/ultraviolet v0.0.0-20260416155717-489999b90468 h1:Q9fO0y1Zo5KB/5Vu8JZoLGm1N3RzF9bNj3Ao3xoR+Ac=
187175
github.com/charmbracelet/ultraviolet v0.0.0-20260416155717-489999b90468/go.mod h1:bAAz7dh/FTYfC+oiHavL4mX1tOIBZ0ZwYjSi3qE6ivM=
188-
github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
189-
github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
190176
github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI=
191177
github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ=
192178
github.com/charmbracelet/x/exp/golden v0.0.0-20250806222409-83e3a29d542f h1:pk6gmGpCE7F3FcjaOEKYriCvpmIN4+6OS/RD0vm4uIA=
@@ -225,7 +211,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
225211
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
226212
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
227213
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
228-
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
229214
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
230215
github.com/docker/cli v27.4.1+incompatible h1:VzPiUlRJ/xh+otB75gva3r05isHMo5wXDfPRi5/b4hI=
231216
github.com/docker/cli v27.4.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
@@ -359,8 +344,6 @@ github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
359344
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
360345
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
361346
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
362-
github.com/jedib0t/go-pretty/v6 v6.7.8 h1:BVYrDy5DPBA3Qn9ICT+PokP9cvCv1KaHv2i+Hc8sr5o=
363-
github.com/jedib0t/go-pretty/v6 v6.7.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
364347
github.com/jedib0t/go-pretty/v6 v6.7.9 h1:frarzQWmkZd97syT81+TH8INKPpzoxQnk+Mk5EIHSrM=
365348
github.com/jedib0t/go-pretty/v6 v6.7.9/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
366349
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
@@ -394,8 +377,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
394377
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
395378
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
396379
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
397-
github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
398-
github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
399380
github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4=
400381
github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
401382
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
@@ -408,8 +389,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
408389
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
409390
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
410391
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
411-
github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ=
412-
github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
413392
github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw=
414393
github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
415394
github.com/mattn/goveralls v0.0.12 h1:PEEeF0k1SsTjOBQ8FOmrOAoCu4ytuMaWCnWe94zxbCg=
@@ -479,8 +458,6 @@ github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkG
479458
github.com/pterm/pterm v0.12.83 h1:ie+YmGmA727VuhxBlyGr74Ks+7McV6kT99IB8EU80aA=
480459
github.com/pterm/pterm v0.12.83/go.mod h1:xlgc6bFWyJIMtmLJvGim+L7jhSReilOlOnodeIYe4Tk=
481460
github.com/redis/go-redis/v9 v9.0.2/go.mod h1:/xDTe9EF1LM61hek62Poq2nzQSGj0xSrEtEHbBQevps=
482-
github.com/redis/go-redis/v9 v9.18.0 h1:pMkxYPkEbMPwRdenAzUNyFNrDgHx9U+DrBabWNfSRQs=
483-
github.com/redis/go-redis/v9 v9.18.0/go.mod h1:k3ufPphLU5YXwNTUcCRXGxUoF1fqxnhFQmscfkCoDA0=
484461
github.com/redis/go-redis/v9 v9.19.0 h1:XPVaaPSnG6RhYf7p+rmSa9zZfeVAnWsH5h3lxthOm/k=
485462
github.com/redis/go-redis/v9 v9.19.0/go.mod h1:v/M13XI1PVCDcm01VtPFOADfZtHf8YW3baQf57KlIkA=
486463
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -541,8 +518,6 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
541518
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
542519
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
543520
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
544-
github.com/stuttgart-things/homerun-library/v3 v3.0.5 h1:CCyYh4Xm46lvywZ1FOSLNCv3fM7MtD10mXjNYZYElsQ=
545-
github.com/stuttgart-things/homerun-library/v3 v3.0.5/go.mod h1:VFH9uHuQK/p2KeraVx9VM//H1vfY+RoqHKXVI78nwcs=
546521
github.com/stuttgart-things/homerun-library/v3 v3.1.0 h1:7LrVvNeohX24WyG565hwZA6DZMTJC2MRzbyW5eWC9Ls=
547522
github.com/stuttgart-things/homerun-library/v3 v3.1.0/go.mod h1:2Ol0sGq0p46OxtQ70CxoSLEc9N/mXn1/oVQykA/l+zE=
548523
github.com/stuttgart-things/redisqueue v0.0.0-20230628084515-1d31f7874df7 h1:nVooDvBYhBPQysVjbvWP3S1CQgmNG/Vovt+ahmv9Cas=
@@ -579,8 +554,8 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsr
579554
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
580555
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
581556
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
582-
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
583-
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
557+
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
558+
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
584559
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
585560
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
586561
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
@@ -645,8 +620,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
645620
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
646621
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
647622
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
648-
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
649-
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
650623
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
651624
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
652625
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -674,8 +647,6 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
674647
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
675648
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
676649
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
677-
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
678-
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
679650
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
680651
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
681652
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=

internal/handlers/github.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,16 @@ import (
1414

1515
"github.com/stuttgart-things/homerun2-omni-pitcher/internal/models"
1616
"github.com/stuttgart-things/homerun2-omni-pitcher/internal/pitcher"
17+
"github.com/stuttgart-things/homerun2-omni-pitcher/internal/routing"
1718

1819
homerun "github.com/stuttgart-things/homerun-library/v3"
1920
)
2021

2122
// NewGitHubPitchHandler creates a handler that accepts GitHub webhook payloads
2223
// and converts them into homerun.Message for pitching.
2324
// If webhookSecret is non-empty, the handler validates X-Hub-Signature-256.
24-
func NewGitHubPitchHandler(p pitcher.Pitcher, webhookSecret string) http.HandlerFunc {
25+
// If router is non-nil, the resolved stream is passed as a per-request override.
26+
func NewGitHubPitchHandler(p pitcher.Pitcher, webhookSecret string, router *routing.Router) http.HandlerFunc {
2527
return func(w http.ResponseWriter, r *http.Request) {
2628
if r.Method != http.MethodPost {
2729
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
@@ -66,7 +68,8 @@ func NewGitHubPitchHandler(p pitcher.Pitcher, webhookSecret string) http.Handler
6668

6769
msg := githubEventToMessage(eventType, payload)
6870

69-
objectID, streamID, err := p.Pitch(msg)
71+
stream := router.Resolve(r.URL.Path, msg)
72+
objectID, streamID, err := p.Pitch(msg, stream)
7073
if err != nil {
7174
slog.Error("failed to pitch github event", "error", err, "event", eventType)
7275
respondWithError(w, http.StatusServiceUnavailable, "Failed to enqueue event")

0 commit comments

Comments
 (0)