|
11 | 11 | from flask import Flask, request, jsonify
|
12 | 12 |
|
13 | 13 | from biz.gitlab.webhook_handler import slugify_url
|
14 |
| -from biz.queue.worker import handle_merge_request_event, handle_push_event |
| 14 | +from biz.queue.worker import handle_merge_request_event, handle_push_event, handle_github_pull_request_event, handle_github_push_event |
15 | 15 | from biz.service.review_service import ReviewService
|
16 | 16 | from biz.utils.im import notifier
|
17 | 17 | from biz.utils.log import logger
|
@@ -108,56 +108,92 @@ def handle_webhook():
|
108 | 108 | if not data:
|
109 | 109 | return jsonify({"error": "Invalid JSON"}), 400
|
110 | 110 |
|
111 |
| - object_kind = data.get("object_kind") |
112 |
| - |
113 |
| - # 优先从请求头获取,如果没有,则从环境变量获取,如果没有,则从推送事件中获取 |
114 |
| - gitlab_url = os.getenv('GITLAB_URL') or request.headers.get('X-Gitlab-Instance') |
115 |
| - if not gitlab_url: |
116 |
| - repository = data.get('repository') |
117 |
| - if not repository: |
118 |
| - return jsonify({'message': 'Missing GitLab URL'}), 400 |
119 |
| - homepage = repository.get("homepage") |
120 |
| - if not homepage: |
121 |
| - return jsonify({'message': 'Missing GitLab URL'}), 400 |
122 |
| - try: |
123 |
| - parsed_url = urlparse(homepage) |
124 |
| - gitlab_url = f"{parsed_url.scheme}://{parsed_url.netloc}/" |
125 |
| - except Exception as e: |
126 |
| - return jsonify({"error": f"Failed to parse homepage URL: {str(e)}"}), 400 |
127 |
| - |
128 |
| - # 优先从环境变量获取,如果没有,则从请求头获取 |
129 |
| - gitlab_token = os.getenv('GITLAB_ACCESS_TOKEN') or request.headers.get('X-Gitlab-Token') |
130 |
| - # 如果gitlab_token为空,返回错误 |
131 |
| - if not gitlab_token: |
132 |
| - return jsonify({'message': 'Missing GitLab access token'}), 400 |
133 |
| - |
134 |
| - gitlab_url_slug = slugify_url(gitlab_url) |
135 |
| - |
136 |
| - # 打印整个payload数据,或根据需求进行处理 |
137 |
| - logger.info(f'Received event: {object_kind}') |
138 |
| - logger.info(f'Payload: {json.dumps(data)}') |
139 |
| - |
140 |
| - # 处理Merge Request Hook |
141 |
| - if object_kind == "merge_request": |
142 |
| - # 创建一个新进程进行异步处理 |
143 |
| - handle_queue(handle_merge_request_event, data, gitlab_token, gitlab_url, gitlab_url_slug) |
144 |
| - # 立马返回响应 |
145 |
| - return jsonify( |
146 |
| - {'message': f'Request received(object_kind={object_kind}), will process asynchronously.'}), 200 |
147 |
| - elif object_kind == "push": |
148 |
| - # 创建一个新进程进行异步处理 |
149 |
| - # TODO check if PUSH_REVIEW_ENABLED is needed here |
150 |
| - handle_queue(handle_push_event, data, gitlab_token, gitlab_url, gitlab_url_slug) |
151 |
| - # 立马返回响应 |
152 |
| - return jsonify( |
153 |
| - {'message': f'Request received(object_kind={object_kind}), will process asynchronously.'}), 200 |
154 |
| - else: |
155 |
| - error_message = f'Only merge_request and push events are supported (both Webhook and System Hook), but received: {object_kind}.' |
156 |
| - logger.error(error_message) |
157 |
| - return jsonify(error_message), 400 |
| 111 | + # 判断是GitLab还是GitHub的webhook |
| 112 | + webhook_source = request.headers.get('X-GitHub-Event') |
| 113 | + |
| 114 | + if webhook_source: # GitHub webhook |
| 115 | + return handle_github_webhook(webhook_source, data) |
| 116 | + else: # GitLab webhook |
| 117 | + return handle_gitlab_webhook(data) |
158 | 118 | else:
|
159 | 119 | return jsonify({'message': 'Invalid data format'}), 400
|
160 | 120 |
|
| 121 | +def handle_github_webhook(event_type, data): |
| 122 | + # 获取GitHub配置 |
| 123 | + github_token = os.getenv('GITHUB_ACCESS_TOKEN') or request.headers.get('X-GitHub-Token') |
| 124 | + if not github_token: |
| 125 | + return jsonify({'message': 'Missing GitHub access token'}), 400 |
| 126 | + |
| 127 | + github_url = os.getenv('GITHUB_URL') or 'https://github.com' |
| 128 | + github_url_slug = slugify_url(github_url) |
| 129 | + |
| 130 | + # 打印整个payload数据 |
| 131 | + logger.info(f'Received GitHub event: {event_type}') |
| 132 | + logger.info(f'Payload: {json.dumps(data)}') |
| 133 | + |
| 134 | + if event_type == "pull_request": |
| 135 | + # 使用handle_queue进行异步处理 |
| 136 | + handle_queue(handle_github_pull_request_event, data, github_token, github_url, github_url_slug) |
| 137 | + # 立马返回响应 |
| 138 | + return jsonify({'message': f'GitHub request received(event_type={event_type}), will process asynchronously.'}), 200 |
| 139 | + elif event_type == "push": |
| 140 | + # 使用handle_queue进行异步处理 |
| 141 | + handle_queue(handle_github_push_event, data, github_token, github_url, github_url_slug) |
| 142 | + # 立马返回响应 |
| 143 | + return jsonify({'message': f'GitHub request received(event_type={event_type}), will process asynchronously.'}), 200 |
| 144 | + else: |
| 145 | + error_message = f'Only pull_request and push events are supported for GitHub webhook, but received: {event_type}.' |
| 146 | + logger.error(error_message) |
| 147 | + return jsonify(error_message), 400 |
| 148 | + |
| 149 | +def handle_gitlab_webhook(data): |
| 150 | + object_kind = data.get("object_kind") |
| 151 | + |
| 152 | + # 优先从请求头获取,如果没有,则从环境变量获取,如果没有,则从推送事件中获取 |
| 153 | + gitlab_url = os.getenv('GITLAB_URL') or request.headers.get('X-Gitlab-Instance') |
| 154 | + if not gitlab_url: |
| 155 | + repository = data.get('repository') |
| 156 | + if not repository: |
| 157 | + return jsonify({'message': 'Missing GitLab URL'}), 400 |
| 158 | + homepage = repository.get("homepage") |
| 159 | + if not homepage: |
| 160 | + return jsonify({'message': 'Missing GitLab URL'}), 400 |
| 161 | + try: |
| 162 | + parsed_url = urlparse(homepage) |
| 163 | + gitlab_url = f"{parsed_url.scheme}://{parsed_url.netloc}/" |
| 164 | + except Exception as e: |
| 165 | + return jsonify({"error": f"Failed to parse homepage URL: {str(e)}"}), 400 |
| 166 | + |
| 167 | + # 优先从环境变量获取,如果没有,则从请求头获取 |
| 168 | + gitlab_token = os.getenv('GITLAB_ACCESS_TOKEN') or request.headers.get('X-Gitlab-Token') |
| 169 | + # 如果gitlab_token为空,返回错误 |
| 170 | + if not gitlab_token: |
| 171 | + return jsonify({'message': 'Missing GitLab access token'}), 400 |
| 172 | + |
| 173 | + gitlab_url_slug = slugify_url(gitlab_url) |
| 174 | + |
| 175 | + # 打印整个payload数据,或根据需求进行处理 |
| 176 | + logger.info(f'Received event: {object_kind}') |
| 177 | + logger.info(f'Payload: {json.dumps(data)}') |
| 178 | + |
| 179 | + # 处理Merge Request Hook |
| 180 | + if object_kind == "merge_request": |
| 181 | + # 创建一个新进程进行异步处理 |
| 182 | + handle_queue(handle_merge_request_event, data, gitlab_token, gitlab_url, gitlab_url_slug) |
| 183 | + # 立马返回响应 |
| 184 | + return jsonify( |
| 185 | + {'message': f'Request received(object_kind={object_kind}), will process asynchronously.'}), 200 |
| 186 | + elif object_kind == "push": |
| 187 | + # 创建一个新进程进行异步处理 |
| 188 | + # TODO check if PUSH_REVIEW_ENABLED is needed here |
| 189 | + handle_queue(handle_push_event, data, gitlab_token, gitlab_url, gitlab_url_slug) |
| 190 | + # 立马返回响应 |
| 191 | + return jsonify( |
| 192 | + {'message': f'Request received(object_kind={object_kind}), will process asynchronously.'}), 200 |
| 193 | + else: |
| 194 | + error_message = f'Only merge_request and push events are supported (both Webhook and System Hook), but received: {object_kind}.' |
| 195 | + logger.error(error_message) |
| 196 | + return jsonify(error_message), 400 |
161 | 197 |
|
162 | 198 | if __name__ == '__main__':
|
163 | 199 | # 启动定时任务调度器
|
|
0 commit comments