Skip to content

Commit 737dcc2

Browse files
committed
chore: Add changelog script to generate CHANGELOG.md file
1 parent 2dea0cf commit 737dcc2

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

bin/changelog

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/bin/sh
2+
3+
# Source: https://github.com/smichard/conventional_changelog/blob/main/generate_changelog_local.sh
4+
5+
# Exit on error
6+
set -e
7+
8+
# Error handling
9+
trap 'echo "An error occurred at line $LINENO. Exiting."' ERR
10+
11+
# Path to the Git repository (current directory)
12+
REPO_DIR="."
13+
CHANGELOG_FILE="$REPO_DIR/CHANGELOG.md"
14+
GITHUB_REPO_URL=$(git remote get-url origin 2>/dev/null | sed 's/^git@/https:\/\//;s/github\.com:/github.com\//;s/\.git$//')
15+
if [ -z "$GITHUB_REPO_URL" ]; then
16+
GITHUB_REPO_URL=0
17+
fi
18+
19+
echo "Starting changelog generation script..."
20+
echo "Repository:"
21+
echo $GITHUB_REPO_URL
22+
# Create or clear the changelog file
23+
> $CHANGELOG_FILE
24+
25+
# Add the introductory text to the changelog
26+
echo "# Changelog" >> $CHANGELOG_FILE
27+
echo "" >> $CHANGELOG_FILE
28+
echo "All notable changes to this project will be documented in this file." >> $CHANGELOG_FILE
29+
echo "" >> $CHANGELOG_FILE
30+
echo "The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) and to [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)." >> $CHANGELOG_FILE
31+
echo "" >> $CHANGELOG_FILE
32+
33+
# Go to the repository directory
34+
cd $REPO_DIR
35+
36+
# Fetch the latest changes
37+
git fetch --tags
38+
echo "Fetched latest tags."
39+
40+
# Get the latest tag
41+
LATEST_TAG=$(git describe --tags --abbrev=0)
42+
43+
# Get tags in reverse order
44+
TAGS=$(git tag --sort=-v:refname)
45+
46+
# Check if there are any tags
47+
if [ -z "$TAGS" ]; then
48+
echo "No tags found in the repository."
49+
exit 1
50+
fi
51+
52+
echo "Found tags: $TAGS"
53+
54+
# Placeholder for the previous tag
55+
TAG_TO=HEAD
56+
57+
# Define categories
58+
CATEGORIES="feat fix perf chore docs refactor test"
59+
60+
# Regular expression for matching conventional commits
61+
CONVENTIONAL_COMMIT_REGEX="^.* (feat|fix|perf|chore|docs|refactor|test)(\(.*\))?: "
62+
63+
print_tag() {
64+
echo "Processing tag: $2"
65+
TAG_DATE=$(git log -1 --format=%ai $2 | cut -d ' ' -f 1)
66+
if [ "$2" = "HEAD" ]; then
67+
if [ $(git rev-parse $1) != $(git rev-parse "HEAD") ]; then
68+
echo "## Unreleased changes" >> $CHANGELOG_FILE
69+
echo "" >> $CHANGELOG_FILE
70+
fi
71+
else
72+
echo "## $2 ($TAG_DATE)" >> $CHANGELOG_FILE
73+
echo "" >> $CHANGELOG_FILE
74+
fi
75+
76+
77+
# Collect all commits for this tag range
78+
if [ -z "$1" ]; then
79+
ALL_COMMITS=$(git log $2 --oneline --always)
80+
else
81+
ALL_COMMITS=$(git log $1..$2 --oneline --always)
82+
fi
83+
84+
# Process each category
85+
for KEY in $CATEGORIES; do
86+
CATEGORY_COMMITS=$(echo "$ALL_COMMITS" | grep -E "^.* $KEY(\(.*\))?: " || true)
87+
if [ ! -z "$CATEGORY_COMMITS" ]; then
88+
case $KEY in
89+
"feat") CATEGORY_NAME="Feature" ;;
90+
"fix") CATEGORY_NAME="Bug Fixes" ;;
91+
"perf") CATEGORY_NAME="Performance Improvements" ;;
92+
"chore") CATEGORY_NAME="Chore" ;;
93+
"docs") CATEGORY_NAME="Documentation" ;;
94+
"refactor") CATEGORY_NAME="Refactor" ;;
95+
"test") CATEGORY_NAME="Test" ;;
96+
esac
97+
echo "### $CATEGORY_NAME" >> $CHANGELOG_FILE
98+
echo "Listing commits for category: $CATEGORY_NAME under tag $2"
99+
echo "$CATEGORY_COMMITS" | while read -r COMMIT; do
100+
HASH=$(echo $COMMIT | awk '{print $1}')
101+
MESSAGE=$(echo $COMMIT | sed -E "s/^$HASH $KEY(\(.*\))?: //")
102+
if [ "$GITHUB_REPO_URL" != "0" ]; then
103+
echo "- $MESSAGE [\`$HASH\`]($GITHUB_REPO_URL/commit/$HASH)" >> $CHANGELOG_FILE
104+
else
105+
echo "- $MESSAGE" >> $CHANGELOG_FILE
106+
fi
107+
done
108+
echo "" >> $CHANGELOG_FILE
109+
fi
110+
done
111+
112+
# Process 'Other' category
113+
OTHER_COMMITS=$(echo "$ALL_COMMITS" | grep -v -E "$CONVENTIONAL_COMMIT_REGEX" || true)
114+
if [ ! -z "$OTHER_COMMITS" ]; then
115+
echo "### Other" >> $CHANGELOG_FILE
116+
echo "Listing commits for category: Other under tag $2"
117+
echo "$OTHER_COMMITS" | while read -r COMMIT; do
118+
HASH=$(echo $COMMIT | awk '{print $1}')
119+
MESSAGE=$(echo $COMMIT | sed -E 's/^[^ ]* //')
120+
if [ "$GITHUB_REPO_URL" != "0" ]; then
121+
echo "- $MESSAGE [\`$HASH\`]($GITHUB_REPO_URL/commit/$HASH)" >> $CHANGELOG_FILE
122+
else
123+
echo "- $MESSAGE" >> $CHANGELOG_FILE
124+
fi
125+
done
126+
echo "" >> $CHANGELOG_FILE
127+
fi
128+
129+
echo "Completed processing tag: $2"
130+
# Update the previous tag
131+
}
132+
133+
# Iterate over tags
134+
for TAG_FROM in $TAGS; do
135+
print_tag $TAG_FROM $TAG_TO
136+
TAG_TO=$TAG_FROM
137+
done
138+
print_tag "" $TAG_FROM
139+
140+
echo "Changelog generation complete."

0 commit comments

Comments
 (0)