From 02b56b76910439374dcffad10d2a67b8d618e136 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Fri, 13 Jun 2025 17:45:06 +0100 Subject: [PATCH 1/2] Release v3.25.2-rc3: Installer improvements and automated changelog enhancements (#133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: dramatically improve automated changelog generation - Add detailed analysis logging and error handling - Clean up commit messages by removing prefixes (feat:, fix:, etc.) - Group changes by type with proper emoji categories - Include version progression info (v3.25.2 → v3.25.3) - Add installation instructions and Docker commands - Filter out technical/automated commits from user-facing changelog - Provide enhanced fallback using git log if analysis fails - Include release statistics and change counts This replaces the generic 'Automated stable release' message with comprehensive, user-friendly changelogs. šŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * chore: bump version to 3.25.2-rc3 for RC release * fix: improve installer resilience against GitHub API rate limits Add fallback mechanism in check_release_exists() to verify release existence by attempting direct tarball download when GitHub API is rate limited. This prevents installation failures when the API quota is exceeded. šŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * chore: bump version to 3.25.2-rc4 for RC release --------- Co-authored-by: rcourtman Co-authored-by: Claude Co-authored-by: GitHub Action --- .github/workflows/stable-release.yml | 81 +++++++++++++++++++++++----- package.json | 2 +- scripts/install-pulse.sh | 13 ++++- 3 files changed, 82 insertions(+), 14 deletions(-) diff --git a/.github/workflows/stable-release.yml b/.github/workflows/stable-release.yml index 3a75d6c8c..e60089e5a 100644 --- a/.github/workflows/stable-release.yml +++ b/.github/workflows/stable-release.yml @@ -195,16 +195,32 @@ jobs: node -e " const { execSync } = require('child_process'); const { analyzeCommitsForVersionBump } = require('./server/versionUtils'); + const fs = require('fs'); try { + console.log('šŸ” Starting changelog generation...'); const analysis = analyzeCommitsForVersionBump(); + console.log('šŸ“Š Analysis results:', { + currentStable: analysis.currentStableVersion, + suggested: analysis.suggestedVersion, + bumpType: analysis.bumpType, + totalCommits: analysis.totalCommits, + breaking: analysis.analysis.breaking.length, + features: analysis.analysis.features.length, + fixes: analysis.analysis.fixes.length, + other: analysis.analysis.other.length + }); + // Generate meaningful changelog based on actual commits let changelog = '## What\\'s Changed\\n\\n'; + // Add version summary + changelog += '**' + analysis.bumpType.charAt(0).toUpperCase() + analysis.bumpType.slice(1) + ' release** with ' + analysis.totalCommits + ' commit' + (analysis.totalCommits !== 1 ? 's' : '') + ' since v' + analysis.currentStableVersion + '\\n\\n'; + if (analysis.analysis.breaking.length > 0) { changelog += '### šŸ’„ Breaking Changes\\n'; analysis.analysis.breaking.forEach(commit => { - changelog += '- ' + commit + '\\n'; + changelog += '- ' + commit.replace(/^(fix|feat|docs|style|refactor|test|chore)!?:\\s*/, '') + '\\n'; }); changelog += '\\n'; } @@ -212,7 +228,7 @@ jobs: if (analysis.analysis.features.length > 0) { changelog += '### ✨ New Features\\n'; analysis.analysis.features.forEach(commit => { - changelog += '- ' + commit + '\\n'; + changelog += '- ' + commit.replace(/^feat:\\s*/, '') + '\\n'; }); changelog += '\\n'; } @@ -220,7 +236,7 @@ jobs: if (analysis.analysis.fixes.length > 0) { changelog += '### šŸ› Bug Fixes\\n'; analysis.analysis.fixes.forEach(commit => { - changelog += '- ' + commit + '\\n'; + changelog += '- ' + commit.replace(/^fix:\\s*/, '') + '\\n'; }); changelog += '\\n'; } @@ -228,33 +244,74 @@ jobs: if (analysis.analysis.other.length > 0) { changelog += '### šŸ”§ Other Changes\\n'; analysis.analysis.other.forEach(commit => { - changelog += '- ' + commit + '\\n'; + let cleanCommit = commit.replace(/^(docs|style|refactor|test|chore):\\s*/, ''); + // Skip very technical commits that aren't user-facing + if (!cleanCommit.includes('šŸ¤– Generated with') && !cleanCommit.includes('resolve:') && cleanCommit.length > 10) { + changelog += '- ' + cleanCommit + '\\n'; + } }); changelog += '\\n'; } - changelog += '### šŸ“Š Release Statistics\\n'; - changelog += '- **Version bump**: ' + analysis.bumpType + '\\n'; - changelog += '- **Total commits**: ' + analysis.totalCommits + '\\n'; + changelog += '### šŸ“Š Release Information\\n'; + changelog += '- **Release type**: ' + analysis.bumpType + ' (v' + analysis.currentStableVersion + ' → v' + analysis.suggestedVersion + ')\\n'; + changelog += '- **Total changes**: ' + analysis.totalCommits + ' commits\\n'; changelog += '- **Breaking changes**: ' + analysis.analysis.breaking.length + '\\n'; changelog += '- **New features**: ' + analysis.analysis.features.length + '\\n'; changelog += '- **Bug fixes**: ' + analysis.analysis.fixes.length + '\\n'; changelog += '\\n'; + changelog += '### 🐳 Docker\\n'; changelog += '\\`\\`\\`bash\\n'; + changelog += '# Latest stable release\\n'; changelog += 'docker pull rcourtman/pulse:v' + analysis.suggestedVersion + '\\n'; changelog += 'docker pull rcourtman/pulse:latest\\n'; changelog += '\\`\\`\\`\\n'; changelog += '\\n'; - changelog += 'šŸ¤– *This release was automatically created from the develop branch*'; - console.log(changelog); + changelog += '### šŸ“„ Installation\\n'; + changelog += '\\`\\`\\`bash\\n'; + changelog += '# Automated installer (recommended)\\n'; + changelog += 'curl -sL https://raw.githubusercontent.com/rcourtman/Pulse/main/scripts/install-pulse.sh | bash\\n'; + changelog += '\\n'; + changelog += '# Or download and extract tarball manually\\n'; + changelog += 'wget https://github.com/rcourtman/Pulse/releases/download/v' + analysis.suggestedVersion + '/pulse-v' + analysis.suggestedVersion + '.tar.gz\\n'; + changelog += '\\`\\`\\`\\n'; + changelog += '\\n'; + changelog += 'šŸ¤– *This release was automatically generated from the develop branch*'; + + console.log('āœ… Generated changelog with', changelog.split('\\n').length, 'lines'); // Write to file for GitHub release - require('fs').writeFileSync('CHANGELOG.md', changelog); + fs.writeFileSync('CHANGELOG.md', changelog); + console.log('šŸ“ Changelog written to CHANGELOG.md'); + } catch (error) { - console.error('Error generating changelog:', error); - require('fs').writeFileSync('CHANGELOG.md', 'Automated stable release\\n\\nSee commit history for details.'); + console.error('āŒ Error generating changelog:', error); + console.error('Stack trace:', error.stack); + + // Enhanced fallback with basic git log + let fallbackChangelog = '## Release v$NEW_VERSION\\n\\n'; + try { + const gitLog = execSync('git log $(git describe --tags --abbrev=0)..HEAD --oneline --no-merges', { encoding: 'utf8' }); + if (gitLog.trim()) { + fallbackChangelog += '### Changes since last release:\\n'; + gitLog.trim().split('\\n').forEach(line => { + if (line.trim() && !line.includes('šŸ¤– Generated with')) { + fallbackChangelog += '- ' + line.replace(/^[a-f0-9]+\\s+/, '') + '\\n'; + } + }); + } else { + fallbackChangelog += 'See commit history for details.\\n'; + } + } catch (gitError) { + fallbackChangelog += 'See commit history for details.\\n'; + } + + fallbackChangelog += '\\nšŸ¤– *Automated release - detailed changelog generation failed*'; + + fs.writeFileSync('CHANGELOG.md', fallbackChangelog); + console.log('šŸ“ Fallback changelog written'); } " diff --git a/package.json b/package.json index 8ca0c4064..18f7c0ad3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pulse", - "version": "3.25.3", + "version": "3.25.2-rc4", "description": "A lightweight monitoring application for Proxmox VE.", "main": "server/index.js", "scripts": { diff --git a/scripts/install-pulse.sh b/scripts/install-pulse.sh index 56811c9ce..934341485 100755 --- a/scripts/install-pulse.sh +++ b/scripts/install-pulse.sh @@ -333,7 +333,18 @@ check_release_exists() { local tag=$1 local api_url="https://api.github.com/repos/rcourtman/Pulse/releases/tags/$tag" - curl -s --fail "$api_url" > /dev/null 2>&1 + # Try API first, but don't fail if rate limited + if curl -s --fail "$api_url" > /dev/null 2>&1; then + return 0 + fi + + # Fallback: try to download the tarball directly to verify existence + local tarball_url="https://github.com/rcourtman/Pulse/releases/download/${tag}/pulse-${tag}.tar.gz" + if curl -s --head --fail "$tarball_url" > /dev/null 2>&1; then + return 0 + fi + + return 1 } # Download and extract tarball From 95fcd6939a5076f445d8988cb123b7e3c89cb6fa Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Fri, 13 Jun 2025 16:45:45 +0000 Subject: [PATCH 2/2] chore: release v3.25.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch bump for 1 other change(s) This stable release includes all changes from the develop branch. šŸ¤– Generated by automated stable release workflow --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a06781ad7..3b94b05f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pulse", - "version": "3.25.3", + "version": "3.25.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pulse", - "version": "3.25.3", + "version": "3.25.4", "license": "MIT", "dependencies": { "axios": "^1.9.0", diff --git a/package.json b/package.json index 18f7c0ad3..dcc558790 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pulse", - "version": "3.25.2-rc4", + "version": "3.25.4", "description": "A lightweight monitoring application for Proxmox VE.", "main": "server/index.js", "scripts": {