fix: move helper functions before their first call site
The verification helpers (_is_parent_issue, _are_all_sub_issues_closed, _get_sub_issue_list) and label/comment helpers (_label_id, _add_label, _remove_label, _post_comment) were defined after the code that calls them. Under set -euo pipefail, this causes a runtime crash. Move all helper function definitions to right after the Claude session completes, before the triage post-processing and verification blocks that use them. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7a1ea91530
commit
0697f7537b
1 changed files with 127 additions and 127 deletions
|
|
@ -492,6 +492,133 @@ if [ $CLAUDE_EXIT -eq 124 ]; then
|
|||
log "WARNING: Claude session timed out after ${FORMULA_TIMEOUT_MINUTES}m"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Verification helpers — bug-report lifecycle
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Check if an issue is a parent with sub-issues (identified by sub-issues
|
||||
# whose body contains "Decomposed from #N" where N is the parent's number).
|
||||
# Returns: 0 if parent with sub-issues found, 1 otherwise
|
||||
# Sets: _PARENT_SUB_ISSUES (space-separated list of sub-issue numbers)
|
||||
_is_parent_issue() {
|
||||
local parent_num="$1"
|
||||
_PARENT_SUB_ISSUES=""
|
||||
|
||||
# Fetch all issues (open and closed) to find sub-issues
|
||||
local all_issues_json
|
||||
all_issues_json=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues?type=issues&state=all&limit=50" 2>/dev/null) || return 1
|
||||
|
||||
# Find issues whose body contains "Decomposed from #<parent_num>"
|
||||
local sub_issues
|
||||
sub_issues=$(python3 -c '
|
||||
import sys, json
|
||||
parent_num = sys.argv[1]
|
||||
data = json.load(open("/dev/stdin"))
|
||||
sub_issues = []
|
||||
for issue in data:
|
||||
body = issue.get("body") or ""
|
||||
if f"Decomposed from #{parent_num}" in body:
|
||||
sub_issues.append(str(issue["number"]))
|
||||
print(" ".join(sub_issues))
|
||||
' "$parent_num" < <(echo "$all_issues_json")) || return 1
|
||||
|
||||
if [ -n "$sub_issues" ]; then
|
||||
_PARENT_SUB_ISSUES="$sub_issues"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if all sub-issues of a parent are closed.
|
||||
# Requires: _PARENT_SUB_ISSUES to be set
|
||||
# Returns: 0 if all closed, 1 if any still open
|
||||
_are_all_sub_issues_closed() {
|
||||
if [ -z "${_PARENT_SUB_ISSUES:-}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for sub_num in $_PARENT_SUB_ISSUES; do
|
||||
local sub_state
|
||||
sub_state=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues/${sub_num}" 2>/dev/null | jq -r '.state // "unknown"') || {
|
||||
log "WARNING: could not fetch state of sub-issue #${sub_num}"
|
||||
return 1
|
||||
}
|
||||
if [ "$sub_state" != "closed" ]; then
|
||||
log "Sub-issue #${sub_num} is not closed (state: ${sub_state})"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get sub-issue details for comment
|
||||
# Returns: formatted list of sub-issues
|
||||
_get_sub_issue_list() {
|
||||
local result=""
|
||||
for sub_num in $_PARENT_SUB_ISSUES; do
|
||||
local sub_title
|
||||
sub_title=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues/${sub_num}" 2>/dev/null | jq -r '.title // "unknown"') || {
|
||||
sub_title="unknown"
|
||||
}
|
||||
result="${result}- #${sub_num} ${sub_title}"$'\n'
|
||||
done
|
||||
printf '%s' "$result"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Label helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
_label_id() {
|
||||
local name="$1" color="$2"
|
||||
local id
|
||||
id=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/labels" 2>/dev/null \
|
||||
| jq -r --arg n "$name" '.[] | select(.name == $n) | .id' 2>/dev/null || echo "")
|
||||
if [ -z "$id" ]; then
|
||||
id=$(curl -sf -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${FORGE_API}/labels" \
|
||||
-d "{\"name\":\"${name}\",\"color\":\"${color}\"}" 2>/dev/null \
|
||||
| jq -r '.id // empty' 2>/dev/null || echo "")
|
||||
fi
|
||||
echo "$id"
|
||||
}
|
||||
|
||||
_add_label() {
|
||||
local issue="$1" label_id="$2"
|
||||
[ -z "$label_id" ] && return 0
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${FORGE_API}/issues/${issue}/labels" \
|
||||
-d "{\"labels\":[${label_id}]}" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
_remove_label() {
|
||||
local issue="$1" label_id="$2"
|
||||
[ -z "$label_id" ] && return 0
|
||||
curl -sf -X DELETE \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues/${issue}/labels/${label_id}" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
_post_comment() {
|
||||
local issue="$1" body="$2"
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${FORGE_API}/issues/${issue}/comments" \
|
||||
-d "$(jq -nc --arg b "$body" '{body:$b}')" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Triage post-processing: enforce backlog label on created issues
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -793,133 +920,6 @@ if find "$(dirname "${SCREENSHOT_PREFIX}")" -name "$(basename "${SCREENSHOT_PREF
|
|||
done
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Verification helpers — bug-report lifecycle
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Check if an issue is a parent with sub-issues (identified by sub-issues
|
||||
# whose body contains "Decomposed from #N" where N is the parent's number).
|
||||
# Returns: 0 if parent with sub-issues found, 1 otherwise
|
||||
# Sets: _PARENT_SUB_ISSUES (space-separated list of sub-issue numbers)
|
||||
_is_parent_issue() {
|
||||
local parent_num="$1"
|
||||
_PARENT_SUB_ISSUES=""
|
||||
|
||||
# Fetch all issues (open and closed) to find sub-issues
|
||||
local all_issues_json
|
||||
all_issues_json=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues?type=issues&state=all&limit=50" 2>/dev/null) || return 1
|
||||
|
||||
# Find issues whose body contains "Decomposed from #<parent_num>"
|
||||
local sub_issues
|
||||
sub_issues=$(python3 -c '
|
||||
import sys, json
|
||||
parent_num = sys.argv[1]
|
||||
data = json.load(open("/dev/stdin"))
|
||||
sub_issues = []
|
||||
for issue in data:
|
||||
body = issue.get("body") or ""
|
||||
if f"Decomposed from #{parent_num}" in body:
|
||||
sub_issues.append(str(issue["number"]))
|
||||
print(" ".join(sub_issues))
|
||||
' "$parent_num" < <(echo "$all_issues_json")) || return 1
|
||||
|
||||
if [ -n "$sub_issues" ]; then
|
||||
_PARENT_SUB_ISSUES="$sub_issues"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Check if all sub-issues of a parent are closed.
|
||||
# Requires: _PARENT_SUB_ISSUES to be set
|
||||
# Returns: 0 if all closed, 1 if any still open
|
||||
_are_all_sub_issues_closed() {
|
||||
if [ -z "${_PARENT_SUB_ISSUES:-}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
for sub_num in $_PARENT_SUB_ISSUES; do
|
||||
local sub_state
|
||||
sub_state=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues/${sub_num}" 2>/dev/null | jq -r '.state // "unknown"') || {
|
||||
log "WARNING: could not fetch state of sub-issue #${sub_num}"
|
||||
return 1
|
||||
}
|
||||
if [ "$sub_state" != "closed" ]; then
|
||||
log "Sub-issue #${sub_num} is not closed (state: ${sub_state})"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get sub-issue details for comment
|
||||
# Returns: formatted list of sub-issues
|
||||
_get_sub_issue_list() {
|
||||
local result=""
|
||||
for sub_num in $_PARENT_SUB_ISSUES; do
|
||||
local sub_title
|
||||
sub_title=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues/${sub_num}" 2>/dev/null | jq -r '.title // "unknown"') || {
|
||||
sub_title="unknown"
|
||||
}
|
||||
result="${result}- #${sub_num} ${sub_title}"$'\n'
|
||||
done
|
||||
printf '%s' "$result"
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Label helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
_label_id() {
|
||||
local name="$1" color="$2"
|
||||
local id
|
||||
id=$(curl -sf \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/labels" 2>/dev/null \
|
||||
| jq -r --arg n "$name" '.[] | select(.name == $n) | .id' 2>/dev/null || echo "")
|
||||
if [ -z "$id" ]; then
|
||||
id=$(curl -sf -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${FORGE_API}/labels" \
|
||||
-d "{\"name\":\"${name}\",\"color\":\"${color}\"}" 2>/dev/null \
|
||||
| jq -r '.id // empty' 2>/dev/null || echo "")
|
||||
fi
|
||||
echo "$id"
|
||||
}
|
||||
|
||||
_add_label() {
|
||||
local issue="$1" label_id="$2"
|
||||
[ -z "$label_id" ] && return 0
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${FORGE_API}/issues/${issue}/labels" \
|
||||
-d "{\"labels\":[${label_id}]}" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
_remove_label() {
|
||||
local issue="$1" label_id="$2"
|
||||
[ -z "$label_id" ] && return 0
|
||||
curl -sf -X DELETE \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
"${FORGE_API}/issues/${issue}/labels/${label_id}" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
_post_comment() {
|
||||
local issue="$1" body="$2"
|
||||
curl -sf -X POST \
|
||||
-H "Authorization: token ${FORGE_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
"${FORGE_API}/issues/${issue}/comments" \
|
||||
-d "$(jq -nc --arg b "$body" '{body:$b}')" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Apply labels and post findings
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue