1- name : Delete Spam Issues
1+ name : Close Spam Issues
22
33on :
44 issues :
77 # 允许手动触发
88
99jobs :
10- delete -spam-issues :
10+ close -spam-issues :
1111 runs-on : ubuntu-latest
1212
1313 permissions :
@@ -18,147 +18,95 @@ jobs:
1818 - name : Checkout repository
1919 uses : actions/checkout@v4
2020
21- - name : Check token permissions
21+ - name : Close spam issues with short descriptions
2222 env :
23- GITHUB_TOKEN : ${{ secrets.PAT_TOKEN || secrets. GITHUB_TOKEN }}
23+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
2424 run : |
25- echo "Checking GitHub token permissions ..."
25+ echo "? Starting spam issue cleanup ..."
2626
27- # 检查当前用户权限
28- user_info=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
29- -H "Accept: application/vnd.github.v3+json" \
30- "https://api.github.com/user")
27+ closed_count=0
3128
32- username=$(echo "$user_info" | jq -r '.login')
33- echo "Running as user: $username "
29+ # 使用 GitHub CLI 获取所有开放的 issues
30+ echo "? Fetching open issues... "
3431
35- # 检查仓库权限
36- repo_perms=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
37- -H "Accept: application/vnd.github.v3+json" \
38- "https://api.github.com/repos/$GITHUB_REPOSITORY" | jq -r '.permissions // {}')
32+ # 获取所有开放的 issues (不包括 PR)
33+ issues=$(gh issue list --state open --json number,title,body,author --limit 100)
3934
40- echo "Repository permissions: $repo_perms"
41-
42- if [ "${{ secrets.PAT_TOKEN }}" == "" ]; then
43- echo "?? Warning: Using default GITHUB_TOKEN which may not have delete permissions"
44- echo "? To fix: Create a Personal Access Token with 'repo' scope and add it as PAT_TOKEN secret"
45- else
46- echo "? Using custom PAT_TOKEN"
35+ if [ "$(echo "$issues" | jq '. | length')" = "0" ]; then
36+ echo "? No open issues found."
37+ exit 0
4738 fi
4839
49- - name : Delete spam issues with short descriptions
50- env :
51- GITHUB_TOKEN : ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
52- run : |
53- echo "Starting deletion of spam issues with short descriptions..."
54-
55- # 获取仓库的node ID (用于GraphQL删除操作)
56- repo_info=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
57- -H "Accept: application/vnd.github.v3+json" \
58- "https://api.github.com/repos/$GITHUB_REPOSITORY")
59- repo_node_id=$(echo "$repo_info" | jq -r '.node_id')
60-
61- # 获取所有开放的issues
62- page=1
63- deleted_count=0
64- while true; do
65- echo "Fetching issues page $page..."
66-
67- issues=$(curl -s -H "Authorization: token $GITHUB_TOKEN" \
68- -H "Accept: application/vnd.github.v3+json" \
69- "https://api.github.com/repos/$GITHUB_REPOSITORY/issues?state=open&page=$page&per_page=100")
70-
71- # 检查是否还有issues
72- issues_count=$(echo "$issues" | jq '. | length')
73- if [ "$issues_count" = "0" ]; then
74- break
75- fi
76-
77- echo "Processing $issues_count issues from page $page..."
78-
79- # 遍历每个issue
80- echo "$issues" | jq -r '.[] | select(.pull_request == null) | @base64' | while read -r issue_data; do
81- issue=$(echo "$issue_data" | base64 --decode)
82-
83- issue_number=$(echo "$issue" | jq -r '.number')
84- issue_title=$(echo "$issue" | jq -r '.title')
85- issue_body=$(echo "$issue" | jq -r '.body // ""')
86- issue_user=$(echo "$issue" | jq -r '.user.login')
87- issue_node_id=$(echo "$issue" | jq -r '.node_id')
88-
89- # 计算标题和描述长度(去除空白字符)
90- title_length=$(echo "$issue_title" | tr -d '[:space:]' | wc -c)
91- body_length=$(echo "$issue_body" | tr -d '[:space:]' | wc -c)
92-
93- echo "Issue #$issue_number: '$issue_title' by $issue_user (title: $title_length chars, body: $body_length chars)"
94-
95- # 如果标题和描述都少于20个字符,则删除issue
96- if [ "$title_length" -lt 20 ] && [ "$body_length" -lt 20 ]; then
97- echo "?? Attempting to delete spam issue #$issue_number due to short title ($title_length chars) and description ($body_length chars)"
98-
99- # 首先尝试关闭issue(如果删除失败的话)
100- close_result=$(curl -s -X PATCH \
101- -H "Authorization: token $GITHUB_TOKEN" \
102- -H "Accept: application/vnd.github.v3+json" \
103- -H "Content-Type: application/json" \
104- "https://api.github.com/repos/$GITHUB_REPOSITORY/issues/$issue_number" \
105- -d '{"state": "closed", "state_reason": "not_planned"}')
106-
107- # 使用GraphQL API删除issue
108- delete_mutation='{
109- "query": "mutation { deleteIssue(input: {issueId: \"'$issue_node_id'\"}) { clientMutationId } }"
110- }'
111-
112- delete_result=$(curl -s -X POST \
113- -H "Authorization: token $GITHUB_TOKEN" \
114- -H "Accept: application/vnd.github.v4+json" \
115- -H "Content-Type: application/json" \
116- "https://api.github.com/graphql" \
117- -d "$delete_mutation")
118-
119- # 检查删除结果
120- if echo "$delete_result" | jq -e '.data.deleteIssue' > /dev/null; then
121- echo "? Issue #$issue_number has been successfully deleted"
122- deleted_count=$((deleted_count + 1))
40+ echo "? Processing $(echo "$issues" | jq '. | length') issues..."
41+
42+ # 处理每个 issue
43+ echo "$issues" | jq -r '.[] | @base64' | while read -r issue_data; do
44+ issue=$(echo "$issue_data" | base64 --decode)
45+
46+ issue_number=$(echo "$issue" | jq -r '.number')
47+ issue_title=$(echo "$issue" | jq -r '.title')
48+ issue_body=$(echo "$issue" | jq -r '.body // ""')
49+ issue_author=$(echo "$issue" | jq -r '.author.login')
50+
51+ # 计算标题和描述长度(去除空白字符)
52+ title_length=$(echo "$issue_title" | tr -d '[:space:]' | wc -c)
53+ body_length=$(echo "$issue_body" | tr -d '[:space:]' | wc -c)
54+
55+ echo "? Issue #$issue_number: '$issue_title' by $issue_author"
56+ echo " ? Title: $title_length chars, Body: $body_length chars"
57+
58+ # 如果标题和描述都少于20个字符,则关闭issue
59+ if [ "$title_length" -lt 20 ] && [ "$body_length" -lt 20 ]; then
60+ echo "? Closing spam issue #$issue_number (title: $title_length chars, body: $body_length chars)"
61+
62+ # 构建评论内容并写入临时文件
63+ echo "? This issue has been automatically closed due to insufficient content." > /tmp/comment.txt
64+ echo "" >> /tmp/comment.txt
65+ echo "**Reason:** Both title and description are too short (less than 20 characters each)" >> /tmp/comment.txt
66+ echo "- Title length: $title_length characters" >> /tmp/comment.txt
67+ echo "- Description length: $body_length characters" >> /tmp/comment.txt
68+ echo "" >> /tmp/comment.txt
69+ echo "Please provide more detailed information when creating issues. If this was closed in error, feel free to reopen with additional details." >> /tmp/comment.txt
70+ echo "" >> /tmp/comment.txt
71+ echo "@tinymins" >> /tmp/comment.txt
72+
73+ # 使用 GitHub CLI 添加评论
74+ if gh issue comment "$issue_number" --body-file /tmp/comment.txt; then
75+ echo "? Added comment to issue #$issue_number"
76+
77+ # 关闭 issue
78+ if gh issue close "$issue_number" --reason "not planned"; then
79+ echo "? Closed issue #$issue_number"
80+ closed_count=$((closed_count + 1))
12381 else
124- error_msg=$(echo "$delete_result" | jq -r '.errors[0].message // "Unknown error"')
125- echo "? Failed to delete issue #$issue_number"
126- echo " Error: $error_msg"
127-
128- # 检查是否至少成功关闭了
129- if echo "$close_result" | jq -e '.state == "closed"' > /dev/null; then
130- echo "? Issue #$issue_number was closed instead"
131- else
132- echo "? Failed to close issue #$issue_number as well"
133- fi
82+ echo "? Failed to close issue #$issue_number"
13483 fi
13584 else
136- echo "Issue #$issue_number has sufficient content (title: $title_length chars, body: $body_length chars), keeping it "
85+ echo "? Failed to add comment to issue #$issue_number "
13786 fi
138- done
87+ else
88+ echo "? Issue #$issue_number has sufficient content, keeping open"
89+ fi
13990
140- page=$((page + 1))
91+ echo "---"
14192 done
14293
143- echo "Spam cleanup completed. Deleted $deleted_count issues."
94+ echo "? Spam cleanup completed. Closed $closed_count issues."
14495
145- - name : Report deletion summary
96+ - name : Report cleanup summary
14697 if : github.event_name == 'workflow_dispatch'
147- env :
148- GITHUB_TOKEN : ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
14998 run : |
150- echo "? Spam issue cleanup workflow completed"
99+ echo "? Spam issue cleanup workflow completed successfully! "
151100 echo ""
152- echo "? This workflow automatically processes issues with BOTH title and description shorter than 20 characters"
153- echo "?? If deletion permission is available: DELETES the issues"
154- echo "? If deletion permission is not available: CLOSES the issues"
155- echo "?? DELETED issues cannot be recovered!"
101+ echo "? This workflow automatically CLOSES issues with insufficient content:"
102+ echo " - Both title AND description must be shorter than 20 characters"
103+ echo " - Issues are closed with 'not planned' reason"
104+ echo " - A comment is added explaining the closure"
105+ echo " - @tinymins is notified in the comment"
156106 echo ""
157- echo "? This workflow runs on:"
158- echo " - New issues being opened (immediate processing of spam)"
159- echo " - Issues being edited (processing if edited to become too short )"
160- echo " - Manual trigger (on-demand cleanup)"
107+ echo "? This workflow runs automatically on:"
108+ echo " ? New issues being opened (immediate spam detection )"
109+ echo " ?? Issues being edited (re-evaluation of content )"
110+ echo " ? Manual trigger (batch cleanup via Actions tab )"
161111 echo ""
162- echo "? To enable deletion:"
163- echo " 1. Create a Personal Access Token with 'repo' scope"
164- echo " 2. Add it as a repository secret named 'PAT_TOKEN'"
112+ echo "? Closed issues can be reopened if they were closed in error."
0 commit comments