Skip to content

Commit bba9531

Browse files
committed
add new generate-changelog task
1 parent 3025421 commit bba9531

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

generate-changelog.sh

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/bin/bash
2+
3+
set -euo pipefail
4+
5+
# Ensure gh CLI available
6+
if ! command -v gh &> /dev/null; then
7+
echo "gh CLI is required but not installed." >&2
8+
exit 1
9+
fi
10+
11+
cd $(dirname "$0")/../../
12+
13+
LATEST_RELEASE_TAG=$(gh release list --json tagName,isLatest --jq '.[] | select(.isLatest)|.tagName')
14+
if [[ -e $LATEST_RELEASE_TAG ]]; then # first release?
15+
LATEST_RELEASE_TAG=$(git rev-list --max-parents=0 HEAD) # first commit in the branch.
16+
fi
17+
18+
PR_COMMITS=$(git log "$LATEST_RELEASE_TAG"..HEAD --oneline --pretty=format:"%s" main | grep -oE "#[0-9]+" | tr -d '#' | sort -u)
19+
20+
CHANGELOG_FILE=./CHANGELOG.md
21+
# File header Header
22+
echo "# Changes included in $VERSION:" > "$CHANGELOG_FILE"
23+
echo "" >> "$CHANGELOG_FILE"
24+
25+
declare -A SECTIONS
26+
SECTIONS=(
27+
[feat]="### 🚀 Features"
28+
[fix]="### 🐛 Fixes"
29+
[chore]="### 🔧 Chores"
30+
[docs]="### 📚 Documentation"
31+
[refactor]="### 🔨 Refactoring"
32+
[test]="### ✅ Tests"
33+
[perf]="### ⚡ Performance"
34+
[ci]="### 🔁 CI"
35+
)
36+
37+
# Prepare section buffers
38+
declare -A PR_ENTRIES
39+
for key in "${!SECTIONS[@]}"; do
40+
PR_ENTRIES[$key]=""
41+
done
42+
43+
for PR_NUMBER in $PR_COMMITS; do
44+
PR_JSON=$(gh pr view "$PR_NUMBER" --json number,title,body,url,author)
45+
46+
IS_BOT=$(echo "$PR_JSON" | jq -r '.author.is_bot')
47+
if [[ "$IS_BOT" == "true" ]]; then
48+
continue
49+
fi
50+
51+
TITLE=$(echo "$PR_JSON" | jq -r '.title')
52+
URL=$(echo "$PR_JSON" | jq -r '.url')
53+
BODY=$(echo "$PR_JSON" | jq -r '.body')
54+
55+
# Determine type from conventional commit (assumes title like "type(scope): message" or "type: message")
56+
TYPE=$(echo "$TITLE" | grep -oE '^[a-z]+' || echo "feat")
57+
CLEAN_TITLE=$(echo "$TITLE" | sed -E 's/^[a-z]+(\([^)]+\))?(!)?:[[:space:]]+//')
58+
59+
# Extract release note block, we only extract the "user" related notes.
60+
RELEASE_NOTE=$(echo "$BODY" | awk '/^```[[:space:]]*(breaking|feature|bugfix|doc|other)[[:space:]]+user[[:space:]]*$/ {flag=1; next} /^```[[:space:]]*$/ {flag=0} flag' || true)
61+
62+
# Format entry
63+
ENTRY="- $CLEAN_TITLE [#${PR_NUMBER}](${URL})"
64+
if [[ -n "$RELEASE_NOTE" || "$RELEASE_NOTE" != "NONE" ]]; then
65+
ENTRY+=": $RELEASE_NOTE"
66+
else
67+
ENTRY+="."
68+
fi
69+
ENTRY+="\n"
70+
71+
# Append to appropriate section
72+
if [[ -n "${PR_ENTRIES[$TYPE]+x}" ]]; then
73+
PR_ENTRIES[$TYPE]+="$ENTRY"
74+
else
75+
PR_ENTRIES[chore]+="$ENTRY"
76+
fi
77+
done
78+
79+
# Output sections
80+
for key in "${!SECTIONS[@]}"; do
81+
if [[ -n "${PR_ENTRIES[$key]}" ]]; then
82+
echo "${SECTIONS[$key]}" >> "$CHANGELOG_FILE"
83+
echo -e "${PR_ENTRIES[$key]}" >> "$CHANGELOG_FILE"
84+
echo "" >> "$CHANGELOG_FILE"
85+
fi
86+
done
87+
88+
cat "$CHANGELOG_FILE"

tasks_rls.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,13 @@ tasks:
139139
desc: "List all nested modules in the project."
140140
cmds:
141141
- cmd: 'echo "{{.NESTED_MODULES}}"'
142+
143+
generate-changelog:
144+
desc: " Generates an automated release changelog based on conventional-commits PR titles in CHANGELOG.md file."
145+
run: once
146+
requires:
147+
vars:
148+
- VERSION
149+
cmds:
150+
- 'VERSION={{.VERSION}} {{.TASKFILE_DIR2}}/generate-changelog.sh'
151+

0 commit comments

Comments
 (0)