Skip to content
This repository was archived by the owner on Jan 27, 2026. It is now read-only.

Commit 5ef8324

Browse files
committed
build: 简化 spam issues 清理器
1 parent 378445b commit 5ef8324

File tree

1 file changed

+73
-125
lines changed

1 file changed

+73
-125
lines changed
Lines changed: 73 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Delete Spam Issues
1+
name: Close Spam Issues
22

33
on:
44
issues:
@@ -7,7 +7,7 @@ on:
77
# 允许手动触发
88

99
jobs:
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

Comments
 (0)