Skip to content

Commit 724fc98

Browse files
ci: generate release notes for rc releases from conventional commits (#546)
1 parent cc3d818 commit 724fc98

2 files changed

Lines changed: 106 additions & 2 deletions

File tree

.github/workflows/release-please-prerelease.yml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ jobs:
1515
outputs:
1616
new_version: ${{ steps.bump.outputs.new_version }}
1717
skipped: ${{ steps.bump.outputs.skipped }}
18+
last_tag: ${{ steps.bump.outputs.last_tag }}
1819
steps:
1920
- uses: actions/checkout@v4
2021
with:
2122
fetch-depth: 0
2223
token: ${{ secrets.GITHUB_TOKEN }}
2324

24-
- name: Compute and write next rc version
25+
- name: Compute next rc version
2526
id: bump
2627
run: |
2728
set +e
@@ -33,17 +34,38 @@ jobs:
3334
echo "skipped=true" >> "$GITHUB_OUTPUT"
3435
exit 0
3536
fi
37+
LAST_TAG="$(git describe --tags --abbrev=0 2>/dev/null || echo "")"
3638
echo "new_version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
39+
echo "last_tag=$LAST_TAG" >> "$GITHUB_OUTPUT"
3740
echo "skipped=false" >> "$GITHUB_OUTPUT"
3841
42+
- name: Generate release notes
43+
id: notes
44+
if: steps.bump.outputs.skipped != 'true'
45+
run: |
46+
NOTES="$(bash Scripts/generate-changelog.sh \
47+
"${{ steps.bump.outputs.last_tag }}" \
48+
HEAD \
49+
"${{ steps.bump.outputs.new_version }}")"
50+
# Write to file to safely pass multiline content
51+
echo "$NOTES" > /tmp/release-notes.md
52+
echo "notes_file=/tmp/release-notes.md" >> "$GITHUB_OUTPUT"
53+
3954
- name: Tag
4055
if: steps.bump.outputs.skipped != 'true'
4156
run: |
4257
git config user.name "github-actions[bot]"
4358
git config user.email "github-actions[bot]@users.noreply.github.com"
44-
git tag "v${{ steps.bump.outputs.new_version }}"
59+
git tag -a "v${{ steps.bump.outputs.new_version }}" -m "chore: release ${{ steps.bump.outputs.new_version }}"
4560
git push origin "v${{ steps.bump.outputs.new_version }}"
4661
62+
- name: Upload release notes
63+
if: steps.bump.outputs.skipped != 'true'
64+
uses: actions/upload-artifact@v6
65+
with:
66+
name: release-notes
67+
path: /tmp/release-notes.md
68+
4769
publish-windows:
4870
needs: bump-version
4971
if: ${{ needs.bump-version.outputs.skipped != 'true' }}
@@ -87,4 +109,5 @@ jobs:
87109
name: ${{ needs.bump-version.outputs.new_version }}
88110
prerelease: true
89111
generate_release_notes: false
112+
body_path: artifacts/release-notes/release-notes.md
90113
files: artifacts/**/*

Scripts/generate-changelog.sh

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env bash
2+
# Generates a markdown changelog from conventional commits between two refs.
3+
#
4+
# Usage: generate-changelog.sh <from-ref> <to-ref> <version>
5+
# Output: markdown string printed to stdout
6+
7+
set -euo pipefail
8+
9+
FROM_REF="${1:-}"
10+
TO_REF="${2:-HEAD}"
11+
VERSION="${3:-unreleased}"
12+
13+
if [ -z "$FROM_REF" ]; then
14+
COMMIT_RANGE="$TO_REF"
15+
else
16+
COMMIT_RANGE="$FROM_REF..$TO_REF"
17+
fi
18+
19+
declare -a BREAKING=()
20+
declare -a FEATURES=()
21+
declare -a FIXES=()
22+
declare -a PERF=()
23+
declare -a REFACTORS=()
24+
declare -a OTHER=()
25+
26+
while IFS= read -r line; do
27+
[ -z "$line" ] && continue
28+
29+
if echo "$line" | grep -qE '^(feat|fix|perf|refactor|build|ci|revert)(\(.+\))?!:' || \
30+
echo "$line" | grep -qE 'BREAKING CHANGE:'; then
31+
BREAKING+=("$line")
32+
elif echo "$line" | grep -qE '^feat(\(.+\))?:'; then
33+
FEATURES+=("$line")
34+
elif echo "$line" | grep -qE '^fix(\(.+\))?:'; then
35+
FIXES+=("$line")
36+
elif echo "$line" | grep -qE '^perf(\(.+\))?:'; then
37+
PERF+=("$line")
38+
elif echo "$line" | grep -qE '^refactor(\(.+\))?:'; then
39+
REFACTORS+=("$line")
40+
fi
41+
done < <(git log "$COMMIT_RANGE" --format="%s" 2>/dev/null)
42+
43+
echo "## $VERSION"
44+
echo ""
45+
echo "$(date -u +%Y-%m-%d)"
46+
echo ""
47+
48+
if [ ${#BREAKING[@]} -gt 0 ]; then
49+
echo "### ⚠ Breaking Changes"
50+
echo ""
51+
for entry in "${BREAKING[@]}"; do echo "* $entry"; done
52+
echo ""
53+
fi
54+
55+
if [ ${#FEATURES[@]} -gt 0 ]; then
56+
echo "### Features"
57+
echo ""
58+
for entry in "${FEATURES[@]}"; do echo "* $entry"; done
59+
echo ""
60+
fi
61+
62+
if [ ${#FIXES[@]} -gt 0 ]; then
63+
echo "### Bug Fixes"
64+
echo ""
65+
for entry in "${FIXES[@]}"; do echo "* $entry"; done
66+
echo ""
67+
fi
68+
69+
if [ ${#PERF[@]} -gt 0 ]; then
70+
echo "### Performance"
71+
echo ""
72+
for entry in "${PERF[@]}"; do echo "* $entry"; done
73+
echo ""
74+
fi
75+
76+
if [ ${#REFACTORS[@]} -gt 0 ]; then
77+
echo "### Refactors"
78+
echo ""
79+
for entry in "${REFACTORS[@]}"; do echo "* $entry"; done
80+
echo ""
81+
fi

0 commit comments

Comments
 (0)