feat: ensure releases show only per-version changelog

- Updated release.md documentation to emphasize per-release changelog behavior
- Added fix-release-changelogs.sh script to update existing releases
- Clarified that release script already extracts only specific version changes
- Script can fix releases that incorrectly show full changelog history

The release system already works correctly - it extracts only the specific
version's changelog. The issue was with some existing releases that somehow
got the full CHANGELOG.md content instead of the extracted version.
This commit is contained in:
Peter Steinberger 2025-07-15 19:29:26 +02:00
parent 8543d4b1e1
commit 7ba1ebbc38
2 changed files with 160 additions and 0 deletions

View file

@ -254,6 +254,13 @@ All notable changes to VibeTunnel will be documented in this file.
**CRITICAL**: The appcast generation relies on the local CHANGELOG.md file, NOT the GitHub release description. The changelog must be added to CHANGELOG.md BEFORE running the release script.
**IMPORTANT - Per-Release Changelog**: The release script automatically extracts ONLY the changelog section for the specific version being released. For example:
- When releasing beta.10, only the `## [1.0.0-beta.10]` section is used
- When releasing beta.11, only the `## [1.0.0-beta.11]` section is used
- This keeps GitHub release pages focused and prevents endless scrolling to find download links
The script uses `changelog-to-html.sh` to extract the specific version's changes, not the entire changelog history.
### Step 4: Create the Release
⚠️ **CRITICAL UNDERSTANDING**: The release script parameters are ONLY for:
@ -304,6 +311,9 @@ The script will:
### Step 5: Verify Success
- Check the GitHub releases page
- **IMPORTANT**: Verify the GitHub release shows ONLY the current version's changelog, not the entire history
- If it shows the full changelog, the release notes were not generated correctly
- The release should only show changes for that specific version (e.g., beta.10 shows only beta.10 changes)
- Verify the appcast was updated correctly with proper changelog content
- **Critical**: Verify the Sparkle signature is correct:
```bash

View file

@ -0,0 +1,150 @@
#!/bin/bash
# =============================================================================
# VibeTunnel Release Changelog Fixer
# =============================================================================
#
# This script updates existing GitHub releases to show only their own changelog
# instead of the cumulative changelog history.
#
# USAGE:
# ./scripts/fix-release-changelogs.sh [--dry-run]
#
# OPTIONS:
# --dry-run Show what would be changed without actually updating
#
# =============================================================================
set -euo pipefail
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Check for dry-run mode
DRY_RUN=false
if [[ "${1:-}" == "--dry-run" ]]; then
DRY_RUN=true
echo -e "${YELLOW}DRY RUN MODE - No changes will be made${NC}"
fi
# Find changelog file
if [[ -f "$PROJECT_ROOT/../CHANGELOG.md" ]]; then
CHANGELOG_PATH="$PROJECT_ROOT/../CHANGELOG.md"
elif [[ -f "$PROJECT_ROOT/CHANGELOG.md" ]]; then
CHANGELOG_PATH="$PROJECT_ROOT/CHANGELOG.md"
else
echo -e "${RED}❌ Error: CHANGELOG.md not found${NC}"
exit 1
fi
echo "📋 Using changelog: $CHANGELOG_PATH"
# Function to extract and format changelog for a specific version
generate_release_notes() {
local version="$1"
local changelog_html=""
# Use the existing changelog-to-html.sh script
if [[ -x "$SCRIPT_DIR/changelog-to-html.sh" ]]; then
changelog_html=$("$SCRIPT_DIR/changelog-to-html.sh" "$version" "$CHANGELOG_PATH" 2>/dev/null || echo "")
fi
# If we got HTML content, format it nicely for GitHub
if [[ -n "$changelog_html" ]] && [[ "$changelog_html" != *"Latest version of VibeTunnel"* ]]; then
# Convert HTML back to Markdown for GitHub (basic conversion)
echo "$changelog_html" | \
sed 's/<h3>/### /g' | \
sed 's/<\/h3>//g' | \
sed 's/<h2>/## /g' | \
sed 's/<\/h2>//g' | \
sed 's/<ul>/\n/g' | \
sed 's/<\/ul>/\n/g' | \
sed 's/<li>/- /g' | \
sed 's/<\/li>//g' | \
sed 's/<strong>/**/g' | \
sed 's/<\/strong>/**/g' | \
sed 's/<code>/`/g' | \
sed 's/<\/code>/`/g' | \
sed 's/<a href="\([^"]*\)">\([^<]*\)<\/a>/[\2](\1)/g' | \
sed 's/<p>//g' | \
sed 's/<\/p>/\n/g' | \
sed 's/<div>//g' | \
sed 's/<\/div>//g' | \
sed '/^$/N;/^\n$/d' # Remove multiple blank lines
else
# Fallback: Try to extract directly from markdown
awk -v version="$version" '
BEGIN { found=0; print_section=0 }
/^## \[/ && $0 ~ "\\[" version "\\]" { found=1; print_section=1; next }
found && print_section && /^## / { print_section=0 }
found && print_section { print }
' "$CHANGELOG_PATH"
fi
}
# Get list of releases
echo "🔍 Fetching releases..."
RELEASES=$(gh release list --limit 20 --json tagName,name,isPrerelease | jq -r '.[] | select(.isPrerelease == true) | .tagName')
if [[ -z "$RELEASES" ]]; then
echo -e "${YELLOW}No pre-releases found to update${NC}"
exit 0
fi
# Process each release
for tag in $RELEASES; do
# Extract version from tag (remove 'v' prefix)
version="${tag#v}"
echo -e "\n📦 Processing release: ${GREEN}$tag${NC} (version: $version)"
# Get current release body
current_body=$(gh release view "$tag" --json body | jq -r '.body')
current_lines=$(echo "$current_body" | wc -l)
# Generate new release notes for this version only
new_body=$(generate_release_notes "$version")
new_lines=$(echo "$new_body" | wc -l)
if [[ -z "$new_body" ]]; then
echo -e " ${YELLOW}⚠️ No changelog found for version $version${NC}"
continue
fi
# Check if update is needed (simple heuristic: if current has way more lines than new)
if [[ $current_lines -gt 100 ]] && [[ $new_lines -lt 100 ]]; then
echo -e " ${YELLOW}📏 Current: $current_lines lines, New: $new_lines lines${NC}"
echo -e " ${GREEN}✅ Update needed${NC}"
if [[ "$DRY_RUN" == "false" ]]; then
# Create temp file with new body
temp_file=$(mktemp)
echo "$new_body" > "$temp_file"
# Update the release
gh release edit "$tag" --notes-file "$temp_file"
rm "$temp_file"
echo -e " ${GREEN}✨ Updated successfully${NC}"
else
echo -e " ${YELLOW}[DRY RUN] Would update this release${NC}"
echo " First 10 lines of new content:"
echo "$new_body" | head -10 | sed 's/^/ /'
fi
else
echo -e " ${GREEN}✓ Already using per-release changelog (or too similar in size)${NC}"
fi
done
echo -e "\n${GREEN}✅ Done!${NC}"
if [[ "$DRY_RUN" == "true" ]]; then
echo -e "${YELLOW}This was a dry run. Run without --dry-run to make actual changes.${NC}"
fi