@@ -85,15 +85,28 @@ gh api -X GET search/issues --paginate -f q="$QUERY" --jq '.items[]' \
8585 | jq -s ' unique_by(.html_url)' > " $ITEMS_FILE "
8686
8787if [ " $OUTPUT " = " json" ]; then
88- cat " $ITEMS_FILE "
88+ # Enrich each item with its comments and a trimmed set of fields, so the
89+ # release-note text (which authors write free-form, in the body OR a
90+ # comment) is available in one place for a human/agent to read and
91+ # interpret. Deliberately NO regex extraction here - see the note below.
92+ jq -c ' .[]' " $ITEMS_FILE " | while IFS= read -r item; do
93+ full=$( echo " $item " | jq -r ' .repository_url | sub(".*/repos/";"")' )
94+ number=$( echo " $item " | jq -r ' .number' )
95+ comments=$( gh api " repos/$full /issues/$number /comments" --jq ' [.[] | {author: .user.login, body}]' 2> /dev/null || echo ' []' )
96+ echo " $item " | jq -c --argjson comments " $comments " ' {
97+ repo: (.repository_url | sub(".*/repos/";"")),
98+ number, title, html_url, state,
99+ is_pr: (.pull_request != null),
100+ merged: (.pull_request.merged_at != null),
101+ labels: [.labels[].name],
102+ action_required: (any(.labels[].name; . == "release-note/action-required")),
103+ body: (.body // ""),
104+ comments: $comments
105+ }'
106+ done | jq -s ' .'
89107 exit 0
90108fi
91109
92- # ------------------------------
93- # Helper: is this item an action-required one?
94- # ------------------------------
95- is_action_required () { echo " $1 " | jq -e ' any(.labels[].name; . == "release-note/action-required")' > /dev/null; }
96-
97110# ------------------------------
98111# Counts (ground truth = number of items actually returned)
99112# ------------------------------
@@ -139,48 +152,34 @@ echo "$OPEN_PRS"
139152echo
140153
141154# ------------------------------
142- # Items grouped by repository, with release-note snippet
155+ # Item inventory grouped by repository (metadata only).
156+ #
157+ # NOTE: we deliberately do NOT try to extract the release-note text here.
158+ # Authors write it free-form - under headings like `### Release notes`, an
159+ # inline `Release-Note:` label, a bare `# Release notes` in a *linked* comment,
160+ # or interleaved with reviewer instructions. A regex can't reliably tell a real
161+ # note from a template checklist line ("- [ ] Release note snippet added") or
162+ # reviewer chatter. Reading and interpreting that text is the skill's job:
163+ # run this script with `--json` to get each item's full body + comments, then
164+ # read them. This inventory is just the deterministic "what's in the release".
143165# ------------------------------
144- echo " ## Items grouped by repository"
166+ echo " ## Item inventory grouped by repository"
167+ echo " # For the release-note text of each item, run this script with --json and read the body + comments."
145168
146169REPOS=$( jq -r ' [.[] | .repository_url | sub(".*/repos/stackabletech/";"")] | unique | .[]' " $ITEMS_FILE " )
147170
148171while IFS= read -r repo; do
149172 [ -z " $repo " ] && continue
150173 echo
151174 echo " ### $repo "
152- # Iterate items for this repo (compact JSON per line)
153- jq -c --arg R " $repo " ' .[] | select((.repository_url | sub(".*/repos/stackabletech/";"")) == $R)' " $ITEMS_FILE " \
154- | while IFS= read -r item; do
155- number=$( echo " $item " | jq -r ' .number' )
156- title=$( echo " $item " | jq -r ' .title' )
157- url=$( echo " $item " | jq -r ' .html_url' )
158- labels=$( echo " $item " | jq -r ' [.labels[].name] | join(", ")' )
159- if echo " $item " | jq -e ' .pull_request == null' > /dev/null; then
160- kind=" issue"
161- elif echo " $item " | jq -e ' .pull_request.merged_at != null' > /dev/null; then
162- kind=" PR-merged"
163- else
164- kind=" PR-$( echo " $item " | jq -r ' .state' ) "
165- fi
166- marker=" "
167- if is_action_required " $item " ; then marker=" **ACTION-REQUIRED**" ; fi
168-
169- echo " - #$number [$kind ]$marker $title "
170- echo " $url "
171- echo " labels: $labels "
172- # Extract the "Release note(s)" section from the body, if present.
173- snippet=$( echo " $item " | jq -r ' .body // ""' | awk '
174- BEGIN { grab=0 }
175- /^#+[[:space:]]*[Rr]elease[[:space:]]*[Nn]ote/ { grab=1; next }
176- grab && /^#+[[:space:]]/ { exit }
177- grab { print }
178- ' | sed ' s/^/ /' | sed ' /^[[:space:]]*$/d' )
179- if [ -n " $snippet " ]; then
180- echo " release-note snippet:"
181- echo " $snippet "
182- else
183- echo " release-note snippet: (none found in body)"
184- fi
185- done
175+ jq -r --arg R " $repo " '
176+ def kind: if .pull_request == null then "issue"
177+ elif .pull_request.merged_at != null then "PR-merged"
178+ else "PR-" + .state end;
179+ def ar: if any(.labels[].name; . == "release-note/action-required")
180+ then " **ACTION-REQUIRED**" else "" end;
181+ [.[] | select((.repository_url | sub(".*/repos/stackabletech/";"")) == $R)]
182+ | sort_by(.number)[]
183+ | "- #\(.number) [\(kind)]\(ar) \(.title)\n \(.html_url)\n labels: \([.labels[].name] | join(", "))"
184+ ' " $ITEMS_FILE "
186185done <<< " $REPOS"
0 commit comments