From bb43625f1e6cb64a2df543894918121041818544 Mon Sep 17 00:00:00 2001 From: selmankoc Date: Wed, 20 May 2026 18:21:32 +0300 Subject: [PATCH] docs(studio): update release notes formatting rules for clarity and user-friendliness --- .github/workflows/update-studio-docs.yml | 130 ++++++++++++++--------- 1 file changed, 80 insertions(+), 50 deletions(-) diff --git a/.github/workflows/update-studio-docs.yml b/.github/workflows/update-studio-docs.yml index 9e16b07280..fd258051e6 100644 --- a/.github/workflows/update-studio-docs.yml +++ b/.github/workflows/update-studio-docs.yml @@ -213,17 +213,18 @@ jobs: CRITICAL RULES: 1. Extract ONLY essential, user-facing changes - 2. Format as bullet points starting with "- " - 3. Keep it concise and professional + 2. Format as markdown bullet points starting with "* " + 3. Keep it concise, friendly and easy to scan 4. Match the style of existing release notes 5. Skip internal/technical details unless critical 6. Return ONLY the bullet points (no version header, no date) 7. One change per line + 8. Prefer short action-oriented summaries like "AI Agent Upgrades: Added browser automation tools" Output example: - - Fixed books sample for blazor-webapp tiered solution - - Enhanced Module Installation UI - - Added AI Management option to Startup Templates + * AI Agent Upgrades: Added browser automation tools + * Module Setup Improvements: Added guidance for modularity options + * UI Polish: Improved sidebar icons and visual consistency Return ONLY the formatted bullet points. @@ -240,56 +241,85 @@ jobs: echo "✅ Using AI-formatted release notes" echo "$AI_RESPONSE" > .tmp/final-notes.txt else - echo "⚠️ AI unavailable - using aggressive cleaning on raw release notes" - - # Clean and format raw notes with aggressive filtering - echo "$RAW_NOTES" | while IFS= read -r line; do - # Skip empty lines - [ -z "$line" ] && continue - - # Skip section headers - [[ "$line" =~ ^#+.*What.*Changed ]] && continue - [[ "$line" =~ ^##[[:space:]] ]] && continue - - # Skip full changelog links - [[ "$line" =~ ^\*\*Full\ Changelog ]] && continue - [[ "$line" =~ ^Full\ Changelog ]] && continue - - # Remove leading bullet/asterisk - line=$(echo "$line" | sed 's/^[[:space:]]*[*-][[:space:]]*//') - - # Aggressive cleaning: remove entire " by @user in https://..." suffix - line=$(echo "$line" | sed 's/[[:space:]]*by @[a-zA-Z0-9_-]*[[:space:]]*in https:\/\/github\.com\/[^[:space:]]*//g') - - # Remove remaining "by @username" or "by username" - line=$(echo "$line" | sed 's/[[:space:]]*by @[a-zA-Z0-9_-]*[[:space:]]*$//g') - line=$(echo "$line" | sed 's/[[:space:]]*by [a-zA-Z0-9_-]*[[:space:]]*$//g') - - # Remove standalone @mentions - line=$(echo "$line" | sed 's/@[a-zA-Z0-9_-]*//g') - - # Clean trailing periods if orphaned - line=$(echo "$line" | sed 's/\.[[:space:]]*$//') - - # Trim all whitespace - line=$(echo "$line" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') - - # Skip if line is empty or too short - [ -z "$line" ] && continue - [ ${#line} -lt 5 ] && continue - - # Capitalize first letter if lowercase - line="$(echo ${line:0:1} | tr '[:lower:]' '[:upper:]')${line:1}" - - # Add clean bullet and output - echo "- $line" - done > .tmp/final-notes.txt + echo "⚠️ AI unavailable - generating concise user-friendly summaries from raw notes" + + python3 <<'PYTHON_EOF' + import os + import re + + raw = os.environ.get("RAW_NOTES", "") + lines = raw.splitlines() + + output = [] + seen = set() + + def clean_line(text: str) -> str: + text = text.strip() + if not text: + return "" + + # Drop markdown headers/changelog lines. + if re.match(r"^#+\s", text, flags=re.I): + return "" + if re.match(r"^\*\*?\s*full\s+changelog", text, flags=re.I): + return "" + if re.match(r"^full\s+changelog", text, flags=re.I): + return "" + + text = re.sub(r"^[\s\-*•]+", "", text) + text = re.sub(r"\s+by\s+@?[a-zA-Z0-9_-]+\s+in\s+https?://\S+", "", text) + text = re.sub(r"\s+by\s+@?[a-zA-Z0-9_-]+\s*$", "", text) + text = re.sub(r"@([a-zA-Z0-9_-]+)", "", text) + text = re.sub(r"\s*\([^)]*#\d+\)\s*$", "", text) + text = re.sub(r"\s+#\d+\s*$", "", text) + text = re.sub(r"\s+", " ", text).strip(" .:-") + + if len(text) < 8: + return "" + + # Make user-friendly short title + summary when possible. + if ":" in text: + left, right = [p.strip() for p in text.split(":", 1)] + left = left[:40].rstrip(" .") + right_words = right.split() + right = " ".join(right_words[:14]).rstrip(" .") + text = f"{left}: {right}" if right else left + else: + words = text.split() + if len(words) > 16: + text = " ".join(words[:16]).rstrip(" .") + + return text + + for line in lines: + cleaned = clean_line(line) + if not cleaned: + continue + + # Normalize casing and deduplicate. + cleaned = cleaned[0].upper() + cleaned[1:] if cleaned else cleaned + key = cleaned.lower() + if key in seen: + continue + seen.add(key) + + output.append(f"* {cleaned}") + if len(output) >= 8: + break + + with open('.tmp/final-notes.txt', 'w', encoding='utf-8') as f: + f.write("\n".join(output)) + PYTHON_EOF fi + + # Normalize bullets to "* " even if AI returns "- ". + sed -E 's/^[[:space:]]*-[[:space:]]+/* /' .tmp/final-notes.txt > .tmp/final-notes.normalized.txt + mv .tmp/final-notes.normalized.txt .tmp/final-notes.txt # Safety check: verify we have content if [ ! -s .tmp/final-notes.txt ]; then echo "⚠️ No valid release notes extracted, using minimal fallback" - echo "- Release ${{ steps.payload.outputs.version }}" > .tmp/final-notes.txt + echo "* Release ${{ steps.payload.outputs.version }}" > .tmp/final-notes.txt fi echo "=== Final release notes ==="