From acdb9a3c4a23b95683b54a9e5dea2d8bb7098c76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=BB=BA=E5=B9=B3?= Date: Tue, 4 Mar 2025 17:25:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0Gitea=E6=94=AF=E6=8C=81?= =?UTF-8?q?=EF=BC=8C=E9=9D=9E=E5=B8=B8=E4=BC=98=E7=A7=80=EF=BC=8C=E7=AE=80?= =?UTF-8?q?=E7=9B=B4=E5=A4=AA=E5=AE=8C=E7=BE=8E=E4=BA=86=EF=BC=81=E4=BC=9F?= =?UTF-8?q?=E5=A4=A7=E7=9A=84=E6=9B=B4=E6=96=B0=EF=BC=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/pr/views.py | 18 ++++-- apps/utils/git_config.py | 134 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 145 insertions(+), 7 deletions(-) diff --git a/apps/pr/views.py b/apps/pr/views.py index 62f70fe..8adfec8 100644 --- a/apps/pr/views.py +++ b/apps/pr/views.py @@ -2,7 +2,7 @@ import json from django.views import View from django.http import JsonResponse -from utils.git_config import GitLabProvider +from utils.git_config import GitLabProvider, GiteaProvider from utils import constant @@ -40,6 +40,8 @@ class WebHookView(View): """ if git_type == "gitlab": return GitLabProvider() + elif git_type == "gitea": + return GiteaProvider() else: return GitLabProvider() @@ -86,9 +88,15 @@ class WebHookView(View): ) # 记录请求日志: 目前仅记录合并日志 - if json_data.get('object_kind') == 'merge_request': - provider.save_pr_agent_log( - request_data=json_data, project_id=project_config.get("project_id") - ) + if GIT_TYPE == "gitlab": + if json_data.get('object_kind') == 'merge_request': + provider.save_pr_agent_log( + request_data=json_data, project_id=project_config.get("project_id") + ) + elif GIT_TYPE == "gitea": + if json_data.get("action") == "opened": + provider.save_pr_agent_log( + request_data=json_data, project_id=project_config.get("project_id") + ) return JsonResponse(status=200, data={"status": "ignored"}) diff --git a/apps/utils/git_config.py b/apps/utils/git_config.py index ffeb240..0101b3e 100644 --- a/apps/utils/git_config.py +++ b/apps/utils/git_config.py @@ -63,9 +63,8 @@ class GitLabProvider(GitProvider): :param project_id: :return: """ - # TODO: 项目配置需要根据id以及git服务器配置 project_config = models.ProjectConfig.objects.filter( - project_id=project_id + project_id=project_id, git_config__git_type=0 ).first() git_config = project_config.git_config # Gitlab if not project_config: @@ -171,3 +170,134 @@ class GitLabProvider(GitProvider): t = Thread(target=cli.run_command, args=(mr_url, cmd)) threads.append(t) t.start() + + +class GiteaProvider(GitProvider): + @staticmethod + def check_secret(request_headers, project_secret, git_type): + """ + 检查密钥 + :param git_type: + :param request_headers: + :param project_secret: + :return: + """ + token = request_headers.get("Authorization") + if token != project_secret: + return JsonResponse(status=403, data={"error": "Invalid token"}) + + @staticmethod + def get_project_id(request_json, git_type): + """ + 获取项目ID + :param git_type: + :param request_json: + :return: + """ + return request_json.get("repository", {}).get("id") + + def get_project_config(self, project_id, git_type): + """ + 实现Gitea项目配置获取逻辑 + :param git_type: + :param project_id: + :return: + """ + project_config = models.ProjectConfig.objects.filter( + project_id=project_id, git_config__git_type=2 + ).first() + git_config = project_config.git_config # Gitea + if not project_config: + return JsonResponse(status=400, data={"error": "Project not found"}) + if not project_config.is_enable: + return JsonResponse(status=400, data={"error": "Project is disabled"}) + + return { + "api_base": git_config.pr_ai.api_base, + "api_key": git_config.pr_ai.api_key, + "llm_model": git_config.pr_ai.llm_model, + "git_url": git_config.git_url, + "git_type": "gitea", + "access_token": git_config.access_token, + "project_secret": project_config.project_secret, + "commands": project_config.commands.split(","), + "project_id": project_config.id, + } + + def get_merge_request( + self, + request_data, + git_url, + access_token, + api_base, + api_key, + llm_model, + project_commands, + ): + """ + 实现GitLab Merge Request获取逻辑 + :param project_commands: + :param llm_model: + :param api_key: + :param api_base: + :param access_token: + :param git_url: + :param request_data: + :return: + """ + if request_data.get("action") == "opened": + merge_request = request_data.get('pull_request', {}) + mr_url = merge_request.get("url") + get_settings().set("config.git_provider", "gitea") + 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", llm_model) + self.run_command(mr_url, project_commands) + # 数据库留存 + return JsonResponse(status=200, data={"status": "review started"}) + return JsonResponse( + status=400, + data={"error": "Merge request URL not found or action not open"}, + ) + + @staticmethod + def save_pr_agent_log(request_data, project_id): + """ + 记录pr agent日志 + :param request_data: + :param project_id: + :return: + """ + if request_data.get('pull_request', {}).get( + "head" + ) and request_data.get('pull_request', {}).get("base"): + models.ProjectHistory.objects.create( + project_id=project_id, + project_url=request_data.get("repository", {}).get("html_url"), + mr_url=request_data.get('pull_request', {}).get("url"), + source_branch=request_data.get('pull_request', {}).get( + "head" + ).get("label"), + target_branch=request_data.get('pull_request', {}).get( + "base" + ).get("label"), + mr_title=request_data.get('pull_request', {}).get("title"), + source_data=request_data, + ) + + def run_command(self, mr_url, project_commands): + """ + 自定义指令 + :param mr_url: + :param project_commands: + :return: + """ + threads = [] + for cmd in project_commands: + if cmd not in [cmd[1] for cmd in constant.DEFAULT_COMMANDS]: + continue + t = Thread(target=cli.run_command, args=(mr_url, cmd)) + threads.append(t) + t.start() \ No newline at end of file