feat: add AI-powered issue triage to QQ notification workflow
This commit is contained in:
parent
c9f584d350
commit
f2efed99fe
|
|
@ -21,6 +21,7 @@ jobs:
|
|||
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||
ISSUE_URL: ${{ github.event.issue.html_url }}
|
||||
ISSUE_USER: ${{ github.event.issue.user.login }}
|
||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||
PR_TITLE: ${{ github.event.pull_request.title }}
|
||||
PR_URL: ${{ github.event.pull_request.html_url }}
|
||||
PR_USER: ${{ github.event.pull_request.user.login }}
|
||||
|
|
@ -42,6 +43,8 @@ jobs:
|
|||
title = os.environ["ISSUE_TITLE"]
|
||||
url = os.environ["ISSUE_URL"]
|
||||
user = os.environ["ISSUE_USER"]
|
||||
issue_body = (os.environ.get("ISSUE_BODY") or "").strip()
|
||||
summary = f"\n\n内容: {issue_body[:300]}" if issue_body else ""
|
||||
msg = "\n".join([
|
||||
"━━━━━━━━━━━━━━━",
|
||||
"📋 新 Issue",
|
||||
|
|
@ -49,6 +52,7 @@ jobs:
|
|||
f"标题: {title}",
|
||||
f"提交者: {user}",
|
||||
f"链接: {url}",
|
||||
f"{summary}",
|
||||
"━━━━━━━━━━━━━━━",
|
||||
])
|
||||
|
||||
|
|
@ -113,6 +117,65 @@ jobs:
|
|||
f.write(f"skip=true\n")
|
||||
PYEOF
|
||||
|
||||
- name: AI Analysis for Issue
|
||||
id: ai
|
||||
if: ${{ github.event_name == 'issues' && steps.msg.outputs.skip != 'true' }}
|
||||
env:
|
||||
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||
ISSUE_USER: ${{ github.event.issue.user.login }}
|
||||
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
|
||||
run: |
|
||||
python3 - <<'PYEOF'
|
||||
import os, json, urllib.request
|
||||
|
||||
title = os.environ["ISSUE_TITLE"]
|
||||
body = (os.environ.get("ISSUE_BODY") or "(无描述)")[:800]
|
||||
user = os.environ.get("ISSUE_USER", "unknown")
|
||||
api_key = os.environ.get("DEEPSEEK_API_KEY", "")
|
||||
|
||||
if not api_key:
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
||||
f.write("analysis=\n")
|
||||
exit(0)
|
||||
|
||||
prompt = f"""分析这个 GitHub Issue,用中文回复。格式要求(严格遵守,不要多余内容):
|
||||
|
||||
合理性: [一句话判断,有效问题/重复报告/信息不足/不是bug]
|
||||
优先级: [P0紧急/P1重要/P2普通/P3低优]
|
||||
总结: [一句话概括核心问题]
|
||||
建议: [一句话给出处理建议或关联方向]
|
||||
|
||||
---
|
||||
标题: {title}
|
||||
提交者: {user}
|
||||
内容: {body}"""
|
||||
|
||||
req = urllib.request.Request(
|
||||
"https://api.deepseek.com/v1/chat/completions",
|
||||
data=json.dumps({
|
||||
"model": "deepseek-chat",
|
||||
"max_tokens": 300,
|
||||
"messages": [{"role": "user", "content": prompt}],
|
||||
}).encode(),
|
||||
headers={
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
)
|
||||
|
||||
try:
|
||||
resp = urllib.request.urlopen(req, timeout=20)
|
||||
data = json.loads(resp.read())
|
||||
text = data["choices"][0]["message"]["content"]
|
||||
except Exception as e:
|
||||
text = f"(AI 分析暂时不可用: {e})"
|
||||
|
||||
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
||||
delim = "EOF_ANALYSIS"
|
||||
f.write(f"analysis<<{delim}\n{text}\n{delim}\n")
|
||||
PYEOF
|
||||
|
||||
- name: Send to QQ group
|
||||
if: steps.msg.outputs.skip != 'true'
|
||||
env:
|
||||
|
|
@ -120,12 +183,20 @@ jobs:
|
|||
HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
ASTRBOT_API_KEY: ${{ secrets.ASTRBOT_API_KEY }}
|
||||
MSG_CONTENT: ${{ steps.msg.outputs.msg }}
|
||||
AI_ANALYSIS: ${{ steps.ai.outputs.analysis }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
echo "$SSH_KEY" > ~/.ssh/id_ed25519
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
ssh-keyscan -H "$HOST" >> ~/.ssh/known_hosts 2>/dev/null
|
||||
|
||||
if [ -n "$AI_ANALYSIS" ]; then
|
||||
MSG_CONTENT="${MSG_CONTENT}
|
||||
|
||||
🤖 AI 分析:
|
||||
${AI_ANALYSIS}"
|
||||
fi
|
||||
|
||||
MSG=$(echo "$MSG_CONTENT" | jq -Rs .)
|
||||
ssh "root@${HOST}" "curl -s -X POST http://localhost:6185/api/v1/im/message \
|
||||
-H 'Authorization: Bearer ${ASTRBOT_API_KEY}' \
|
||||
|
|
|
|||
Loading…
Reference in New Issue