过滤器教程
过滤器决定哪些 Webhook 事件会被路由转发。只有当路由 filters 数组中的每一个过滤器都匹配时,路由才会触发(AND 逻辑)。本页是一份上手教程:解释每种过滤器类型的行为,以及如何组合它们实现真实场景的路由规则。
匹配机制
- 路由中所有过滤器都必须匹配,否则该路由被跳过。
- 每个过滤器将事件与 Webhook 载荷的某个字段进行匹配。
- 所有过滤器类型都不区分大小写。
match值可以是单个字符串,也可以是字符串数组。数组相当于 OR——只要其中一个值匹配,该过滤器即匹配。- 设置
"exclude": true会反转结果(NOT 逻辑):当值不匹配时,该过滤器才匹配。
{
"type": "event",
"match": ["push", "pull_request"],
"exclude": false
}上面这条路由同时匹配 push 和 pull_request 事件。
模式语法
所有过滤器类型共享以下三种模式写法:
| 模式 | 含义 |
|---|---|
纯文本 | 字段过滤器:完全相等匹配;keyword:在载荷中任意位置搜索。 |
* / ? | 通配符(glob)——* 任意长度、? 恰好一个字符。 |
/正则表达式/ | 按正则表达式编译(忽略大小写标志)。 |
- 字段过滤器(
event/repo/actor/action/branch)的纯文本与通配符匹配整个值;keyword则在载荷中任意位置搜索。 - 正则表达式始终是搜索语义:
/^feat/匹配以feat开头的值,/feat/匹配任意位置出现feat的值。
示例:
{ "type": "event", "match": "pull_*" }匹配 pull_request、pull_request_review、pull_request_review_comment 等。
{ "type": "repo", "match": "myorg/*" }{ "type": "branch", "match": "feature-?" }匹配 feature-x、feature-1,但不匹配 feature-xy。
{ "type": "branch", "match": "/^feat/" }匹配任何以 feat 开头的分支名。
TIP
通配符和正则同样不区分大小写,且 * 可以跨过仓库名中的 /(myorg/* 也能匹配 myorg/sub/backend)。
各过滤器类型详解
event — 事件类型
匹配 GitHub 事件名称,如 push、pull_request、issues、release。它是每条路由的主干。
{ "type": "event", "match": "release" }用数组匹配多种事件:
{ "type": "event", "match": ["create", "delete"] }repo — 仓库
匹配仓库全名(owner/name)。不区分大小写。
{ "type": "repo", "match": "myorg/backend" }将多个仓库路由到同一频道:
{ "type": "repo", "match": ["myorg/backend", "myorg/frontend"] }actor — 发送者
匹配触发事件的 GitHub 发送者登录名(载荷中的 sender.login)。常用于忽略机器人。
{ "type": "actor", "match": "dependabot[bot]", "exclude": true }上面这条路由对除 Dependabot 触发之外的所有事件都会触发。
action — 事件操作
匹配载荷中的 action 字段,如 opened、closed、published、completed。并非所有事件都带有 action——参见过滤器兼容性。与 event 组合可精确到某个生命周期步骤:
{
"type": "event",
"match": "pull_request",
"exclude": false
},
{
"type": "action",
"match": ["opened", "reopened"]
}上面的规则在拉取请求被打开或重新打开时触发(合并/关闭/编辑时不触发)。
branch — 分支
匹配事件涉及的分支。何种字段算作「分支」取决于事件类型:
| 事件 | 提取的分支 |
|---|---|
push | 推送到的目标分支 |
pull_request(及 review) | 拉取请求的 head(源)分支 |
create / delete | 创建/删除的分支或标签 |
workflow_run | 工作流运行所在的 head_branch |
workflow_job | 作业运行所在的 head_branch |
check_suite | 检查套件的 head_branch |
deployment | 部署引用(去除 refs/heads/ 前缀) |
code_scanning_alert | 告警所属的分支 |
{
"type": "event",
"match": "push"
},
{
"type": "branch",
"match": "main"
}仅当推送到 main 时触发。要关注多个长期分支:
{ "type": "branch", "match": ["main", "develop"] }NOTE
branch 匹配不区分大小写。需要前缀或通配符式匹配时,可直接使用通配符(feature/*)或用 / 包裹正则(/^release-/)。
keyword — 载荷中的文本
匹配整个 JSON 载荷(转为小写)。它是最灵活的过滤器:纯文本在任意位置搜索,*/? 通配符带通配搜索,// 包裹的模式按正则表达式编译(带 i 标志)。
{ "type": "keyword", "match": "deploy" }当载荷中任意位置包含 deploy 时触发。由于载荷已被转为小写,Deploy、DEPLOY 等都会匹配。
{ "type": "keyword", "match": "*release-*" }{ "type": "keyword", "match": "/^(fix|hotfix)/" }{ "type": "keyword", "match": "/release-[0-9]+/" }行为细节:
- 超过 200 个字符的模式不编译为通配符/正则,回退为纯文本匹配。
- 被
/包裹但不是合法正则的模式匹配任何内容都不命中(过滤器恒为 false),而不会报错。 - 要搜索是通配符或正则特殊字符的文本(如
v1.2.3),使用纯文本形式即可——不含*、?且未被//包裹的模式按字面匹配。 - 搜索覆盖整个载荷:提交信息、PR 标题与正文、标签、引用,甚至仓库名和发送者名。
keyword 与 exclude 组合
与其他过滤器一样,exclude 会反转关键词匹配:
{ "type": "keyword", "match": "/wip|draft/", "exclude": true }跳过载荷中提及 wip 或 draft 的事件。
示例 1:PR 通知,跳过机器人和草稿
转发拉取请求动态,但忽略机器人作者和草稿 PR,发往 #prs 频道:
{
"id": "pr-notices",
"name": "PR Notices",
"enabled": true,
"groupId": "eng",
"filters": [
{ "type": "event", "match": "pull_request" },
{ "type": "actor", "match": "dependabot[bot]", "exclude": true },
{ "type": "keyword", "match": "\"draft\": true", "exclude": true }
],
"target": { "channelId": "111111111111111111" }
}"draft": true 模式匹配 GitHub 在拉取请求载荷中包含的 draft 字段;配合 exclude: true 即可过滤掉草稿 PR。
示例 2:仅发布通知频道
只转发特定仓库的已发布 release:
{
"id": "release-alerts",
"name": "Release Alerts",
"enabled": true,
"groupId": "eng",
"filters": [
{ "type": "event", "match": "release" },
{ "type": "action", "match": "published" },
{ "type": "repo", "match": "myorg/backend" }
],
"target": { "channelId": "222222222222222222" }
}示例 3:CI 失败
转发任意分支上以失败结束的 workflow run,发往 #ci 频道:
{
"id": "ci-failures",
"name": "CI Failures",
"enabled": true,
"groupId": "eng",
"filters": [
{ "type": "event", "match": "workflow_run" },
{ "type": "action", "match": "completed" },
{ "type": "keyword", "match": "\"conclusion\":\"failure\"" }
],
"target": { "channelId": "333333333333333333" }
}常见陷阱
- 通配符是 glob,不是正则。
repo: "myorg/*"匹配myorg下的任意仓库(含myorg/sub/backend),但repo: "myorg/.*"按字面匹配。需要正则请用/包裹:"/myorg\/.*/"。 - 被
/包裹的非法正则永远不匹配。 与纯文本不同——未包裹的非法模式按字面匹配。只有确定是真正的正则时才使用//包裹。 action过滤器遇到无 action 的事件永远不匹配。 先确认该事件带有action字段(见过滤器兼容性)。branch过滤器遇到无分支的事件永远不匹配。 在issues事件上使用branch过滤器恒为假。此时需要类似分支的匹配可用keyword。keyword会搜索一切。 因为它扫描整个载荷,"fix"这样的模式可能同时匹配提交信息、issue 标题和仓库名。请尽量写得更具体。- 牢记
exclude语义。exclude: true反转的是整个过滤器——数组中的一个值不匹配并不会「阻断」路由;只有当所有值都不匹配时,取反后的过滤器才匹配。