Overview
Currently webhook subscriptions support two filters: repo and event_types. This issue proposes a richer, flat filter model that lets subscribers watch for very specific changes without having to filter on the receiver side.
Motivation
Primary use case: get alerted any time a path or set of paths changes on a specific branch. More generally, subscribers need to express routing logic that today requires post-delivery filtering in their own code.
Proposed Filter Fields
All filters are optional. A filter field is only evaluated when the event carries that field — if the event type doesn't have that field, the filter passes.
| Field |
Type |
Applies to |
repo |
string |
all (already exists) |
event_types |
[]string |
all (already exists) |
branch |
string |
commit.created, branch.*, proposal.*, check.reported |
base_branch |
string |
proposal.*, branch.merged, branch.rebased |
author |
string |
commit.created, proposal.*, review.submitted, role.changed |
paths |
[]string |
commit.created — prefix match; event delivers if ANY touched file matches ANY prefix |
check_name |
string |
check.reported |
Semantics
- Flat bag: all filters live on the subscription, not scoped per event type. Simple to implement and reason about.
- Pass-through rule: if an event type doesn't carry a field (e.g.
org.created has no branch), that filter is ignored for that event — the event passes.
- AND logic: all specified filters must match for the event to deliver.
paths matching: prefix match to start (src/api/ matches src/api/handler.go); glob can be added later.
branch and author: exact string match.
Example Subscription
Alert when anyone touches src/payments/ or internal/billing/ on the main branch:
{
"repo": "acme/platform",
"branch": "main",
"paths": ["src/payments/", "internal/billing/"],
"event_types": ["com.docstore.commit.created"],
"backend": "webhook",
"config": { "url": "https://hooks.example.com/billing-alert", "secret": "..." }
}
Implementation Notes
paths filtering requires commit.created events to carry the list of touched file paths — this means computing a tree diff at emit time (a store query per commit). This is the main cost. Consider only computing the diff if at least one active subscription for the repo has a paths filter set.
- Branch/author/base_branch/check_name filters are cheap string comparisons against the existing event payload fields.
- Schema: add
branch, base_branch, author, paths (text[]), check_name columns to event_subscriptions table; all nullable.
- Filter evaluation lives in the outbox worker (before HTTP delivery) or at emission time — at-emission is more efficient for high-volume repos.
- Auth model is unchanged: existing rules for who can create/manage subscriptions apply.
Out of Scope (for now)
- Pattern/glob matching for
branch or author
- Per-event-type filter blocks
- Negation filters
Overview
Currently webhook subscriptions support two filters:
repoandevent_types. This issue proposes a richer, flat filter model that lets subscribers watch for very specific changes without having to filter on the receiver side.Motivation
Primary use case: get alerted any time a path or set of paths changes on a specific branch. More generally, subscribers need to express routing logic that today requires post-delivery filtering in their own code.
Proposed Filter Fields
All filters are optional. A filter field is only evaluated when the event carries that field — if the event type doesn't have that field, the filter passes.
repostringevent_types[]stringbranchstringcommit.created,branch.*,proposal.*,check.reportedbase_branchstringproposal.*,branch.merged,branch.rebasedauthorstringcommit.created,proposal.*,review.submitted,role.changedpaths[]stringcommit.created— prefix match; event delivers if ANY touched file matches ANY prefixcheck_namestringcheck.reportedSemantics
org.createdhas nobranch), that filter is ignored for that event — the event passes.pathsmatching: prefix match to start (src/api/matchessrc/api/handler.go); glob can be added later.branchandauthor: exact string match.Example Subscription
Alert when anyone touches
src/payments/orinternal/billing/on themainbranch:{ "repo": "acme/platform", "branch": "main", "paths": ["src/payments/", "internal/billing/"], "event_types": ["com.docstore.commit.created"], "backend": "webhook", "config": { "url": "https://hooks.example.com/billing-alert", "secret": "..." } }Implementation Notes
pathsfiltering requirescommit.createdevents to carry the list of touched file paths — this means computing a tree diff at emit time (a store query per commit). This is the main cost. Consider only computing the diff if at least one active subscription for the repo has apathsfilter set.branch,base_branch,author,paths(text[]),check_namecolumns toevent_subscriptionstable; all nullable.Out of Scope (for now)
branchorauthor