114 lines
4.1 KiB
Python
114 lines
4.1 KiB
Python
from pr import models
|
|
from django.views import View
|
|
from django.http import JsonResponse
|
|
|
|
from utils.pr_agent import cli
|
|
from utils.pr_agent.config_loader import get_settings
|
|
from utils import constant
|
|
|
|
|
|
def load_project_config(
|
|
git_url,
|
|
access_token,
|
|
project_secret,
|
|
openai_api_base,
|
|
openai_key,
|
|
llm_model
|
|
):
|
|
"""
|
|
加载项目配置
|
|
:param git_url: git服务器地址
|
|
:param access_token: 用户访问密钥
|
|
:param project_secret: 项目秘钥
|
|
:param openai_api_base: openai api base
|
|
:param openai_key: openai key
|
|
:param llm_model: llm model
|
|
:return:
|
|
"""
|
|
|
|
return {
|
|
"gitlab_url": git_url,
|
|
"access_token": access_token,
|
|
"secret": project_secret,
|
|
"openai_api_base": openai_api_base,
|
|
"openai_key": openai_key,
|
|
"llm_model": llm_model
|
|
}
|
|
|
|
|
|
class WebHookView(View):
|
|
def post(self, request):
|
|
data = request.POST
|
|
if not data:
|
|
return JsonResponse(status=400, data={"error": "Invalid JSON"})
|
|
|
|
project_id = data.get('project', {}).get('id') or data.get('project_id')
|
|
if not project_id:
|
|
return JsonResponse(status=400, data={"error": "Missing project ID"})
|
|
|
|
project_config = models.ProjectConfig.objects.filter(project_id=project_id).first()
|
|
# AI模型配置
|
|
api_base = project_config.git_config.pr_ai.api_base
|
|
api_key = project_config.git_config.pr_ai.api_key
|
|
model = project_config.git_config.pr_ai.llm_model
|
|
# Git服务器配置
|
|
git_url = project_config.git_config.git_url
|
|
git_type = constant.GIT_TYPE[project_config.git_config.git_type][1]
|
|
access_token = project_config.git_config.access_token
|
|
project_secret = project_config.project_secret
|
|
project_commands = project_config.commands
|
|
|
|
config = load_project_config(
|
|
git_url=git_url,
|
|
access_token=access_token,
|
|
project_secret=project_secret,
|
|
openai_api_base=api_base,
|
|
openai_key=api_key,
|
|
llm_model=model
|
|
)
|
|
token = request.headers.get('X-Gitlab-Token')
|
|
if token:
|
|
token = token.strip()
|
|
expected_token = config["secret"].strip() if config["secret"] else None
|
|
if token != expected_token:
|
|
return JsonResponse(status=403, data={"error": "Invalid token"})
|
|
|
|
# 处理Merge Request事件
|
|
if data.get('object_kind') == 'merge_request':
|
|
merge_request = data.get('object_attributes', {})
|
|
if merge_request.get('state') == 'opened':
|
|
# 获取Merge Request的详细信息
|
|
mr_url = merge_request.get('url')
|
|
mr_action = merge_request.get('action')
|
|
get_settings().set("config.git_provider", git_type)
|
|
get_settings().set("gitlab.url", git_url)
|
|
get_settings().set("gitlab.personal_access_token", access_token)
|
|
get_settings().set("openai.api_base", api_base)
|
|
get_settings().set("openai.key", api_key)
|
|
get_settings().set("llm.model", model)
|
|
|
|
if mr_action == "update":
|
|
old_rev = merge_request.get("oldrev")
|
|
new_rev = merge_request.get("newrev")
|
|
if old_rev == new_rev:
|
|
return JsonResponse(status=200, data={"status": "ignored (no code change)"})
|
|
|
|
import threading
|
|
|
|
def run_cmd(command):
|
|
cli.run_command(mr_url, command)
|
|
|
|
threads = []
|
|
for cmd in project_commands:
|
|
if cmd not in constant.DEFAULT_COMMANDS:
|
|
continue
|
|
t = threading.Thread(target=run_cmd, args=(cmd,))
|
|
threads.append(t)
|
|
t.start()
|
|
# 记录MR信息
|
|
return JsonResponse(status=200, data={"status": "review started"})
|
|
return JsonResponse(status=400, data={"error": "Merge request URL not found or action not open"})
|
|
return JsonResponse(status=200, data={"status": "ignored"})
|
|
|
|
|