Skip to content

Commit be1ac2f

Browse files
authored
feat: enhance assignment bot to guard against users with spam PRs (#1270)
Signed-off-by: MonaaEid <[email protected]> Signed-off-by: MontyPokemon <[email protected]>
1 parent dff4a28 commit be1ac2f

File tree

3 files changed

+142
-20
lines changed

3 files changed

+142
-20
lines changed
Lines changed: 140 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,159 @@
11
#!/bin/bash
2+
set -Eeuo pipefail
23

3-
if [ -z "$ASSIGNEE" ] || [ -z "$ISSUE_NUMBER" ] || [ -z "$REPO" ]; then
4+
# Validate required env vars
5+
if [ -z "${ASSIGNEE:-}" ] || [ -z "${ISSUE_NUMBER:-}" ] || [ -z "${REPO:-}" ]; then
46
echo "Error: Missing required environment variables (ASSIGNEE, ISSUE_NUMBER, REPO)."
57
exit 1
68
fi
79

810
echo "Checking assignment rules for user $ASSIGNEE on issue #$ISSUE_NUMBER"
911

10-
PERM_JSON=$(gh api repos/$REPO/collaborators/$ASSIGNEE/permission)
11-
PERMISSION=$(echo "$PERM_JSON" | jq -r '.permission')
12+
# Helper functions
13+
get_permission() {
14+
gh api "repos/${REPO}/collaborators/${ASSIGNEE}/permission" --jq '.permission' 2>/dev/null || echo "none"
1215

13-
echo "User permission level: $PERMISSION"
16+
}
1417

15-
if [[ "$PERMISSION" == "admin" ]] || [[ "$PERMISSION" == "write" ]]; then
16-
echo "User is a maintainer or committer. Limit does not apply."
17-
exit 0
18-
fi
18+
is_spam_user() {
19+
local spam_file=".github/spam-list.txt"
20+
21+
# Check static spam list
22+
if [[ -f "$spam_file" ]]; then
23+
if grep -vE '^\s*#|^\s*$' "$spam_file" | grep -qxF "$ASSIGNEE"; then
24+
return 0
25+
fi
26+
else
27+
echo "Spam list file not found. Treating as empty." >&2
28+
fi
29+
return 1
30+
}
31+
32+
issue_has_gfi() {
33+
local has
34+
has=$(gh api "repos/${REPO}/issues/${ISSUE_NUMBER}" --jq 'any(.labels[]; .name=="Good First Issue")' || echo "false")
35+
[[ "$has" == "true" ]]
36+
}
37+
38+
assignments_count() {
39+
gh issue list --repo "${REPO}" --assignee "${ASSIGNEE}" --state open --limit 100 --json number --jq 'length'
40+
}
41+
42+
remove_assignee() {
43+
gh issue edit "${ISSUE_NUMBER}" --repo "${REPO}" --remove-assignee "${ASSIGNEE}"
44+
}
45+
46+
post_comment() {
47+
gh issue comment "$ISSUE_NUMBER" --repo "$REPO" --body "$1"
48+
}
49+
50+
msg_spam_non_gfi() {
51+
cat <<EOF
52+
Hi @$ASSIGNEE, this is the Assignment Bot.
53+
54+
:warning: **Assignment Restricted**
55+
56+
Your account currently has limited assignment privileges. You may only be assigned to issues labeled **Good First Issue**.
57+
58+
**Current Restrictions:**
59+
- :white_check_mark: Can be assigned to 'Good First Issue' labeled issues (maximum 1 at a time)
60+
- :x: Cannot be assigned to other issues
61+
62+
**How to have restrictions lifted:**
63+
1. Successfully complete and merge your assigned Good First Issue
64+
2. Demonstrate consistent, quality contributions
65+
3. Contact a maintainer to review your restriction status
66+
67+
Thank you for your understanding!
68+
EOF
69+
}
70+
71+
msg_spam_limit_exceeded() {
72+
local count="$1"
73+
cat <<EOF
74+
Hi @$ASSIGNEE, this is the Assignment Bot.
75+
76+
:warning: **Assignment Limit Exceeded**
77+
78+
Your account currently has limited assignment privileges with a maximum of **1 open assignment** at a time.
1979
20-
ASSIGNMENTS_JSON=$(gh issue list --repo $REPO --assignee "$ASSIGNEE" --state open --json number)
21-
COUNT=$(echo "$ASSIGNMENTS_JSON" | jq '. | length')
80+
You currently have $count open issue(s) assigned. Please complete and merge your existing assignment before requesting a new one.
2281
23-
echo "Current open assignments count: $COUNT"
82+
**Current Restrictions:**
83+
- Maximum 1 open assignment at a time
84+
- Can only be assigned to 'Good First Issue' labeled issues
2485
25-
if (( COUNT > 2 )); then
26-
echo "Limit exceeded (Max 2 allowed). Revoking assignment."
86+
**How to have restrictions lifted:**
87+
1. Successfully complete and merge your current assigned issue
88+
2. Demonstrate consistent, quality contributions
89+
3. Contact a maintainer to review your restriction status
2790
28-
gh issue edit $ISSUE_NUMBER --repo $REPO --remove-assignee "$ASSIGNEE"
91+
Thank you for your cooperation!
92+
EOF
93+
}
2994

30-
MSG="Hi @$ASSIGNEE, this is the Assignment Bot."
31-
MSG="$MSG\n\nAssigning you to this issue would exceed the limit of 2 open assignments."
32-
MSG="$MSG\n\nPlease resolve and merge your existing assigned issues before requesting new ones."
95+
msg_normal_limit_exceeded() {
96+
cat <<EOF
97+
Hi @$ASSIGNEE, this is the Assignment Bot.
3398
34-
gh issue comment $ISSUE_NUMBER --repo $REPO --body "$(printf "$MSG")"
99+
Assigning you to this issue would exceed the limit of 2 open assignments.
100+
101+
Please resolve and merge your existing assigned issues before requesting new ones.
102+
EOF
103+
}
104+
105+
# Check permission level
106+
PERMISSION="$(get_permission)"
107+
echo "User permission level: $PERMISSION"
108+
109+
if [[ "$PERMISSION" == "admin" || "$PERMISSION" == "write" ]]; then
110+
echo "User is a maintainer or committer. Limit does not apply."
111+
exit 0
112+
fi
113+
114+
# Check spam status
115+
SPAM=false
116+
if is_spam_user; then
117+
SPAM=true
118+
echo "User is in spam list. Applying restricted assignment rules."
119+
fi
120+
121+
COUNT="$(assignments_count)"
122+
123+
# Apply assignment rules
124+
if [[ "$SPAM" == "true" ]]; then
125+
# Spam users can only be assigned to Good First Issues
126+
if ! issue_has_gfi; then
127+
echo "Issue does not have 'Good First Issue' label."
128+
echo "Spam-listed user attempting to assign non-GFI issue. Revoking assignment."
129+
remove_assignee
130+
post_comment "$(msg_spam_non_gfi)"
131+
exit 1
132+
fi
35133

36-
exit 1
134+
echo "Issue has 'Good First Issue' label."
135+
136+
# Spam users have a limit of 1 open assignment
137+
echo "Spam-listed user has $COUNT open assignments."
138+
139+
if (( COUNT > 1 )); then
140+
echo "Spam user limit exceeded (Max 1 allowed). Revoking assignment."
141+
remove_assignee
142+
post_comment "$(msg_spam_limit_exceeded "$COUNT")"
143+
exit 1
144+
fi
145+
146+
echo "Spam-listed user assignment valid. User has $COUNT assignment(s)."
37147
else
148+
# Normal users have a limit of 2 open assignments
149+
echo "Current open assignments count: $COUNT"
150+
151+
if (( COUNT > 2 )); then
152+
echo "Limit exceeded (Max 2 allowed). Revoking assignment."
153+
remove_assignee
154+
post_comment "$(msg_normal_limit_exceeded)"
155+
exit 1
156+
fi
157+
38158
echo "Assignment valid. User has $COUNT assignments."
39-
fi
159+
fi

.github/spam-list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
KubanjaElijahEldred

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
124124
- Issue reminder bot now explicitly mentions assignees (e.g., `@user`) in comments. ([#1232](https://github.com/hiero-ledger/hiero-sdk-python/issues/1232))
125125
- Updated `transfer_transaction_hbar.py` example to use `Hbar` objects instead of raw integers and added receipt checking with `ResponseCode` validation.([#1249](https://github.com/hiero-ledger/hiero-sdk-python/issues/1249))
126126
- Renamed `pr-missing-linked-issue.yml` and `pr_missing_linked_issue.js` to `bot-pr-missing-linked-issue.yml` and `bot-pr-missing-linked-issue.js` respectively. Enhanced LinkBot PR comment with clickable hyperlinks to documentation for linking issues and creating issues. (#1264)
127+
- Enhance assignment bot to guard against users with spam PRs `.github/scripts/bot-assignment-check.sh`
127128

128129
### Fixed
129130
- GFI workflow casing

0 commit comments

Comments
 (0)