Skip to content

Commit 1d92e3c

Browse files
committed
build: update prepare release script to automatically merge goreleaser-created changelog contents into root changelog
1 parent 77dd007 commit 1d92e3c

1 file changed

Lines changed: 177 additions & 8 deletions

File tree

scripts/prepare-release.sh

Lines changed: 177 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,154 @@ GREEN='\033[0;32m'
1212
YELLOW='\033[1;33m'
1313
NC='\033[0m' # No Color
1414

15+
# Merge GoReleaser changelog into Keep a Changelog format
16+
# Arguments:
17+
# $1 - Version (e.g., v0.4.0)
18+
# Returns:
19+
# 0 on success, 1 on failure
20+
merge_changelog() {
21+
local version="$1"
22+
local version_number="${version#v}"
23+
local dist_changelog="dist/CHANGELOG.md"
24+
local root_changelog="CHANGELOG.md"
25+
local repo_url="https://github.com/leefowlercu/go-contextforge"
26+
27+
# Edge case 1: dist/CHANGELOG.md doesn't exist
28+
if [ ! -f "$dist_changelog" ]; then
29+
echo -e "${YELLOW}Warning: $dist_changelog not found${NC}"
30+
echo -e "${YELLOW}Skipping changelog merge${NC}"
31+
return 0
32+
fi
33+
34+
# Edge case 2: dist/CHANGELOG.md is empty
35+
if [ ! -s "$dist_changelog" ]; then
36+
echo -e "${YELLOW}Warning: $dist_changelog is empty (no commits since last release)${NC}"
37+
echo -e "${YELLOW}Skipping changelog merge${NC}"
38+
return 0
39+
fi
40+
41+
# Edge case 3: Version already exists
42+
if grep -q "^## \[${version_number}\]" "$root_changelog"; then
43+
echo -e "${RED}Error: Version ${version_number} already exists in $root_changelog${NC}"
44+
return 1
45+
fi
46+
47+
# Get date from tag
48+
local tag_date
49+
tag_date=$(git log -1 --format=%cd --date=short "$version")
50+
51+
# Build version header
52+
local new_section="## [${version_number}] - ${tag_date}"
53+
54+
# Parse dist/CHANGELOG.md and transform to Keep a Changelog format
55+
local current_section=""
56+
local section_content=""
57+
local all_content=""
58+
59+
while IFS= read -r line; do
60+
# Skip "## Changelog" header
61+
if [[ "$line" == "## Changelog" ]]; then
62+
continue
63+
fi
64+
65+
# Detect section headers
66+
if [[ "$line" =~ ^###[[:space:]](.+)$ ]]; then
67+
# Save previous section if it has content
68+
if [ -n "$current_section" ] && [ -n "$section_content" ]; then
69+
all_content+="### ${current_section}"$'\n'
70+
all_content+="${section_content}"$'\n'
71+
fi
72+
73+
# Start new section
74+
current_section="${BASH_REMATCH[1]}"
75+
section_content=""
76+
77+
# Transform entry lines
78+
elif [[ "$line" =~ ^\*[[:space:]][a-f0-9]{7}[[:space:]](.+)$ ]]; then
79+
# Extract message and capitalize first letter
80+
local message="${BASH_REMATCH[1]}"
81+
local first_char="${message:0:1}"
82+
local rest="${message:1}"
83+
message="$(echo "$first_char" | tr '[:lower:]' '[:upper:]')${rest}"
84+
85+
section_content+="- ${message}"$'\n'
86+
fi
87+
done < "$dist_changelog"
88+
89+
# Add final section
90+
if [ -n "$current_section" ] && [ -n "$section_content" ]; then
91+
all_content+="### ${current_section}"$'\n'
92+
all_content+="${section_content}"$'\n'
93+
fi
94+
95+
# Edge case 4: No content extracted
96+
if [ -z "$all_content" ]; then
97+
echo -e "${YELLOW}Warning: No changelog entries found in $dist_changelog${NC}"
98+
echo -e "${YELLOW}Skipping changelog merge${NC}"
99+
return 0
100+
fi
101+
102+
# Build complete new version section
103+
local new_version_block="${new_section}"$'\n'$'\n'
104+
new_version_block+="${all_content}"
105+
106+
# Find insertion point (first version section)
107+
local first_version_line
108+
first_version_line=$(grep -n '^## \[' "$root_changelog" | head -1 | cut -d: -f1)
109+
110+
if [ -z "$first_version_line" ]; then
111+
echo -e "${RED}Error: Could not find version sections in $root_changelog${NC}"
112+
return 1
113+
fi
114+
115+
# Insert new version section
116+
{
117+
head -n $((first_version_line - 1)) "$root_changelog"
118+
echo "$new_version_block"
119+
tail -n "+${first_version_line}" "$root_changelog"
120+
} > "${root_changelog}.new"
121+
122+
mv "${root_changelog}.new" "$root_changelog"
123+
124+
# Update footer links
125+
local links_start
126+
links_start=$(grep -n '^\[[0-9]' "$root_changelog" | head -1 | cut -d: -f1)
127+
128+
if [ -z "$links_start" ]; then
129+
# Edge case 5: No links section - append at end
130+
echo "" >> "$root_changelog"
131+
132+
# Edge case 6: Check if this is first release
133+
local prev_tag
134+
prev_tag=$(git describe --tags --abbrev=0 "${version}^" 2>/dev/null)
135+
136+
if [ -z "$prev_tag" ]; then
137+
echo "[${version_number}]: ${repo_url}/releases/tag/${version}" >> "$root_changelog"
138+
else
139+
echo "[${version_number}]: ${repo_url}/compare/${prev_tag}...${version}" >> "$root_changelog"
140+
fi
141+
else
142+
# Insert new link at top of links section
143+
local prev_tag
144+
prev_tag=$(git describe --tags --abbrev=0 "${version}^" 2>/dev/null)
145+
146+
local new_link
147+
if [ -z "$prev_tag" ]; then
148+
new_link="[${version_number}]: ${repo_url}/releases/tag/${version}"
149+
else
150+
new_link="[${version_number}]: ${repo_url}/compare/${prev_tag}...${version}"
151+
fi
152+
153+
# Use sed to insert before links_start
154+
sed -i.bak "${links_start}i\\
155+
${new_link}
156+
" "$root_changelog"
157+
rm -f "${root_changelog}.bak"
158+
fi
159+
160+
return 0
161+
}
162+
15163
# Validate version argument
16164
if [ -z "$VERSION" ]; then
17165
echo -e "${RED}Error: VERSION argument is required${NC}"
@@ -100,31 +248,52 @@ fi
100248

101249
echo -e "${GREEN}GoReleaser completed successfully!${NC}"
102250

251+
# Merge dist/CHANGELOG.md into root CHANGELOG.md
252+
echo -e "${YELLOW}Merging changelog...${NC}"
253+
if ! merge_changelog "$VERSION"; then
254+
echo -e "${RED}Error: Changelog merge failed${NC}"
255+
echo -e "${YELLOW}Undoing tag and commit...${NC}"
256+
git tag -d "$VERSION"
257+
git reset --hard HEAD~1
258+
exit 1
259+
fi
260+
261+
echo -e "${GREEN}Changelog merged successfully!${NC}"
262+
263+
# Amend commit to include CHANGELOG.md changes
264+
git add CHANGELOG.md
265+
git commit --amend --no-edit
266+
echo -e "${GREEN}Updated release commit with changelog${NC}"
267+
103268
# Display next steps
104269
echo ""
105270
echo -e "${GREEN}========================================${NC}"
106271
echo -e "${GREEN}Release preparation complete!${NC}"
107272
echo -e "${GREEN}========================================${NC}"
108273
echo ""
109-
echo -e "${YELLOW}GoReleaser has:${NC}"
110-
echo " - Updated CHANGELOG.md"
274+
echo -e "${YELLOW}Completed steps:${NC}"
275+
echo " - Updated version in contextforge/version.go"
276+
echo " - Merged GoReleaser changelog into CHANGELOG.md"
277+
echo " - Created release commit and tag $VERSION"
111278
echo " - Created draft GitHub release"
112279
echo ""
113280
echo -e "${YELLOW}Next steps:${NC}"
114-
echo "1. Review the draft release on GitHub:"
115-
echo " https://github.com/leefowlercu/go-contextforge/releases"
281+
echo "1. Review changelog changes:"
282+
echo " git show HEAD:CHANGELOG.md"
283+
echo " git diff HEAD~1 CHANGELOG.md"
116284
echo ""
117-
echo "2. Review CHANGELOG.md changes:"
118-
echo " git diff CHANGELOG.md"
285+
echo "2. Review draft release on GitHub:"
286+
echo " https://github.com/leefowlercu/go-contextforge/releases"
119287
echo ""
120288
echo "3. If changes needed:"
121-
echo " - Edit release notes on GitHub and/or CHANGELOG.md locally"
289+
echo " - Edit CHANGELOG.md locally and/or release notes on GitHub"
122290
echo " - Amend commit: git add CHANGELOG.md && git commit --amend --no-edit"
291+
echo " - Update tag: git tag -fa $VERSION -m \"Go ContextForge SDK $VERSION\""
123292
echo " - OR undo completely: git tag -d $VERSION && git reset --hard HEAD~1"
124293
echo ""
125294
echo "4. When ready to publish:"
126295
echo " - Push commit and tag: git push && git push --tags"
127296
echo " - Publish draft release on GitHub"
128297
echo ""
129-
echo -e "${YELLOW}Note: GoReleaser created a DRAFT release. Review before publishing.${NC}"
298+
echo -e "${YELLOW}Note: Review merged changelog format matches Keep a Changelog standards.${NC}"
130299
echo ""

0 commit comments

Comments
 (0)