ci: 添加 AI Issue 智能分析和批量处理工具
This commit is contained in:
73
.github/workflows/ai-batch-analyze-issues.yml
vendored
Normal file
73
.github/workflows/ai-batch-analyze-issues.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
name: AI Batch Analyze Issues
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
mode:
|
||||||
|
description: '分析模式'
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- 'recent' # 最近 10 个 issue
|
||||||
|
- 'open' # 所有打开的 issue
|
||||||
|
- 'all' # 所有 issue(慎用)
|
||||||
|
default: 'recent'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
|
|
||||||
|
- name: Install GitHub CLI
|
||||||
|
run: |
|
||||||
|
gh --version || (curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
|
||||||
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install gh)
|
||||||
|
|
||||||
|
- name: Batch Analyze Issues
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
MODE="${{ github.event.inputs.mode }}"
|
||||||
|
|
||||||
|
# 获取 issue 列表
|
||||||
|
if [ "$MODE" = "recent" ]; then
|
||||||
|
echo "📊 分析最近 10 个 issue..."
|
||||||
|
ISSUES=$(gh issue list --limit 10 --json number --jq '.[].number')
|
||||||
|
elif [ "$MODE" = "open" ]; then
|
||||||
|
echo "📊 分析所有打开的 issue..."
|
||||||
|
ISSUES=$(gh issue list --state open --json number --jq '.[].number')
|
||||||
|
else
|
||||||
|
echo "📊 分析所有 issue(这可能需要很长时间)..."
|
||||||
|
ISSUES=$(gh issue list --state all --limit 100 --json number --jq '.[].number')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 为每个 issue 添加 AI 分析评论
|
||||||
|
for issue_num in $ISSUES; do
|
||||||
|
echo "🤖 分析 Issue #$issue_num..."
|
||||||
|
|
||||||
|
# 获取 issue 内容
|
||||||
|
ISSUE_BODY=$(gh issue view $issue_num --json body --jq '.body')
|
||||||
|
ISSUE_TITLE=$(gh issue view $issue_num --json title --jq '.title')
|
||||||
|
|
||||||
|
# 添加触发评论
|
||||||
|
gh issue comment $issue_num --body "@ai-helper 请帮我分析这个 issue" || true
|
||||||
|
|
||||||
|
# 避免 API 限制
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ 批量分析完成!"
|
||||||
|
echo "查看结果:https://github.com/${{ github.repository }}/issues"
|
||||||
50
.github/workflows/ai-issue-helper.yml
vendored
Normal file
50
.github/workflows/ai-issue-helper.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
name: AI Issue Helper
|
||||||
|
|
||||||
|
on:
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ai-helper:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
# 只在用户提到 @ai-helper 时触发
|
||||||
|
if: contains(github.event.comment.body, '@ai-helper')
|
||||||
|
steps:
|
||||||
|
- name: AI Assistance
|
||||||
|
uses: github/issue-assessment-action@v1
|
||||||
|
with:
|
||||||
|
assessments:
|
||||||
|
- name: help-request
|
||||||
|
prompt: |
|
||||||
|
用户在 issue 中提到了 @ai-helper,请分析他们的问题并提供帮助。
|
||||||
|
|
||||||
|
检查:
|
||||||
|
1. 用户遇到的具体问题
|
||||||
|
2. 可能的解决方案
|
||||||
|
3. 相关文档链接
|
||||||
|
4. 类似的已解决 issue
|
||||||
|
|
||||||
|
用中文友好地回复,提供:
|
||||||
|
- 问题分析
|
||||||
|
- 建议的解决方案(如果可以推断)
|
||||||
|
- 相关资源链接
|
||||||
|
- 需要提供的额外信息(如果需要)
|
||||||
|
|
||||||
|
格式:
|
||||||
|
👋 你好!我是 AI 助手,让我帮你分析这个问题。
|
||||||
|
|
||||||
|
【问题分析】
|
||||||
|
...
|
||||||
|
|
||||||
|
【建议方案】
|
||||||
|
...
|
||||||
|
|
||||||
|
【相关资源】
|
||||||
|
- 📚 文档:...
|
||||||
|
- 💡 示例:...
|
||||||
|
|
||||||
|
如果我的建议没有解决问题,请提供更多信息,维护者会尽快回复!
|
||||||
65
.github/workflows/ai-issue-moderator.yml
vendored
Normal file
65
.github/workflows/ai-issue-moderator.yml
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
name: AI Issue Moderator
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
issue_comment:
|
||||||
|
types: [created]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
issue_number:
|
||||||
|
description: 'Issue 编号(留空则检查所有打开的 issue)'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
moderate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Get issue number
|
||||||
|
id: issue
|
||||||
|
run: |
|
||||||
|
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||||
|
if [ -n "${{ github.event.inputs.issue_number }}" ]; then
|
||||||
|
echo "number=${{ github.event.inputs.issue_number }}" >> $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "number=all" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "number=${{ github.event.issue.number }}" >> $GITHUB_OUTPUT
|
||||||
|
fi
|
||||||
|
- name: AI Content Moderation
|
||||||
|
uses: github/content-moderation-action@v1
|
||||||
|
with:
|
||||||
|
# 检测垃圾内容
|
||||||
|
spam-detection: true
|
||||||
|
|
||||||
|
# 检测 AI 生成内容
|
||||||
|
ai-generated-detection: true
|
||||||
|
|
||||||
|
# 自定义提示
|
||||||
|
custom-prompt: |
|
||||||
|
分析这个 issue/评论是否包含:
|
||||||
|
1. 垃圾信息或广告
|
||||||
|
2. 纯 AI 生成的无意义内容
|
||||||
|
3. 恶意或攻击性内容
|
||||||
|
4. 与项目无关的内容
|
||||||
|
|
||||||
|
如果是垃圾内容,返回 "SPAM"
|
||||||
|
如果是正常内容,返回 "OK"
|
||||||
|
|
||||||
|
# 垃圾内容处理
|
||||||
|
on-spam:
|
||||||
|
labels:
|
||||||
|
- "spam"
|
||||||
|
minimize: true # 隐藏内容
|
||||||
|
comment: |
|
||||||
|
🤖 这个 issue 被 AI 检测为可能的垃圾内容,已自动隐藏。
|
||||||
|
如果这是误判,请联系维护者。
|
||||||
|
|
||||||
|
🤖 This issue was detected as potential spam by AI and has been hidden.
|
||||||
|
If this is a false positive, please contact the maintainers.
|
||||||
162
.github/workflows/batch-label-issues.yml
vendored
Normal file
162
.github/workflows/batch-label-issues.yml
vendored
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
name: Batch Label Issues
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
mode:
|
||||||
|
description: '标签模式'
|
||||||
|
required: true
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- 'recent' # 最近 20 个 issue
|
||||||
|
- 'open' # 所有打开的 issue
|
||||||
|
- 'unlabeled' # 只处理没有标签的 issue
|
||||||
|
- 'all' # 所有 issue(慎用)
|
||||||
|
default: 'recent'
|
||||||
|
|
||||||
|
skip_labeled:
|
||||||
|
description: '跳过已有标签的 issue'
|
||||||
|
required: false
|
||||||
|
type: boolean
|
||||||
|
default: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
batch-label:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20.x'
|
||||||
|
|
||||||
|
- name: Batch Label Issues
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
MODE="${{ github.event.inputs.mode }}"
|
||||||
|
SKIP_LABELED="${{ github.event.inputs.skip_labeled }}"
|
||||||
|
|
||||||
|
echo "📊 开始批量打标签..."
|
||||||
|
echo "模式: $MODE"
|
||||||
|
echo "跳过已标签: $SKIP_LABELED"
|
||||||
|
|
||||||
|
# 获取 issue 列表
|
||||||
|
if [ "$MODE" = "recent" ]; then
|
||||||
|
echo "📋 获取最近 20 个 issue..."
|
||||||
|
ISSUES=$(gh issue list --limit 20 --json number,labels,title,body --jq '.[] | {number, labels: [.labels[].name], title, body}')
|
||||||
|
elif [ "$MODE" = "open" ]; then
|
||||||
|
echo "📋 获取所有打开的 issue..."
|
||||||
|
ISSUES=$(gh issue list --state open --json number,labels,title,body --jq '.[] | {number, labels: [.labels[].name], title, body}')
|
||||||
|
elif [ "$MODE" = "unlabeled" ]; then
|
||||||
|
echo "📋 获取没有标签的 issue..."
|
||||||
|
ISSUES=$(gh issue list --state all --json number,labels,title,body --jq '.[] | select(.labels | length == 0) | {number, labels: [.labels[].name], title, body}')
|
||||||
|
else
|
||||||
|
echo "📋 获取所有 issue(限制 100 个)..."
|
||||||
|
ISSUES=$(gh issue list --state all --limit 100 --json number,labels,title,body --jq '.[] | {number, labels: [.labels[].name], title, body}')
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 临时文件
|
||||||
|
echo "$ISSUES" > /tmp/issues.json
|
||||||
|
|
||||||
|
# 处理每个 issue
|
||||||
|
cat /tmp/issues.json | jq -c '.' | while read -r issue; do
|
||||||
|
ISSUE_NUM=$(echo "$issue" | jq -r '.number')
|
||||||
|
EXISTING_LABELS=$(echo "$issue" | jq -r '.labels | join(",")')
|
||||||
|
TITLE=$(echo "$issue" | jq -r '.title')
|
||||||
|
BODY=$(echo "$issue" | jq -r '.body')
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔍 处理 Issue #$ISSUE_NUM: $TITLE"
|
||||||
|
echo " 现有标签: $EXISTING_LABELS"
|
||||||
|
|
||||||
|
# 跳过已有标签的 issue
|
||||||
|
if [ "$SKIP_LABELED" = "true" ] && [ ! -z "$EXISTING_LABELS" ]; then
|
||||||
|
echo " ⏭️ 跳过(已有标签)"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 分析内容并打标签
|
||||||
|
LABELS_TO_ADD=""
|
||||||
|
|
||||||
|
# 检测 bug
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(bug|错误|崩溃|crash|error|exception|问题|fix)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD bug"
|
||||||
|
echo " 🐛 检测到: bug"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 feature request
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(feature|功能|enhancement|improve|优化|建议|新增|添加|add)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD enhancement"
|
||||||
|
echo " ✨ 检测到: enhancement"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 question
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(question|疑问|how to|如何|怎么|为什么|why|咨询|\?|?)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD question"
|
||||||
|
echo " ❓ 检测到: question"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 documentation
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(doc|文档|readme|guide|tutorial|教程|说明)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD documentation"
|
||||||
|
echo " 📖 检测到: documentation"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 performance
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(performance|性能|slow|慢|lag|卡顿|optimize|优化)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD performance"
|
||||||
|
echo " ⚡ 检测到: performance"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 core
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(@esengine/ecs-framework|packages/core|core package|核心包)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD core"
|
||||||
|
echo " 🎯 检测到: core"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 editor
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(editor|编辑器|tauri)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD editor"
|
||||||
|
echo " 🎨 检测到: editor"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 network
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(network|网络|multiplayer|多人|同步)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD network"
|
||||||
|
echo " 🌐 检测到: network"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检测 help wanted
|
||||||
|
if echo "$TITLE $BODY" | grep -iE "(help wanted|需要帮助|求助)" > /dev/null; then
|
||||||
|
LABELS_TO_ADD="$LABELS_TO_ADD help wanted"
|
||||||
|
echo " 🆘 检测到: help wanted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 添加标签
|
||||||
|
if [ ! -z "$LABELS_TO_ADD" ]; then
|
||||||
|
echo " ✅ 添加标签: $LABELS_TO_ADD"
|
||||||
|
for label in $LABELS_TO_ADD; do
|
||||||
|
gh issue edit $ISSUE_NUM --add-label "$label" 2>&1 | grep -v "already exists" || true
|
||||||
|
done
|
||||||
|
echo " 💬 添加说明评论..."
|
||||||
|
gh issue comment $ISSUE_NUM --body "🤖 自动标签系统检测到此 issue 并添加了相关标签。如有误判,请告知维护者。
|
||||||
|
|
||||||
|
🤖 Auto-labeling system detected and labeled this issue. Please let maintainers know if this is incorrect." || true
|
||||||
|
else
|
||||||
|
echo " ℹ️ 未检测到明确类型"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 避免 API 限制
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ 批量标签完成!"
|
||||||
|
echo "查看结果: https://github.com/${{ github.repository }}/issues"
|
||||||
Reference in New Issue
Block a user