Skip to content

Commit 7db7c73

Browse files
committed
feat: Implement automated changelog generation following best practices
- Create comprehensive changelog generation system - Add standalone script (scripts/generate-changelog.sh) for manual changelog generation - Update release workflow to automatically generate and maintain CHANGELOG.md - Follow Keep a Changelog format with proper categorization - Support conventional commit format (feat:, fix:, docs:, etc.) - Categorize changes into Added, Changed, Fixed, Security, Deprecated, Removed - Preserve complete changelog history across releases - Generate version comparison links automatically - Include comprehensive help and usage documentation Features: - Automatic categorization based on commit message prefixes - Complete history preservation from previous releases - Cross-platform compatibility (Windows, Linux, macOS) - Proper semantic versioning support - Version comparison links for GitHub - Standalone script for manual generation and testing This addresses the requirement for automated changelog management and ensures CHANGELOG.md is generated by scripts rather than manually maintained.
1 parent c2f47c6 commit 7db7c73

File tree

3 files changed

+453
-6
lines changed

3 files changed

+453
-6
lines changed

.github/workflows/release.yml

Lines changed: 129 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,136 @@ jobs:
102102
echo EOF
103103
} >> $GITHUB_OUTPUT
104104
105-
- name: Update CHANGELOG.md
105+
- name: Generate and update CHANGELOG.md
106106
run: |
107-
echo "${{ steps.release_notes.outputs.content }}" > CHANGELOG.md
107+
#!/bin/bash
108+
set -euo pipefail
109+
110+
# Get the latest tag for comparison
111+
latest_tag=$(git describe --tags --abbrev=0 2>/dev/null || echo "v0.0.0")
112+
113+
echo "Generating changelog for ${{ steps.version.outputs.new_version }} (since $latest_tag)"
114+
115+
# Create temporary files for categorizing commits
116+
added_file=$(mktemp)
117+
changed_file=$(mktemp)
118+
fixed_file=$(mktemp)
119+
security_file=$(mktemp)
120+
deprecated_file=$(mktemp)
121+
removed_file=$(mktemp)
122+
other_file=$(mktemp)
123+
124+
# Get commits since last tag
125+
if [ "$latest_tag" != "v0.0.0" ]; then
126+
commits=$(git log --pretty=format:"%s" ${latest_tag}..HEAD)
127+
else
128+
commits=$(git log --pretty=format:"%s")
129+
fi
130+
131+
# Process each commit and categorize based on conventional commits
132+
echo "$commits" | while IFS= read -r commit; do
133+
case "$commit" in
134+
feat\(*|feat:*)
135+
echo "- ${commit#feat*: }" >> "$added_file"
136+
;;
137+
fix\(*|fix:*)
138+
echo "- ${commit#fix*: }" >> "$fixed_file"
139+
;;
140+
security\(*|security:*)
141+
echo "- ${commit#security*: }" >> "$security_file"
142+
;;
143+
deprecate\(*|deprecate:*|deprecated\(*|deprecated:*)
144+
echo "- ${commit#deprecat*: }" >> "$deprecated_file"
145+
;;
146+
remove\(*|remove:*|removed\(*|removed:*)
147+
echo "- ${commit#remov*: }" >> "$removed_file"
148+
;;
149+
docs\(*|docs:*|chore\(*|chore:*|refactor\(*|refactor:*|perf\(*|perf:*|style\(*|style:*|test\(*|test:*)
150+
echo "- ${commit}" >> "$changed_file"
151+
;;
152+
*)
153+
echo "- ${commit}" >> "$other_file"
154+
;;
155+
esac
156+
done
157+
158+
# Create the new changelog entry
159+
{
160+
echo "## [${{ steps.version.outputs.new_version }}] - $(date +%Y-%m-%d)"
161+
echo ""
162+
} > new_entry.md
163+
164+
# Add categorized changes following Keep a Changelog format
165+
for category in "Added:$added_file" "Changed:$changed_file" "Deprecated:$deprecated_file" "Removed:$removed_file" "Fixed:$fixed_file" "Security:$security_file"; do
166+
category_name="${category%:*}"
167+
file_path="${category#*:}"
168+
169+
if [ -s "$file_path" ]; then
170+
echo "### $category_name" >> new_entry.md
171+
echo "" >> new_entry.md
172+
cat "$file_path" >> new_entry.md
173+
echo "" >> new_entry.md
174+
fi
175+
done
176+
177+
# Add other changes if any
178+
if [ -s "$other_file" ]; then
179+
echo "### Other Changes" >> new_entry.md
180+
echo "" >> new_entry.md
181+
cat "$other_file" >> new_entry.md
182+
echo "" >> new_entry.md
183+
fi
184+
185+
# Create or update the complete changelog
186+
{
187+
echo "# Changelog"
188+
echo ""
189+
echo "All notable changes to this project will be documented in this file."
190+
echo ""
191+
echo "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),"
192+
echo "and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)."
193+
echo ""
194+
} > CHANGELOG.md
195+
196+
# Add the new entry
197+
cat new_entry.md >> CHANGELOG.md
198+
199+
# Preserve existing changelog entries if they exist
200+
if git show HEAD:CHANGELOG.md >/dev/null 2>&1; then
201+
# Get existing entries (skip header and current version if it exists)
202+
git show HEAD:CHANGELOG.md | sed -n '/^## \[/,$p' | grep -v "^## \[${{ steps.version.outputs.new_version }}\]" >> CHANGELOG.md 2>/dev/null || true
203+
fi
204+
205+
# Add version links at the bottom
206+
echo "" >> CHANGELOG.md
207+
208+
# Get all tags for version links
209+
all_tags=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' || true)
210+
if [ -n "$all_tags" ]; then
211+
prev_tag=""
212+
echo "$all_tags" | while IFS= read -r tag; do
213+
version="${tag#v}"
214+
if [ -z "$prev_tag" ]; then
215+
# First tag (latest) - compare with HEAD
216+
echo "[$version]: https://github.com/${{ github.repository }}/compare/$tag...HEAD" >> CHANGELOG.md
217+
else
218+
# Compare with previous tag
219+
echo "[$version]: https://github.com/${{ github.repository }}/compare/$tag...$prev_tag" >> CHANGELOG.md
220+
fi
221+
prev_tag="$tag"
222+
done
223+
224+
# Add link for the oldest version
225+
if [ -n "$prev_tag" ]; then
226+
oldest_version="${prev_tag#v}"
227+
echo "[$oldest_version]: https://github.com/${{ github.repository }}/releases/tag/$prev_tag" >> CHANGELOG.md
228+
fi
229+
fi
230+
231+
# Cleanup temporary files
232+
rm -f "$added_file" "$changed_file" "$fixed_file" "$security_file" "$deprecated_file" "$removed_file" "$other_file" new_entry.md
233+
234+
echo "CHANGELOG.md generated successfully"
108235
109236
- name: Commit and push CHANGELOG.md
110237
run: |

CHANGELOG.md

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,49 @@
1-
## What's Changed
1+
# Changelog
22

3-
- Merge branch 'main' of https://github.com/d-oit/gh-sub-issues ([d3b0200](https://github.com/d-oit/gh-sub-issues/commit/d3b0200ee58362d491d6969a00b1cae69480ed00))
4-
- fix: Make issue processing in release workflow more robust ([6c60d75](https://github.com/d-oit/gh-sub-issues/commit/6c60d752c00b454c15f1ab96d95e8e2124d41830))
5-
**Full Changelog**: https://github.com/d-oit/gh-sub-issues/compare/v0.2.0...v0.3.0
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Added
11+
12+
- Add comprehensive logging and debugging capabilities
13+
- comprehensive test suite improvements and bug fixes
14+
- Implement automated GitHub release and issue management workflow
15+
- Complete changelog automation testing and improvements
16+
- Add comprehensive GitHub Actions workflows and automation
17+
- Prepare v0.1.1 release with enhanced features and fixes
18+
- Handle pre-release tags and fix shellcheck warning
19+
20+
### Changed
21+
22+
- docs: update CHANGELOG.md for v0.3.0
23+
- docs: update CHANGELOG.md for v0.2.0
24+
- docs: Update CHANGELOG.md for v0.1.3 release
25+
- docs: Add comprehensive workflow setup summary
26+
27+
### Fixed
28+
29+
- Make issue processing in release workflow more robust
30+
- Replace git-cliff-action with native git log for release notes
31+
- Make GitHub API wrapper test more robust for CI environment
32+
- Improve changelog automation date filtering
33+
- Resolve release manager test errors
34+
- Resolve GitHub Actions workflow errors
35+
36+
### Other Changes
37+
38+
- Merge branch 'main' of https://github.com/d-oit/gh-sub-issues
39+
- Revert "docs: Update CHANGELOG.md for v0.1.3 release"
40+
41+
42+
[0.3.0]: https://github.com/d-oit/gh-sub-issues/compare/v0.3.0...HEAD
43+
[0.2.0]: https://github.com/d-oit/gh-sub-issues/compare/v0.2.0...v0.3.0
44+
[0.1.4]: https://github.com/d-oit/gh-sub-issues/compare/v0.1.4...v0.2.0
45+
[0.1.3]: https://github.com/d-oit/gh-sub-issues/compare/v0.1.3...v0.1.4
46+
[0.1.2]: https://github.com/d-oit/gh-sub-issues/compare/v0.1.2...v0.1.3
47+
[0.1.1]: https://github.com/d-oit/gh-sub-issues/compare/v0.1.1...v0.1.2
48+
[0.1.0]: https://github.com/d-oit/gh-sub-issues/compare/v0.1.0...v0.1.1
49+
[Unreleased]: https://github.com/d-oit/gh-sub-issues/compare/v0.3.0...HEAD

0 commit comments

Comments
 (0)