Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
- **安全验证**:支持 Webhook 签名验证,确保请求安全性
- **OneBot 协议支持**:通过 OneBot 协议将推送信息转发到指定的 QQ 群或私聊
- **灵活配置**:可配置监听的仓库、分支和事件类型
- **高级仓库匹配**:
- 支持大小写不敏感的仓库名匹配
- 支持 `用户名/*` 通配符匹配用户的所有仓库
- **高级匹配规则**:
- **仓库匹配**:支持通配符模式(如 `user/*`、`*/*-api`、`org/[abc]*` 等)
- **分支匹配**:支持通配符模式(如 `main`、`release-*`、`feature/*` 等)
- 大小写不敏感匹配
- **格式化消息**:结构化的推送通知,包含仓库、分支、推送者和最新提交信息

### 计划实现功能
Expand Down Expand Up @@ -101,12 +102,15 @@ ONEBOT_ACCESS_TOKEN: "your_token" # OneBot 访问令牌

GITHUB_WEBHOOK:
- NAME: "github" # webhook 名称
REPO: # 监听的仓库列表,支持用户名/* 匹配用户所有仓库
REPO: # 监听的仓库列表,支持通配符匹配
- "username/repo"
- "username/*"
BRANCH: # 监听的分支列表
- "*/*-api"
BRANCH: # 监听的分支列表,支持通配符匹配
- "main"
- "develop"
- "feature/*"
- "release-*"
SECRET: "your_secret" # GitHub Webhook 密钥
EVENTS: # 监听的事件类型
- "push"
Expand Down Expand Up @@ -272,7 +276,7 @@ GITHUB_API_POLLING:
## 项目结构

- app.py: 主应用入口和 Web 服务器
- github_webhook.py: GitHub Webhook 处理逻辑
- hooks/github_webhook.py: GitHub Webhook 处理逻辑
- send_message.py: OneBot 消息发送客户端
- settings.py: 配置加载和验证
- requirements.txt: 项目依赖
Expand Down
2 changes: 1 addition & 1 deletion docs/src/deployment.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 部署建议

### Docker 部署(计划支持)
### Docker 部署

```bash
docker run -d \
Expand Down
7 changes: 4 additions & 3 deletions docs/src/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
- **安全验证**:支持 Webhook 签名验证,确保请求安全性
- **OneBot 协议支持**:通过 OneBot 协议将推送信息转发到指定的 QQ 群或私聊
- **灵活配置**:可配置监听的仓库、分支和事件类型
- **高级仓库匹配**:
- 支持大小写不敏感的仓库名匹配
- 支持 `用户名/*` 通配符匹配用户的所有仓库
- **高级匹配规则**:
- **仓库匹配**:支持通配符模式(如 `user/*`、`*/*-api`、`org/[abc]*` 等)
- **分支匹配**:支持通配符模式(如 `main`、`release-*`、`feature/*` 等)
- 大小写不敏感匹配
- **格式化消息**:结构化的推送通知,包含仓库、分支、推送者和最新提交信息

### 计划实现功能
Expand Down
43 changes: 26 additions & 17 deletions hooks/github_webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,40 @@
import hmac
import hashlib
import logging
import fnmatch
from typing import Optional, Dict, Any, List

from fastapi import Request, HTTPException, Header

logger = logging.getLogger(__name__)

def match_repository(repo_name: str, pattern: str) -> bool:
def match_pattern(value: str, pattern: str) -> bool:
"""
检查仓库名是否匹配配置中的模式
支持大小写不敏感匹配和通配符(用户名/*)形式
检查字符串是否匹配配置中的模式
支持大小写不敏感匹配和通配符模式

Args:
repo_name: 实际的仓库全名 (例如 'user/repo')
pattern: 配置中的仓库模式 (例如 'user/repo' 或 'user/*')
value: 要匹配的字符串 (例如 'user/repo' 或 'main')
pattern: 配置中的模式 (例如 'user/*', 'feature/*')
treat_star_as_all: 是否将单独的 "*" 视为匹配所有内容(用于分支匹配)

Returns:
bool: 是否匹配
"""
if not repo_name or not pattern:
if not value or not pattern:
return False

repo_name = repo_name.lower()
value = value.lower()
pattern = pattern.lower()

if pattern.endswith('/*'):
user = pattern[:-2]
return repo_name.startswith(f"{user}/")
# 分支匹配特殊情况:单独的 "*" 匹配所有内容
if pattern == "*":
return True
Comment thread
AptS-1547 marked this conversation as resolved.

if '*' in pattern or '?' in pattern or '[' in pattern:
return fnmatch.fnmatch(value, pattern)

return repo_name == pattern
return value == pattern

async def verify_signature(
request: Request,
Expand All @@ -58,7 +63,7 @@ async def verify_signature(

webhook_secret = None
for webhook in webhooks:
if any(match_repository(repo_name, repo_pattern) for repo_pattern in webhook.REPO):
if any(match_pattern(repo_name, repo_pattern) for repo_pattern in webhook.REPO):
webhook_secret = webhook.SECRET
break

Expand Down Expand Up @@ -101,12 +106,16 @@ def find_matching_webhook(
匹配的 webhook 配置或 None
"""
for webhook in webhooks:
repo_matches = any(match_repository(repo_name, repo_pattern)
for repo_pattern in webhook.REPO)
# 检查仓库名是否匹配配置中的任一模式
repo_matches = any(match_pattern(repo_name, repo_pattern)
for repo_pattern in webhook.REPO)

# 检查分支名是否匹配配置中的任一模式
branch_matches = any(match_pattern(branch, branch_pattern)
for branch_pattern in webhook.BRANCH)

if (repo_matches and
branch in webhook.BRANCH and
event_type in webhook.EVENTS):
# 检查事件类型是否匹配
if (repo_matches and branch_matches and event_type in webhook.EVENTS):
return webhook

return None
Expand Down
12 changes: 6 additions & 6 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
aiohttp
fastapi
pydantic
pydantic-settings
pyyaml
uvicorn
aiohttp~=3.11.18
fastapi~=0.115.12
pydantic~=2.11.4
pydantic-settings~=2.9.1
pyyaml~=6.0.2
uvicorn~=0.34.2