This commit is contained in:
Dang Zerong
2026-03-10 11:18:39 +08:00
parent 31e3b7b497
commit 8594cf4d77
4 changed files with 208 additions and 14 deletions

96
app.py
View File

@@ -3,6 +3,7 @@
import os
import logging
from typing import Dict, Tuple, Any
os.environ.setdefault('FLASK_RUN_HOST', '0.0.0.0')
@@ -79,7 +80,11 @@ def handle_gitea_webhook():
event_type = request.headers.get('X-Gitea-Event', 'push')
logger.info(f'收到 Gitea Webhook 事件: {event_type}')
# 处理 push 事件
# 处理 Pull Request 事件
if event_type == 'pull_request':
return handle_pull_request(payload)
# 处理 Push 事件
if event_type != 'push':
return jsonify({'message': 'Event ignored'}), 200
@@ -161,6 +166,95 @@ def handle_gitea_webhook():
return jsonify({'error': str(e)}), 500
def handle_pull_request(payload: Dict[str, Any]) -> Tuple[Dict, int]:
"""
处理 Pull Request 事件
Args:
payload: Webhook payload
Returns:
JSON 响应和状态码
"""
try:
# 解析 PR 事件
pr_info = webhook_handler.parse_pull_request_event(payload)
if not pr_info:
logger.info('PR 事件不需要处理(如关闭、合并等)')
return jsonify({'message': 'PR event ignored'}), 200
repo_name = pr_info['repo_name']
source_branch = pr_info['source_branch']
source_sha = pr_info['source_sha']
pr_number = pr_info['pr_number']
pr_title = pr_info['pr_title']
pr_url = pr_info['pr_url']
target_branch = pr_info['target_branch']
author = pr_info['author']
logger.info(f'处理 PR #{pr_number}: {pr_title} ({source_branch} -> {target_branch})')
logger.info(f'扫描 PR 分支: {source_branch}, commit: {source_sha}')
try:
# 获取仓库 URL
repo = payload.get('repository', {})
clone_url = repo.get('clone_url')
if not clone_url:
web_url = repo.get('web_url', '')
if web_url:
clone_url = web_url.rstrip('/') + '.git'
# 执行代码扫描
scan_results = {}
# Python 扫描
if 'python' in config.get('scanner', {}).get('languages', []):
scan_results['python'] = python_scanner.scan(
clone_url, source_sha, source_branch
)
# JavaScript/TypeScript 扫描
if any(lang in config.get('scanner', {}).get('languages', [])
for lang in ['javascript', 'typescript']):
scan_results['javascript'] = js_scanner.scan(
clone_url, source_sha, source_branch
)
# 安全扫描
scan_results['security'] = security_scanner.scan(
clone_url, source_sha, source_branch
)
# 生成报告
commit_message = f'PR #{pr_number}: {pr_title}'
report = report_generator.generate(
repo_name=repo_name,
branch=source_branch,
commit_id=source_sha,
commit_message=commit_message,
author=author,
scan_results=scan_results,
pr_url=pr_url,
target_branch=target_branch
)
# 发送飞书通知
feishu_notifier.send_report(report)
logger.info(f'PR #{pr_number} 扫描完成')
except Exception as e:
logger.error(f'扫描 PR #{pr_number} 失败: {str(e)}')
return jsonify({'error': str(e)}), 500
return jsonify({'status': 'ok', 'message': 'PR scan completed'}), 200
except Exception as e:
logger.error(f'处理 PR Webhook 失败: {str(e)}', exc_info=True)
return jsonify({'error': str(e)}), 500
@app.route('/scan/manual', methods=['POST'])
def manual_scan():
"""手动触发扫描接口"""