mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-04-22 03:46:43 +02:00
chore: cleanup triage bot
This commit is contained in:
@@ -1,76 +0,0 @@
|
||||
messages:
|
||||
- role: system
|
||||
content: |-
|
||||
You are an issue validation assistant for Donut Browser, an anti-detect browser.
|
||||
|
||||
Analyze the provided issue content and determine if it contains sufficient information based on these requirements:
|
||||
|
||||
For Bug Reports, the issue should include:
|
||||
1. Clear description of the problem
|
||||
2. Steps to reproduce the issue (numbered list preferred)
|
||||
3. Expected vs actual behavior
|
||||
4. Environment information (OS, browser version, etc.)
|
||||
5. Error messages, stack traces, or screenshots if applicable
|
||||
|
||||
For Feature Requests, the issue should include:
|
||||
1. Clear description of the requested feature
|
||||
2. Use case or problem it solves
|
||||
3. Proposed solution or how it should work
|
||||
4. Priority level or importance
|
||||
|
||||
General Requirements for all issues:
|
||||
1. Descriptive title
|
||||
2. Sufficient detail to understand and act upon
|
||||
3. Professional tone and clear communication
|
||||
|
||||
Constraints:
|
||||
- Maximum 3 items in missing_info array
|
||||
- Maximum 3 items in suggestions array
|
||||
- Each array item must be under 80 characters
|
||||
- overall_assessment must be under 100 characters
|
||||
- role: user
|
||||
content: |-
|
||||
## Issue Content to Analyze:
|
||||
|
||||
**Title:** {{issue_title}}
|
||||
|
||||
**Body:**
|
||||
{{issue_body}}
|
||||
|
||||
**Labels:** {{issue_labels}}
|
||||
model: openai/gpt-4.1
|
||||
responseFormat: json_schema
|
||||
jsonSchema: |-
|
||||
{
|
||||
"name": "issue_validation",
|
||||
"strict": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"is_valid": {
|
||||
"type": "boolean",
|
||||
"description": "Whether the issue contains sufficient information"
|
||||
},
|
||||
"issue_type": {
|
||||
"type": "string",
|
||||
"enum": ["bug_report", "feature_request", "other"]
|
||||
},
|
||||
"missing_info": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Missing information items (max 3, each under 80 characters)"
|
||||
},
|
||||
"suggestions": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Suggestions for improvement (max 3, each under 80 characters)"
|
||||
},
|
||||
"overall_assessment": {
|
||||
"type": "string",
|
||||
"description": "One sentence assessment under 100 characters"
|
||||
}
|
||||
},
|
||||
"required": ["is_valid", "issue_type", "missing_info", "suggestions", "overall_assessment"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
messages:
|
||||
- role: system
|
||||
content: |-
|
||||
You are a code review assistant for Donut Browser, an open-source anti-detect browser built with Tauri, Next.js, and Rust.
|
||||
|
||||
Review the provided pull request and provide constructive feedback. Focus on:
|
||||
1. Code quality and best practices
|
||||
2. Potential bugs or issues
|
||||
3. Security concerns (especially important for an anti-detect browser)
|
||||
4. Performance implications
|
||||
5. Consistency with the project's patterns
|
||||
|
||||
Constraints:
|
||||
- Maximum 4 items in feedback array
|
||||
- Maximum 3 items in suggestions array
|
||||
- Maximum 2 items in security_notes array
|
||||
- Each array item must be under 150 characters
|
||||
- summary must be under 200 characters
|
||||
- Be constructive and helpful, not harsh
|
||||
- role: user
|
||||
content: |-
|
||||
## Pull Request to Review:
|
||||
|
||||
**Title:** {{pr_title}}
|
||||
|
||||
**Description:**
|
||||
{{pr_body}}
|
||||
|
||||
**Diff:**
|
||||
{{pr_diff}}
|
||||
model: openai/gpt-4.1
|
||||
responseFormat: json_schema
|
||||
jsonSchema: |-
|
||||
{
|
||||
"name": "pr_review",
|
||||
"strict": true,
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"summary": {
|
||||
"type": "string",
|
||||
"description": "Brief 1-2 sentence summary under 200 characters"
|
||||
},
|
||||
"quality_score": {
|
||||
"type": "string",
|
||||
"enum": ["good", "needs_work", "critical_issues"]
|
||||
},
|
||||
"feedback": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Feedback points (max 4, each under 150 characters)"
|
||||
},
|
||||
"suggestions": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Suggestions (max 3, each under 150 characters)"
|
||||
},
|
||||
"security_notes": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Security notes if any (max 2, each under 150 characters)"
|
||||
}
|
||||
},
|
||||
"required": ["summary", "quality_score", "feedback", "suggestions", "security_notes"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
@@ -18,31 +18,13 @@ permissions:
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
validate-issue:
|
||||
analyze-issue:
|
||||
if: github.event_name == 'issues'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
|
||||
|
||||
- name: Save issue body to file
|
||||
env:
|
||||
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||
run: printf '%s' "${ISSUE_BODY:-}" > issue_body.txt
|
||||
|
||||
- name: Validate issue with AI
|
||||
id: validate
|
||||
uses: actions/ai-inference@e09e65981758de8b2fdab13c2bfb7c7d5493b0b6 # v2.0.7
|
||||
with:
|
||||
prompt-file: .github/prompts/issue-validation.prompt.yml
|
||||
input: |
|
||||
issue_title: ${{ github.event.issue.title }}
|
||||
issue_labels: ${{ join(github.event.issue.labels.*.name, ', ') }}
|
||||
file_input: |
|
||||
issue_body: ./issue_body.txt
|
||||
max-tokens: 1024
|
||||
|
||||
- name: Check if first-time contributor
|
||||
id: check-first-time
|
||||
env:
|
||||
@@ -59,101 +41,31 @@ jobs:
|
||||
echo "is_first_time=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Parse validation result and take action
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RESPONSE_FILE: ${{ steps.validate.outputs.response-file }}
|
||||
run: |
|
||||
if [ -n "$RESPONSE_FILE" ] && [ -f "$RESPONSE_FILE" ]; then
|
||||
RAW_OUTPUT=$(cat "$RESPONSE_FILE")
|
||||
else
|
||||
echo "::error::Response file not found: $RESPONSE_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JSON_RESULT=$(printf "%s" "$RAW_OUTPUT" | sed -n '/```json/,/```/p' | sed '1d;$d')
|
||||
if [ -z "$JSON_RESULT" ]; then
|
||||
JSON_RESULT="$RAW_OUTPUT"
|
||||
fi
|
||||
|
||||
if ! echo "$JSON_RESULT" | jq empty 2>/dev/null; then
|
||||
echo "::warning::Invalid JSON in AI response, using fallback"
|
||||
JSON_RESULT='{"is_valid":true,"issue_type":"other","missing_info":[],"suggestions":[],"overall_assessment":"Unable to validate automatically"}'
|
||||
fi
|
||||
|
||||
IS_VALID=$(echo "$JSON_RESULT" | jq -r '.is_valid // false')
|
||||
ISSUE_TYPE=$(echo "$JSON_RESULT" | jq -r '.issue_type // "other"')
|
||||
MISSING_INFO=$(echo "$JSON_RESULT" | jq -r '.missing_info[]? // empty' | sed 's/^/- /')
|
||||
SUGGESTIONS=$(echo "$JSON_RESULT" | jq -r '.suggestions[]? // empty' | sed 's/^/- /')
|
||||
ASSESSMENT=$(echo "$JSON_RESULT" | jq -r '.overall_assessment // "No assessment provided"')
|
||||
|
||||
IS_FIRST_TIME="${{ steps.check-first-time.outputs.is_first_time }}"
|
||||
GREETING_SECTION=""
|
||||
if [ "$IS_FIRST_TIME" = "true" ]; then
|
||||
GREETING_SECTION="## 👋 Welcome!\n\nThank you for your first issue ❤️ If this is a feature request, please make sure it is clear what you want, why you want it, and how important it is to you. If you posted a bug report, please make sure it includes as much detail as possible.\n\n---\n\n"
|
||||
fi
|
||||
|
||||
if [ "$IS_VALID" = "false" ]; then
|
||||
{
|
||||
printf "%b" "$GREETING_SECTION"
|
||||
printf "## 🤖 Issue Validation\n\n"
|
||||
printf "Thank you for submitting this issue! However, it appears that some required information might be missing to help the maintainers better understand and address your concern.\n\n"
|
||||
printf "**Issue Type Detected:** \`%s\`\n\n" "$ISSUE_TYPE"
|
||||
printf "**Assessment:** %s\n\n" "$ASSESSMENT"
|
||||
printf "### 📋 Missing Information:\n%s\n\n" "$MISSING_INFO"
|
||||
printf "### 💡 Suggestions for Improvement:\n%s\n\n" "$SUGGESTIONS"
|
||||
printf "### 📝 How to Provide Additional Information:\n\n"
|
||||
printf "Please edit your original issue description to include the missing information. Here are the issue templates for reference:\n\n"
|
||||
printf -- "- **Bug Report Template:** [View Template](.github/ISSUE_TEMPLATE/01-bug-report.md)\n"
|
||||
printf -- "- **Feature Request Template:** [View Template](.github/ISSUE_TEMPLATE/02-feature-request.md)\n\n"
|
||||
printf "### 🔧 Quick Tips:\n"
|
||||
printf -- "- For **bug reports**: Include step-by-step reproduction instructions, your environment details, and any error messages\n"
|
||||
printf -- "- For **feature requests**: Describe the use case, expected behavior, and why this feature would be valuable\n"
|
||||
printf -- "- Add **screenshots** or **logs** when applicable\n\n"
|
||||
printf "Once you have updated the issue with the missing information, feel free to remove this comment or reply to let the maintainers know the updates have been made.\n\n"
|
||||
printf -- "---\n*This validation was performed automatically to ensure all the information needed to help effectively is provided.*\n"
|
||||
} > comment.md
|
||||
|
||||
gh issue comment ${{ github.event.issue.number }} --body-file comment.md
|
||||
gh issue edit ${{ github.event.issue.number }} --add-label "needs-info"
|
||||
else
|
||||
SUGGESTIONS_SECTION=""
|
||||
if [ -n "$SUGGESTIONS" ]; then
|
||||
SUGGESTIONS_SECTION=$(printf "### 💡 Suggestions:\n%s\n\n" "$SUGGESTIONS")
|
||||
fi
|
||||
|
||||
{
|
||||
printf "%b" "$GREETING_SECTION"
|
||||
printf "## 🤖 Issue Validation\n\n"
|
||||
printf "**Issue Type Detected:** \`%s\`\n\n" "$ISSUE_TYPE"
|
||||
printf "**Assessment:** %s\n\n" "$ASSESSMENT"
|
||||
printf "%b" "$SUGGESTIONS_SECTION"
|
||||
printf -- "---\n*This validation was performed automatically to help triage issues.*\n"
|
||||
} > comment.md
|
||||
|
||||
gh issue comment ${{ github.event.issue.number }} --body-file comment.md
|
||||
|
||||
case "$ISSUE_TYPE" in
|
||||
"bug_report")
|
||||
gh issue edit ${{ github.event.issue.number }} --add-label "bug"
|
||||
;;
|
||||
"feature_request")
|
||||
gh issue edit ${{ github.event.issue.number }} --add-label "enhancement"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
- name: Run opencode analysis
|
||||
- name: Analyze issue
|
||||
uses: anomalyco/opencode/github@6c7d968c4423a0cd6c85099c9377a6066313fa0a #v1.2.20
|
||||
env:
|
||||
ZHIPU_API_KEY: ${{ secrets.ZHIPU_API_KEY }}
|
||||
with:
|
||||
model: zai-coding-plan/glm-4.7
|
||||
prompt: |
|
||||
You are a triage bot for Donut Browser (open-source anti-detect browser, Tauri + Next.js + Rust).
|
||||
|
||||
- name: Cleanup
|
||||
run: rm -f issue_body.txt comment.md
|
||||
${{ steps.check-first-time.outputs.is_first_time == 'true' && 'This is a first-time contributor. Start your comment with: "Thanks for opening your first issue!"' || '' }}
|
||||
|
||||
handle-pr:
|
||||
Analyze this issue and post a single concise comment. Format:
|
||||
|
||||
1. One sentence acknowledging what the user wants.
|
||||
2. A short **Action items** list — what specific info is missing or what the user should do next. Only include items that are actually missing. If the issue is complete, say so and skip this section.
|
||||
3. Label the issue: add "bug" label for bug reports, "enhancement" label for feature requests.
|
||||
|
||||
Rules:
|
||||
- Be brief. No filler, no generic tips, no templates.
|
||||
- If it's a bug report, check for: reproduction steps, OS/version, error messages. Only ask for what's actually missing.
|
||||
- If it's a feature request, check for: clear description of desired behavior, use case. Only ask for what's actually missing.
|
||||
- If the issue already has everything needed, just acknowledge it and label it.
|
||||
- Never exceed 6 items total.
|
||||
|
||||
analyze-pr:
|
||||
if: github.event_name == 'pull_request' && github.actor != 'dependabot[bot]'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -178,109 +90,29 @@ jobs:
|
||||
echo "is_first_time=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Get PR diff
|
||||
id: get-diff
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh pr diff ${{ github.event.pull_request.number }} > pr_diff.txt
|
||||
head -c 10000 pr_diff.txt > pr_diff_truncated.txt
|
||||
|
||||
- name: Save PR body to file
|
||||
env:
|
||||
PR_BODY: ${{ github.event.pull_request.body }}
|
||||
run: printf '%s' "${PR_BODY:-No description provided}" > pr_body.txt
|
||||
|
||||
- name: Analyze PR with AI
|
||||
id: analyze
|
||||
uses: actions/ai-inference@e09e65981758de8b2fdab13c2bfb7c7d5493b0b6 # v2.0.7
|
||||
with:
|
||||
prompt-file: .github/prompts/pr-review.prompt.yml
|
||||
input: |
|
||||
pr_title: ${{ github.event.pull_request.title }}
|
||||
file_input: |
|
||||
pr_body: ./pr_body.txt
|
||||
pr_diff: ./pr_diff_truncated.txt
|
||||
max-tokens: 1024
|
||||
|
||||
- name: Post PR feedback comment
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
RESPONSE_FILE: ${{ steps.analyze.outputs.response-file }}
|
||||
run: |
|
||||
if [ -n "$RESPONSE_FILE" ] && [ -f "$RESPONSE_FILE" ]; then
|
||||
RAW_OUTPUT=$(cat "$RESPONSE_FILE")
|
||||
else
|
||||
echo "::error::Response file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JSON_RESULT=$(printf "%s" "$RAW_OUTPUT" | sed -n '/```json/,/```/p' | sed '1d;$d')
|
||||
if [ -z "$JSON_RESULT" ]; then
|
||||
JSON_RESULT="$RAW_OUTPUT"
|
||||
fi
|
||||
|
||||
if ! echo "$JSON_RESULT" | jq empty 2>/dev/null; then
|
||||
echo "::warning::Invalid JSON in AI response, using fallback"
|
||||
JSON_RESULT='{"summary":"Unable to analyze automatically","quality_score":"good","feedback":[],"suggestions":[],"security_notes":[]}'
|
||||
fi
|
||||
|
||||
SUMMARY=$(echo "$JSON_RESULT" | jq -r '.summary // "No summary"')
|
||||
QUALITY=$(echo "$JSON_RESULT" | jq -r '.quality_score // "good"')
|
||||
FEEDBACK=$(echo "$JSON_RESULT" | jq -r '.feedback[]? // empty' | sed 's/^/- /')
|
||||
SUGGESTIONS=$(echo "$JSON_RESULT" | jq -r '.suggestions[]? // empty' | sed 's/^/- /')
|
||||
SECURITY=$(echo "$JSON_RESULT" | jq -r '.security_notes[]? // empty' | sed 's/^/- ⚠️ /')
|
||||
|
||||
IS_FIRST_TIME="${{ steps.check-first-time.outputs.is_first_time }}"
|
||||
|
||||
{
|
||||
if [ "$IS_FIRST_TIME" = "true" ]; then
|
||||
printf "## 👋 Welcome!\n\n"
|
||||
printf "Thank you for your first contribution ❤️ A human will review your PR shortly. Make sure that the pipelines are green, so that the PR is considered ready for review and could be merged.\n\n"
|
||||
printf -- "---\n\n"
|
||||
fi
|
||||
|
||||
printf "## 🤖 PR Review\n\n"
|
||||
printf "**Summary:** %s\n\n" "$SUMMARY"
|
||||
|
||||
case "$QUALITY" in
|
||||
"good")
|
||||
printf "**Status:** ✅ Looking good!\n\n"
|
||||
;;
|
||||
"needs_work")
|
||||
printf "**Status:** 🔧 Some improvements suggested\n\n"
|
||||
;;
|
||||
"critical_issues")
|
||||
printf "**Status:** ⚠️ Please address the issues below\n\n"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "$FEEDBACK" ]; then
|
||||
printf "### 📝 Feedback:\n%s\n\n" "$FEEDBACK"
|
||||
fi
|
||||
|
||||
if [ -n "$SUGGESTIONS" ]; then
|
||||
printf "### 💡 Suggestions:\n%s\n\n" "$SUGGESTIONS"
|
||||
fi
|
||||
|
||||
if [ -n "$SECURITY" ]; then
|
||||
printf "### 🔒 Security Notes:\n%s\n\n" "$SECURITY"
|
||||
fi
|
||||
|
||||
printf -- "---\n*This review was performed automatically. A human maintainer will also review your changes.*\n"
|
||||
} > comment.md
|
||||
|
||||
gh pr comment ${{ github.event.pull_request.number }} --body-file comment.md
|
||||
|
||||
- name: Run opencode analysis
|
||||
- name: Analyze PR
|
||||
uses: anomalyco/opencode/github@6c7d968c4423a0cd6c85099c9377a6066313fa0a #v1.2.20
|
||||
env:
|
||||
ZHIPU_API_KEY: ${{ secrets.ZHIPU_API_KEY }}
|
||||
with:
|
||||
model: zai-coding-plan/glm-4.7
|
||||
prompt: |
|
||||
You are a review bot for Donut Browser (open-source anti-detect browser, Tauri + Next.js + Rust).
|
||||
|
||||
- name: Cleanup
|
||||
run: rm -f pr_diff.txt pr_diff_truncated.txt pr_body.txt comment.md
|
||||
${{ steps.check-first-time.outputs.is_first_time == 'true' && 'This is a first-time contributor. Start your comment with: "Thanks for your first PR!"' || '' }}
|
||||
|
||||
Review this PR and post a single concise comment. Format:
|
||||
|
||||
1. One sentence summarizing what this PR does.
|
||||
2. **Action items** — only list things that actually need to be fixed or addressed. If the PR looks good, say so and skip this section.
|
||||
|
||||
Rules:
|
||||
- Be brief. No filler, no praise padding.
|
||||
- Focus on: bugs, security issues, missing edge cases, breaking changes.
|
||||
- If the PR touches UI text or adds new strings, remind to update translation files in src/i18n/locales/.
|
||||
- If the PR modifies Tauri commands, remind to check the unused-commands test.
|
||||
- Do not nitpick style or formatting — the project has automated linting.
|
||||
- Never exceed 8 lines total.
|
||||
|
||||
opencode-command:
|
||||
if: |
|
||||
|
||||
Reference in New Issue
Block a user