diff --git a/scripts/generate-release-notes.sh b/scripts/generate-release-notes.sh index 849a169a8..ab6d8beb4 100755 --- a/scripts/generate-release-notes.sh +++ b/scripts/generate-release-notes.sh @@ -224,6 +224,132 @@ JSON printf '%s' "$content" } +# Pretty-print a section of notes (expects array name) +print_section() { + local ref="$1" + declare -n arr_ref="$ref" + if [ ${#arr_ref[@]} -eq 0 ]; then + echo "None" + return + fi + + local item + for item in "${arr_ref[@]}"; do + echo "- ${item}" + done +} + +# Deterministic fallback when no LLM providers are available +generate_fallback_release_notes() { + local subjects=() + mapfile -t subjects < <(echo "$COMMIT_LOG" | sed 's/^[0-9a-f]\+ //') + + local features=() + local bugs=() + local improvements=() + local breakings=() + + local subject lower + for subject in "${subjects[@]}"; do + [ -z "$subject" ] && continue + lower=$(echo "$subject" | tr '[:upper:]' '[:lower:]') + if [[ "$lower" =~ (feat|feature|add|introduc|support|new) ]]; then + features+=("$subject") + elif [[ "$lower" =~ (fix|bug|issue|patch|regress|correct) ]]; then + bugs+=("$subject") + elif [[ "$lower" =~ (breaking|deprecat|remove|drop|incompatib) ]]; then + breakings+=("$subject") + else + improvements+=("$subject") + fi + done + + if [ ${#improvements[@]} -eq 0 ] && [ ${#features[@]} -eq 0 ] && [ ${#bugs[@]} -eq 0 ]; then + improvements=("${subjects[@]}") + fi + + local notes=() + for subject in "${subjects[@]}"; do + notes+=("$subject") + [ ${#notes[@]} -ge 3 ] && break + done + if [ ${#notes[@]} -eq 0 ]; then + notes+=("Routine maintenance and dependency updates.") + fi + + { + echo "## What's Changed" + echo "" + echo "### New Features" + print_section features + echo "" + echo "### Bug Fixes" + print_section bugs + echo "" + echo "### Improvements" + print_section improvements + echo "" + echo "### Breaking Changes" + print_section breakings + echo "" + echo "## Installation" + echo "" + echo "**Quick Install (systemd / LXC / Proxmox VE):**" + cat <<'EOQI' +```bash +curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | bash +``` +EOQI + echo "" + echo "**Docker:**" + cat <&2 if ! RELEASE_NOTES=$(generate_with_openai); then - echo "Error: OpenAI fallback failed as well" >&2 - exit 1 + echo "OpenAI fallback failed; generating heuristic release notes." >&2 + RELEASE_NOTES=$(generate_fallback_release_notes) fi LLM_PROVIDER="openai" else - echo "Error: Failed to generate release notes via Anthropic and no OpenAI fallback is available" >&2 - exit 1 + echo "Anthropic generation failed and no OpenAI fallback is available; generating heuristic release notes." >&2 + RELEASE_NOTES=$(generate_fallback_release_notes) fi fi else if ! RELEASE_NOTES=$(generate_with_openai); then - echo "Error: Failed to generate release notes via OpenAI" >&2 - exit 1 + echo "OpenAI generation failed; generating heuristic release notes." >&2 + RELEASE_NOTES=$(generate_fallback_release_notes) fi fi +if [ -z "$RELEASE_NOTES" ] || [ "$RELEASE_NOTES" = "null" ]; then + echo "Error: Release notes generation returned empty content" >&2 + exit 1 +fi + # Output release notes echo "" echo "Generated release notes:"