Skip to content

Commit c2fed24

Browse files
committed
fix: Fix Bot API
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
1 parent ea81547 commit c2fed24

File tree

3 files changed

+174
-57
lines changed

3 files changed

+174
-57
lines changed
Lines changed: 151 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,194 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22
set -euo pipefail
33

4-
# 1. Define Helper Functions First
4+
#######################################
5+
# Logging helper
6+
#######################################
57
log() {
68
echo "[advanced-check] $1"
79
}
810

9-
# 2. Validate required environment variables
10-
if [[ -z "${REPO:-}" ]] || [[ -z "${ISSUE_NUMBER:-}" ]] || [[ -z "${GH_TOKEN:-}" ]]; then
11-
log "ERROR: Required environment variables (REPO, ISSUE_NUMBER, GH_TOKEN) must be set"
11+
#######################################
12+
# Validate required environment variables
13+
#######################################
14+
if [[ -z "${REPO:-}" ]]; then
15+
log "ERROR: REPO must be set (e.g. owner/name)"
1216
exit 1
1317
fi
1418

15-
# 3. Function to check a single user
19+
OWNER="${REPO%%/*}"
20+
NAME="${REPO##*/}"
21+
22+
#######################################
23+
# GraphQL count helper (INTERMEDIATE ONLY)
24+
#######################################
25+
get_intermediate_count() {
26+
local user=$1
27+
28+
gh api graphql -f query="
29+
{
30+
repository(owner: \"$OWNER\", name: \"$NAME\") {
31+
intermediate: issues(
32+
first: 1
33+
states: CLOSED
34+
filterBy: {
35+
assignee: \"$user\"
36+
labels: [\"intermediate\"]
37+
}
38+
) {
39+
totalCount
40+
}
41+
}
42+
}"
43+
}
44+
45+
#######################################
46+
# Helper: has bot already commented for user?
47+
#######################################
48+
already_commented() {
49+
local user=$1
50+
51+
gh issue view "$ISSUE_NUMBER" --repo "$REPO" \
52+
--json comments \
53+
--jq --arg user "@$user" '
54+
.comments[].body
55+
| select(test("Hi " + $user + ", I cannot assign you to this issue yet."))
56+
' | grep -q .
57+
}
58+
59+
#######################################
60+
# Helper: is user currently assigned?
61+
#######################################
62+
is_assigned() {
63+
local user=$1
64+
65+
gh issue view "$ISSUE_NUMBER" --repo "$REPO" \
66+
--json assignees \
67+
--jq --arg user "$user" '
68+
.assignees[].login | select(. == $user)
69+
' | grep -q .
70+
}
71+
72+
#######################################
73+
# DRY RUN MODE
74+
#######################################
75+
if [[ "${DRY_RUN:-false}" == "true" ]]; then
76+
if [[ -z "${DRY_RUN_USER:-}" ]]; then
77+
log "ERROR: DRY_RUN_USER must be set when DRY_RUN=true"
78+
exit 1
79+
fi
80+
81+
USER="$DRY_RUN_USER"
82+
log "DRY RUN MODE ENABLED"
83+
log "Repository: $REPO"
84+
log "User: @$USER"
85+
86+
COUNTS=$(get_intermediate_count "$USER")
87+
INT_COUNT=$(jq '.data.repository.intermediate.totalCount' <<<"$COUNTS")
88+
89+
echo
90+
log "Intermediate Issues (closed): $INT_COUNT"
91+
92+
if (( INT_COUNT >= 1 )); then
93+
log "Result: USER QUALIFIED"
94+
else
95+
log "Result: USER NOT QUALIFIED"
96+
fi
97+
98+
exit 0
99+
fi
100+
101+
#######################################
102+
# NORMAL MODE (ENFORCEMENT)
103+
#######################################
104+
if [[ -z "${ISSUE_NUMBER:-}" ]]; then
105+
log "ERROR: ISSUE_NUMBER must be set in normal mode"
106+
exit 1
107+
fi
108+
109+
#######################################
110+
# Check a single user
111+
#######################################
16112
check_user() {
17113
local user=$1
18114
log "Checking qualification for @$user..."
19115

20116
# Permission exemption
21-
PERM_JSON=$(gh api "repos/$REPO/collaborators/$user/permission" 2>/dev/null || echo '{"permission":"none"}')
22-
PERMISSION=$(echo "$PERM_JSON" | jq -r '.permission // "none"')
117+
PERMISSION=$(
118+
gh api "repos/$REPO/collaborators/$user/permission" \
119+
--jq '.permission // "none"' 2>/dev/null || echo "none"
120+
)
23121

24122
if [[ "$PERMISSION" =~ ^(admin|write|triage)$ ]]; then
25-
log "User @$user is core member ($PERMISSION). Qualification check skipped."
123+
log "User @$user is core member ($PERMISSION). Skipping."
26124
return 0
27125
fi
28126

29-
# 2. Get counts
30-
# Using exact repository label names ("Good First Issue" and "intermediate")
31-
GFI_QUERY="repo:$REPO is:issue is:closed assignee:$user -reason:\"not planned\" label:\"Good First Issue\""
32-
INT_QUERY="repo:$REPO is:issue is:closed assignee:$user -reason:\"not planned\" label:\"intermediate\""
33-
34-
GFI_COUNT=$(gh api "search/issues" -f q="$GFI_QUERY" --jq '.total_count' || echo "0")
35-
INT_COUNT=$(gh api "search/issues" -f q="$INT_QUERY" --jq '.total_count' || echo "0")
127+
COUNTS=$(get_intermediate_count "$user")
128+
INT_COUNT=$(jq '.data.repository.intermediate.totalCount' <<<"$COUNTS")
36129

37-
# Numeric validation
38-
if ! [[ "$GFI_COUNT" =~ ^[0-9]+$ ]]; then GFI_COUNT=0; fi
39-
if ! [[ "$INT_COUNT" =~ ^[0-9]+$ ]]; then INT_COUNT=0; fi
130+
log "Counts → Intermediate: $INT_COUNT"
40131

41-
# Validation Logic
42-
if (( GFI_COUNT >= 1 )) && (( INT_COUNT >= 1 )); then
132+
if (( INT_COUNT >= 1 )); then
43133
log "User @$user qualified."
44134
return 0
45-
else
46-
log "User @$user failed. Unassigning..."
135+
fi
47136

48-
# Tailor the suggestion based on what is missing
49-
# Links and names now match exact repository labels
50-
if (( GFI_COUNT == 0 )); then
51-
SUGGESTION="[Good First Issue](https://github.com/$REPO/labels/Good%20First%20Issue)"
52-
else
53-
SUGGESTION="[intermediate issue](https://github.com/$REPO/labels/intermediate)"
54-
fi
137+
###################################
138+
# Failure path (duplicate-safe)
139+
###################################
140+
log "User @$user NOT qualified."
55141

56-
# Post the message FIRST, then unassign.
57-
MSG="Hi @$user, I cannot assign you to this issue yet.
142+
SUGGESTION="[intermediate issues](https://github.com/$REPO/labels/intermediate)"
143+
144+
MSG="Hi @$user, I cannot assign you to this issue yet.
58145
59146
**Why?**
60-
Advanced issues involve high-risk changes to the core codebase. They require significant testing and can impact automation and CI behavior.
147+
Advanced issues involve high-risk changes to the core codebase and require prior experience in this repository.
61148
62149
**Requirement:**
63-
- Complete at least **1** 'Good First Issue' (You have: **$GFI_COUNT**)
64150
- Complete at least **1** 'intermediate' issue (You have: **$INT_COUNT**)
65151
66-
Please check out our **$SUGGESTION** tasks to build your experience first!"
152+
Please check out our **$SUGGESTION** to build your experience first!"
67153

154+
if already_commented "$user"; then
155+
log "Comment already exists for @$user. Skipping comment."
156+
else
157+
log "Posting comment for @$user."
68158
gh issue comment "$ISSUE_NUMBER" --repo "$REPO" --body "$MSG"
159+
fi
160+
161+
if is_assigned "$user"; then
162+
log "Unassigning @$user."
69163
gh issue edit "$ISSUE_NUMBER" --repo "$REPO" --remove-assignee "$user"
164+
else
165+
log "User @$user already unassigned. Skipping."
70166
fi
71167
}
72168

73-
# --- Main Logic ---
169+
#######################################
170+
# Main execution
171+
#######################################
172+
log "Normal enforcement mode enabled"
173+
log "Repository: $REPO"
174+
log "Issue: #$ISSUE_NUMBER"
74175

75176
if [[ -n "${TRIGGER_ASSIGNEE:-}" ]]; then
76177
check_user "$TRIGGER_ASSIGNEE"
77178
else
78-
log "Checking all current assignees..."
79-
80-
# Fetch assignees into a variable first.
81-
ASSIGNEE_LIST=$(gh issue view "$ISSUE_NUMBER" --repo "$REPO" --json assignees --jq '.assignees[].login')
179+
log "Checking all assignees..."
82180

83-
if [[ -z "$ASSIGNEE_LIST" ]]; then
84-
log "No assignees found to check."
85-
else
86-
# Use a here-string (<<<) to iterate over the variable safely.
87-
while read -r user; do
88-
if [[ -n "$user" ]]; then
89-
check_user "$user"
90-
fi
91-
done <<< "$ASSIGNEE_LIST"
181+
ASSIGNEES=$(
182+
gh issue view "$ISSUE_NUMBER" --repo "$REPO" \
183+
--json assignees --jq '.assignees[].login'
184+
)
185+
186+
if [[ -z "$ASSIGNEES" ]]; then
187+
log "No assignees found."
188+
exit 0
92189
fi
93-
fi
190+
191+
while read -r user; do
192+
[[ -n "$user" ]] && check_user "$user"
193+
done <<< "$ASSIGNEES"
194+
fi

.github/workflows/bot-advanced-check.yml

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,40 @@ on:
44
issues:
55
types: [assigned, labeled]
66

7+
workflow_dispatch:
8+
inputs:
9+
username:
10+
description: "GitHub username to dry-run qualification check"
11+
required: true
12+
type: string
13+
714
permissions:
815
issues: write
916

1017
concurrency:
11-
group: ${{ github.workflow }}-${{ github.event.issue.number }}
18+
group: ${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}
1219
cancel-in-progress: true
1320

1421
jobs:
22+
#######################################
23+
# Automatic enforcement (issues)
24+
#######################################
1525
check-advanced-qualification:
16-
# Run only for issues labeled 'advanced', triggered by assignment or by adding
17-
# the label to an issue that already has assignees
1826
if: >
19-
contains(github.event.issue.labels.*.name, 'advanced') &&
20-
(github.event.action == 'assigned' || (github.event.action == 'labeled' && github.event.issue.assignees[0] != null))
27+
github.event_name == 'issues' &&
28+
contains(github.event.issue.labels.*.name, 'advanced') &&
29+
(
30+
github.event.action == 'assigned' ||
31+
(
32+
github.event.action == 'labeled' &&
33+
github.event.label.name == 'advanced' &&
34+
github.event.issue.assignees[0] != null
35+
)
36+
)
37+
2138
runs-on: ubuntu-latest
2239
steps:
2340
- name: Checkout scripts
24-
# Pinned to v6.0.1 (8e8c483db84b4bee98b60c0593521ed34d9990e8)
25-
# Followed guide: https://github.com/actions/checkout/releases
2641
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
2742
with:
2843
sparse-checkout: .github/scripts

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ This changelog is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.
158158
- Modified and renamed hasIntermediateOrAdvancedLabel() to check if issue label is beginner or higher (#1385)
159159

160160
### Fixed
161+
- Fixed bot advanced check bash script to correctly handle API calls and prevent incorrect issue unassignments. (#PR TBD)
161162
- GFI workflow casing
162163
- Update `bot-workflows.yml` to trigger only on open PRs with failed workflows; ignore closed PRs and branches without open PRs.
163164
- Fixed step-security/harden-runner action SHA in merge conflict bot workflow (#1278)

0 commit comments

Comments
 (0)