From 1654bbf6125cbd688c270e3682b87faa2de518bf Mon Sep 17 00:00:00 2001 From: baozaotumao Date: Sat, 6 Jun 2026 08:07:04 -0700 Subject: [PATCH] feat: add AI code review workflow and skills --- .claude/skills/code-review-skill | 1 + .gitea/workflows/ai-review.yml | 92 ++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 160000 .claude/skills/code-review-skill create mode 100644 .gitea/workflows/ai-review.yml diff --git a/.claude/skills/code-review-skill b/.claude/skills/code-review-skill new file mode 160000 index 0000000..17267ff --- /dev/null +++ b/.claude/skills/code-review-skill @@ -0,0 +1 @@ +Subproject commit 17267ff26b95dcea28c3dae76f9931cdf9604520 diff --git a/.gitea/workflows/ai-review.yml b/.gitea/workflows/ai-review.yml new file mode 100644 index 0000000..d9e03db --- /dev/null +++ b/.gitea/workflows/ai-review.yml @@ -0,0 +1,92 @@ +name: "AI Code Review" + +# 当有人发起 Pull Request (PR) 或者向 PR 提交新代码时,触发此工作流 +on: + pull_request: + types: [opened, synchronize] + +jobs: + review_with_skill: + runs-on: ubuntu-latest + steps: + # 1. 把你仓库里的代码(包括 .claude 里的规则文件)下载到运行服务器上 + - name: Checkout Code & Skills + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # 2. 运行 AI 审查脚本 + - name: Run Review Engine + env: + # 引入我们在第二步配置的 API Key + API_KEY: ${{ secrets.LLM_API_KEY }} + # Gitea 自动生成的 Token,用于给机器人发评论权限,无需手动配置 + GITEA_TOKEN: ${{ gitea.token }} + # 传递 Gitea 的相关环境变量给 Python 脚本 + GITEA_SERVER_URL: ${{ gitea.server_url }} + GITEA_REPOSITORY: ${{ gitea.repository }} + GITEA_PR_NUMBER: ${{ gitea.event.number }} + GITEA_BASE_REF: ${{ gitea.base_ref }} + GITEA_HEAD_REF: ${{ gitea.head_ref }} + run: | + # 提取当前 PR 的代码变动并保存到 diff.txt + git diff origin/$GITEA_BASE_REF...origin/$GITEA_HEAD_REF > diff.txt + + # 使用 Python 执行审查 + python3 -c " + import os, json, urllib.request, urllib.error + + # 1. 读取你提交的 Skill 规则书 + skill_base_path = '.claude/skills/code-review-skill/' + try: + skill_config = open(os.path.join(skill_base_path, 'SKILL.md')).read() + python_rules = open(os.path.join(skill_base_path, 'reference/python.md')).read() + except FileNotFoundError as e: + print(f'未找到规则文件: {e}'); exit(1) + + # 组合成完整的 AI 提示词(System Prompt) + full_skill_prompt = f'{skill_config}\n\n以下是针对当前语言的补充规范:\n{python_rules}' + + # 读取代码变动 + diff_data = open('diff.txt').read() + if not diff_data.strip(): + print('没有检测到代码变更,跳过审查。'); exit(0) + + # 2. 呼叫大模型 (这里以 DeepSeek 为例,已修正为官方标准 API 接口) + api_url = 'https://api.deepseek.com/v1/chat/completions' + headers = { + 'Authorization': f'Bearer {os.getenv(\"API_KEY\")}', + 'Content-Type': 'application/json' + } + payload = { + 'model': 'deepseek-chat', # 或者使用 deepseek-coder + 'messages': [ + {'role': 'system', 'content': full_skill_prompt}, + {'role': 'user', 'content': f'请严格对照上述 Skill 规范,评审以下 FastAPI 代码改动,并用中文输出评审意见:\n\n{diff_data}'} + ], + 'temperature': 0.2 + } + + req = urllib.request.Request(api_url, data=json.dumps(payload).encode('utf-8'), headers=headers, method='POST') + try: + with urllib.request.urlopen(req) as response: + res = json.loads(response.read().decode('utf-8')) + comment_body = res['choices'][0]['message']['content'] + except Exception as e: + print(f'请求大模型失败: {e}'); exit(1) + + # 3. 将 AI 审查意见发表到 Gitea 的 Pull Request 评论区 + gitea_url = f'{os.getenv(\"GITEA_SERVER_URL\")}/api/v1/repos/{os.getenv(\"GITEA_REPOSITORY\")}/issues/{os.getenv(\"GITEA_PR_NUMBER\")}/comments' + gitea_headers = { + 'Authorization': f'token {os.getenv(\"GITEA_TOKEN\")}', + 'Content-Type': 'application/json' + } + gitea_payload = {'body': f'### 🤖 AI 自动化审查报告 (基于 Code Review Skill)\n\n{comment_body}'} + + gitea_req = urllib.request.Request(gitea_url, data=json.dumps(gitea_payload).encode('utf-8'), headers=gitea_headers, method='POST') + try: + urllib.request.urlopen(gitea_req) + print('Skill 审查报告已成功发表!') + except Exception as e: + print(f'发表评论失败: {e}'); exit(1) + "