Skip to content

Commit a8f95fa

Browse files
authored
Merge branch 'hiero-ledger:main' into main
2 parents 81bcf2a + 8fd18fc commit a8f95fa

33 files changed

Lines changed: 1193 additions & 305 deletions

.github/mentor_roster.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
"exploreriii",
88
"Adityarya11",
99
"tech0priyanshu",
10-
"Akshat8510"
10+
"Akshat8510",
11+
"Mounil2005",
12+
"parvninama",
13+
"drtoxic69",
14+
"prajeeta15",
15+
"undefinedIsMyLife",
16+
"cheese-cakee"
1117
]
1218
}

.github/scripts/bot-assignment-check.sh

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ issue_has_gfi() {
3636
}
3737

3838
assignments_count() {
39-
gh issue list --repo "${REPO}" --assignee "${ASSIGNEE}" --state open --limit 100 --json number --jq 'length'
39+
# Count only issues (not PRs) assigned to the user, using structured isPullRequest field
40+
gh issue list --repo "${REPO}" --assignee "${ASSIGNEE}" --state open --limit 100 --json number,isPullRequest --jq '[.[] | select(.isPullRequest | not)] | length'
4041
}
4142

4243
remove_assignee() {
@@ -75,12 +76,12 @@ Hi @$ASSIGNEE, this is the Assignment Bot.
7576
7677
:warning: **Assignment Limit Exceeded**
7778
78-
Your account currently has limited assignment privileges with a maximum of **1 open assignment** at a time.
79+
Your account currently has limited assignment privileges with a maximum of **1 open issue assignment** at a time.
7980
8081
You currently have $count open issue(s) assigned. Please complete and merge your existing assignment before requesting a new one.
8182
8283
**Current Restrictions:**
83-
- Maximum 1 open assignment at a time
84+
- Maximum 1 open issue assignment at a time
8485
- Can only be assigned to 'Good First Issue' labeled issues
8586
8687
**How to have restrictions lifted:**
@@ -96,7 +97,7 @@ msg_normal_limit_exceeded() {
9697
cat <<EOF
9798
Hi @$ASSIGNEE, this is the Assignment Bot.
9899
99-
Assigning you to this issue would exceed the limit of 2 open assignments.
100+
Assigning you to this issue would exceed the limit of 2 open issue assignments.
100101
101102
Please resolve and merge your existing assigned issues before requesting new ones.
102103
EOF

.github/scripts/bot-issue-reminder-no-pr.sh

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,31 @@ echo "$ALL_ISSUES_JSON" | jq -c '.' | while read -r ISSUE_JSON; do
132132
fi
133133

134134
# Get assignment time (use the last assigned event)
135-
ASSIGN_TS=$(gh api "repos/$REPO/issues/$ISSUE/events" \
136-
--jq ".[] | select(.event==\"assigned\") | .created_at" \
137-
| tail -n1)
135+
if ! ASSIGN_TS=$(gh api graphql -f query="
136+
query {
137+
repository(owner: \"${REPO%/*}\", name: \"${REPO#*/}\") {
138+
issue(number: $ISSUE) {
139+
timelineItems(itemTypes: [ASSIGNED_EVENT], last: 1) {
140+
nodes {
141+
... on AssignedEvent {
142+
createdAt
143+
assignee {
144+
__typename
145+
... on User { login }
146+
}
147+
}
148+
}
149+
}
150+
}
151+
}
152+
}
153+
" --jq '.data.repository.issue.timelineItems.nodes[0].createdAt' 2>&1); then
154+
echo "[WARN] GraphQL query failed for issue #$ISSUE: $ASSIGN_TS. Skipping."
155+
continue
156+
fi
138157

139-
if [ -z "$ASSIGN_TS" ]; then
140-
echo "[WARN] No assignment event found. Skipping."
158+
if [ -z "$ASSIGN_TS" ] || [ "$ASSIGN_TS" = "null" ]; then
159+
echo "[WARN] No assignment event found for issue #$ISSUE. Skipping."
141160
continue
142161
fi
143162

@@ -148,24 +167,17 @@ echo "$ALL_ISSUES_JSON" | jq -c '.' | while read -r ISSUE_JSON; do
148167
echo "[INFO] Days since assignment: $DIFF_DAYS"
149168

150169
# Check if any open PRs are linked to this issue
151-
PR_NUMBERS=$(gh api \
152-
-H "Accept: application/vnd.github.mockingbird-preview+json" \
153-
"repos/$REPO/issues/$ISSUE/timeline" \
154-
--jq ".[]
155-
| select(.event == \"cross-referenced\")
156-
| select(.source.issue.pull_request != null)
157-
| .source.issue.number" 2>/dev/null || true)
158-
159-
OPEN_PR_FOUND=""
160-
if [ -n "$PR_NUMBERS" ]; then
161-
for PR_NUM in $PR_NUMBERS; do
162-
PR_STATE=$(gh pr view "$PR_NUM" --repo "$REPO" --json state --jq '.state' 2>/dev/null || true)
163-
if [ "$PR_STATE" = "OPEN" ]; then
164-
OPEN_PR_FOUND="$PR_NUM"
165-
break
166-
fi
167-
done
168-
fi
170+
OPEN_PR_FOUND=$(gh api graphql -f query="
171+
query {
172+
repository(owner: \"${REPO%/*}\", name: \"${REPO#*/}\") {
173+
issue(number: $ISSUE) {
174+
closedByPullRequestsReferences(first: 100, includeClosedPrs: false) {
175+
nodes { number state }
176+
}
177+
}
178+
}
179+
}
180+
" --jq '[.data.repository.issue.closedByPullRequestsReferences.nodes[] | select(.state == "OPEN") | .number] | first // empty' 2>&1) || true
169181

170182
if [ -n "$OPEN_PR_FOUND" ]; then
171183
echo "[KEEP] An OPEN PR #$OPEN_PR_FOUND is linked to this issue → skip reminder."

.github/scripts/pr-check-changelog.sh

Lines changed: 127 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/bin/bash
2-
2+
set -euo pipefail
33
# ==============================================================================
44
# Executes When:
55
# - Run by GitHub Actions workflow: .github/workflows/pr-check-changelog.yml
@@ -61,6 +61,7 @@
6161
#
6262
# Dependencies:
6363
# - git (must be able to fetch upstream)
64+
# - jq (required for PR context parsing)
6465
# - grep, sed (standard Linux utilities)
6566
# - CHANGELOG.md (file must exist in the root directory)
6667
#
@@ -76,6 +77,32 @@
7677

7778
CHANGELOG="CHANGELOG.md"
7879

80+
# Ensure jq is available (required for PR context + comments)
81+
command -v jq >/dev/null || {
82+
echo "❌ jq is required but not installed"
83+
exit 1
84+
}
85+
86+
# Validate required environment variables
87+
: "${GITHUB_EVENT_PATH:?GITHUB_EVENT_PATH is not set}"
88+
: "${GITHUB_REPOSITORY:?GITHUB_REPOSITORY is not set}"
89+
90+
# PR Number
91+
PR_NUMBER=$(jq -r '.pull_request.number // empty' "$GITHUB_EVENT_PATH")
92+
if [[ -n "$PR_NUMBER" ]] && ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
93+
echo "❌ Invalid PR_NUMBER: $PR_NUMBER"
94+
exit 1
95+
fi
96+
97+
# GITHUB_TOKEN is only required for PR commenting
98+
if [[ -n "$PR_NUMBER" ]]; then
99+
: "${GITHUB_TOKEN:?GITHUB_TOKEN is required for PR commenting but is not set}"
100+
fi
101+
102+
# Marker
103+
MISSING_MARKER="<!-- changelog-missing-bot -->"
104+
WRONG_SECTION_MARKER="<!-- changelog-wrong-section-bot -->"
105+
79106
# ANSI color codes
80107
RED="\033[31m"
81108
GREEN="\033[32m"
@@ -88,6 +115,57 @@ failed=0
88115
git remote add upstream https://github.com/${GITHUB_REPOSITORY}.git
89116
git fetch upstream main >/dev/null 2>&1
90117

118+
#PR Comment
119+
DRY_RUN="${DRY_RUN:-false}"
120+
post_pr_comment() {
121+
local message="$1"
122+
123+
# Only comment if this is a PR (not workflow_dispatch)
124+
if [[ -z "$PR_NUMBER" ]]; then
125+
echo "ℹ️ No PR_NUMBER set — skipping comment."
126+
return
127+
fi
128+
129+
if [[ "$DRY_RUN" == "true" ]]; then
130+
echo "🔍 [DRY RUN] Would post PR comment on #${PR_NUMBER}"
131+
return
132+
fi
133+
134+
local http_code
135+
http_code=$(curl -sS -o /dev/null -w "%{http_code}" -X POST \
136+
-H "Authorization: Bearer $GITHUB_TOKEN" \
137+
-H "Accept: application/vnd.github+json" \
138+
"https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \
139+
-d "$(jq -n --arg body "$message" '{body: $body}')")
140+
141+
if [[ "$http_code" -lt 200 || "$http_code" -ge 300 ]]; then
142+
echo "⚠️ Failed to post PR comment (HTTP $http_code)"
143+
fi
144+
}
145+
146+
comment_already_exists() {
147+
local marker="$1"
148+
149+
if [[ -z "$PR_NUMBER" ]]; then
150+
return 1
151+
fi
152+
153+
local comments
154+
comments=$(curl -s \
155+
-H "Authorization: Bearer $GITHUB_TOKEN" \
156+
-H "Accept: application/vnd.github+json" \
157+
"https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments?per_page=100")
158+
159+
if ! echo "$comments" | jq -e 'type == "array"' >/dev/null 2>&1; then
160+
echo "⚠️ Failed to fetch PR comments — assuming marker absent"
161+
return 1
162+
fi
163+
164+
echo "$comments" | jq -e --arg marker "$marker" '
165+
.[] | select(.body | contains($marker))
166+
' >/dev/null
167+
}
168+
91169
# Get raw diff
92170
raw_diff=$(git diff upstream/main -- "$CHANGELOG")
93171

@@ -119,7 +197,21 @@ done < <(echo "$raw_diff" | grep '^\-' | grep -vE '^(--- |\+\+\+ |@@ )' | sed 's
119197
# 2️⃣b Warn if no added entries
120198
if [[ ${#added_bullets[@]} -eq 0 ]]; then
121199
echo -e "${RED}❌ No new changelog entries detected in this PR.${RESET}"
122-
echo -e "${YELLOW}⚠️ Please add an entry in [UNRELEASED] under the appropriate subheading.${RESET}"
200+
echo -e "${YELLOW}⚠️ Please add an entry in [Unreleased] under the appropriate subheading.${RESET}"
201+
202+
if ! comment_already_exists "$MISSING_MARKER"; then
203+
post_pr_comment "$MISSING_MARKER
204+
👋 **Changelog reminder**
205+
206+
This PR appears to resolve an issue, but no entry was found in **CHANGELOG.md**.
207+
208+
📌 In this repository, all resolved issues — including docs, CI, and workflow changes — are expected to include a changelog entry under **[Unreleased]**, grouped by category (e.g. *Added*, *Fixed*).
209+
210+
If this PR should not require a changelog entry, feel free to clarify in the discussion. Thanks! 🙌"
211+
else
212+
echo "⚠️ Changelog bot comment already exists, skipping"
213+
fi
214+
123215
failed=1
124216
fi
125217

@@ -133,15 +225,17 @@ current_release=""
133225
current_subtitle=""
134226
in_unreleased=0
135227

228+
shopt -s extglob
229+
136230
while IFS= read -r line; do
137231
# Track release sections
138232
if [[ $line =~ ^##\ \[Unreleased\] ]]; then
139233
current_release="Unreleased"
140234
in_unreleased=1
141235
current_subtitle=""
142236
continue
143-
elif [[ $line =~ ^##\ \[.*\] ]]; then
144-
current_release="$line"
237+
elif [[ $line =~ ^#{1,2}\ \[([0-9]+\.[0-9]+\.[0-9]+)\] ]]; then
238+
current_release="${BASH_REMATCH[1]}"
145239
in_unreleased=0
146240
current_subtitle=""
147241
continue
@@ -151,14 +245,18 @@ while IFS= read -r line; do
151245
fi
152246

153247
# Check each added bullet
248+
249+
normalized_line="${line%%+([[:space:]])}"
154250
for added in "${added_bullets[@]}"; do
155-
if [[ "$line" == "$added" ]]; then
251+
normalized_added="${added%%+([[:space:]])}"
252+
253+
if [[ "$normalized_line" == "$normalized_added" ]]; then
156254
if [[ "$in_unreleased" -eq 1 && -n "$current_subtitle" ]]; then
157255
correctly_placed+="$added (placed under $current_subtitle)"$'\n'
158256
elif [[ "$in_unreleased" -eq 1 && -z "$current_subtitle" ]]; then
159257
orphan_entries+="$added (NOT under a subtitle)"$'\n'
160258
elif [[ "$in_unreleased" -eq 0 ]]; then
161-
wrong_release_entries+="$added (added under released version $current_release)"$'\n'
259+
wrong_release_entries+="$added (added under released version [$current_release], expected under [Unreleased])"$'\n'
162260
fi
163261
fi
164262
done
@@ -174,6 +272,29 @@ fi
174272
if [[ -n "$wrong_release_entries" ]]; then
175273
echo -e "${RED}❌ Some changelog entries were added under a released version (should be in [Unreleased]):${RESET}"
176274
echo "$wrong_release_entries"
275+
276+
if ! comment_already_exists "$WRONG_SECTION_MARKER"; then
277+
post_pr_comment "$WRONG_SECTION_MARKER
278+
⚠️ **Changelog placement issue**
279+
280+
Thanks for adding a changelog entry! 🙌
281+
However, one or more entries in this PR were added under a **released version**.
282+
283+
📌 New changelog entries should always go under **[Unreleased]**, grouped beneath an appropriate category (e.g. *Added*, *Fixed*).
284+
285+
Please move the following entries to **[Unreleased]**:
286+
287+
\`\`\`
288+
$wrong_release_entries
289+
\`\`\`
290+
291+
292+
Let us know if you’re unsure where it should live — happy to help!"
293+
294+
else
295+
echo "⚠️ Changelog bot comment already exists, skipping"
296+
fi
297+
177298
failed=1
178299
fi
179300

0 commit comments

Comments
 (0)