Skip to content

Commit a6f4eeb

Browse files
authored
feat: add structure changelog (#283)
* feat: add structure changelog
1 parent f07dd07 commit a6f4eeb

File tree

3 files changed

+135
-21
lines changed

3 files changed

+135
-21
lines changed

.github/workflows/release.yml

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,29 +57,12 @@ jobs:
5757
echo "Found previous tag: $PREVIOUS"
5858
echo "tag=$PREVIOUS" >> $GITHUB_OUTPUT
5959
60-
- name: Generate simple changelog from git commits
60+
- name: Generate categorized changelog
6161
id: changelog
6262
run: |
63-
git fetch --tags
64-
echo "Validating tags: ${{ steps.latest.outputs.tag }} and ${{ github.ref_name }}"
65-
66-
# Validate the existence of the previous tag
67-
if ! git rev-parse --verify ${{ steps.latest.outputs.tag }} >/dev/null 2>&1; then
68-
echo "Error: Previous tag ${{ steps.latest.outputs.tag }} does not exist." >&2
69-
exit 1
70-
fi
71-
72-
# Validate the existence of the current tag
73-
if ! git rev-parse --verify ${{ github.ref_name }} >/dev/null 2>&1; then
74-
echo "Error: Current tag ${{ github.ref_name }} does not exist." >&2
75-
exit 1
76-
fi
77-
78-
echo "Generating changelog from commits between ${{ steps.latest.outputs.tag }} and ${{ github.ref_name }}"
79-
LOG=$(git log ${{ steps.latest.outputs.tag }}..${{ github.ref_name }} --pretty=format:"- %s (%an)")
80-
# Removed unused changelog.txt file creation
63+
make changelog PREVIOUS=${{ steps.latest.outputs.tag }} CURRENT=${{ github.ref_name }}
8164
echo "changelog<<EOF" >> $GITHUB_OUTPUT
82-
echo "$LOG" >> $GITHUB_OUTPUT
65+
cat changelog.md >> $GITHUB_OUTPUT
8366
echo "EOF" >> $GITHUB_OUTPUT
8467
8568
- name: Publish GitHub Release

Makefile

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ endif
6464
--tag ghcr.io/$(REPO_OWNER)/leafwiki:latest \
6565
--push .
6666

67+
# Generate markdown changelog between two tags
68+
changelog:
69+
@if [ -z "$(PREVIOUS)" ] || [ -z "$(CURRENT)" ]; then \
70+
echo "Usage: make changelog PREVIOUS=v0.1.0 CURRENT=v0.2.0"; \
71+
exit 1; \
72+
fi
73+
@./scripts/changelog.sh $(PREVIOUS) $(CURRENT)
74+
6775
help:
6876
@echo "Available commands:"
6977
@echo " make build – Build binary for current system"
@@ -72,5 +80,6 @@ help:
7280
@echo " make test – Run all Go tests"
7381
@echo " make run – Run development server"
7482
@echo " make docker-build-publish – Build and push multi-arch Docker image"
83+
@echo " make changelog – Generate changelog"
7584

76-
.PHONY: all build run clean test fmt lint help docker-build-publish
85+
.PHONY: all build run clean test fmt lint help docker-build-publish changelog

scripts/changelog.sh

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
#!/usr/bin/env bash
2+
3+
# -----------------------------------------------------------------------------
4+
# changelog.sh
5+
#
6+
# Purpose:
7+
# Generates a categorized changelog in markdown format from git commit messages
8+
# between two tags.
9+
#
10+
# Expected commit message format:
11+
# Uses Conventional Commits prefixes for categorization:
12+
# feat: New features
13+
# fix: Bug fixes
14+
# docs: Documentation changes
15+
# refactor: Code refactoring
16+
# test: Test-related changes
17+
# chore: Maintenance tasks
18+
# Any commit not matching these prefixes is categorized as "Other Changes".
19+
#
20+
# Usage:
21+
# ./changelog.sh <previous_tag> <current_tag>
22+
#
23+
# Output:
24+
# Writes a markdown changelog to 'changelog.md' in the current directory.
25+
# -----------------------------------------------------------------------------
26+
set -euo pipefail
27+
28+
# === Configuration ===
29+
PREVIOUS_TAG="${1:-}"
30+
CURRENT_TAG="${2:-}"
31+
32+
if [[ -z "$PREVIOUS_TAG" || -z "$CURRENT_TAG" ]]; then
33+
echo "Usage: $0 <previous_tag> <current_tag>"
34+
exit 1
35+
fi
36+
37+
echo "🔍 Generating changelog from $PREVIOUS_TAG$CURRENT_TAG"
38+
39+
# Validate tags exist
40+
if ! git rev-parse --verify "$PREVIOUS_TAG" >/dev/null 2>&1; then
41+
echo "❌ Previous tag '$PREVIOUS_TAG' does not exist."
42+
exit 1
43+
fi
44+
if ! git rev-parse --verify "$CURRENT_TAG" >/dev/null 2>&1; then
45+
echo "❌ Current tag '$CURRENT_TAG' does not exist."
46+
exit 1
47+
fi
48+
49+
# Collect commits
50+
COMMITS=$(git log "$PREVIOUS_TAG".."$CURRENT_TAG" --pretty=format:"%s (@%an)")
51+
52+
# Categorize exclusively
53+
FEATURES=""
54+
FIXES=""
55+
DOCS=""
56+
REFACTOR=""
57+
TESTS=""
58+
CHORES=""
59+
OTHERS=""
60+
while IFS= read -r commit; do
61+
if [[ "$commit" =~ ^feat ]]; then
62+
FEATURES+="$commit"$'\n'
63+
elif [[ "$commit" =~ ^fix ]]; then
64+
FIXES+="$commit"$'\n'
65+
elif [[ "$commit" =~ ^docs ]]; then
66+
DOCS+="$commit"$'\n'
67+
elif [[ "$commit" =~ ^refactor ]]; then
68+
REFACTOR+="$commit"$'\n'
69+
elif [[ "$commit" =~ ^test ]]; then
70+
TESTS+="$commit"$'\n'
71+
elif [[ "$commit" =~ ^chore ]]; then
72+
CHORES+="$commit"$'\n'
73+
else
74+
OTHERS+="$commit"$'\n'
75+
fi
76+
done <<< "$COMMITS"
77+
78+
# Build markdown file
79+
OUTFILE="changelog.md"
80+
81+
{
82+
echo "## 📝 Changelog for $CURRENT_TAG"
83+
echo ""
84+
85+
if [ -n "$FEATURES" ]; then
86+
echo "### ✨ Features"
87+
echo "$FEATURES" | sed '/^$/d; s/^/- /'
88+
echo ""
89+
fi
90+
if [ -n "$FIXES" ]; then
91+
echo "### 🐛 Bug Fixes"
92+
echo "$FIXES" | sed '/^$/d; s/^/- /'
93+
echo ""
94+
fi
95+
if [ -n "$DOCS" ]; then
96+
echo "### 🧾 Documentation"
97+
echo "$DOCS" | sed '/^$/d; s/^/- /'
98+
echo ""
99+
fi
100+
if [ -n "$REFACTOR" ]; then
101+
echo "### 🔧 Refactoring"
102+
echo "$REFACTOR" | sed '/^$/d; s/^/- /'
103+
echo ""
104+
fi
105+
if [ -n "$TESTS" ]; then
106+
echo "### 🧪 Tests"
107+
echo "$TESTS" | sed '/^$/d; s/^/- /'
108+
echo ""
109+
fi
110+
if [ -n "$CHORES" ]; then
111+
echo "### 🧰 Chores"
112+
echo "$CHORES" | sed '/^$/d; s/^/- /'
113+
echo ""
114+
fi
115+
if [ -n "$OTHERS" ]; then
116+
echo "### 🔹 Other Changes"
117+
echo "$OTHERS" | sed '/^$/d; s/^/- /'
118+
echo ""
119+
fi
120+
} > "$OUTFILE"
121+
122+
echo "✅ Changelog written to $OUTFILE"

0 commit comments

Comments
 (0)