Skip to content

Commit 3b46cf3

Browse files
committed
split up changelogs + changelog generation even further
1 parent 64a5e6d commit 3b46cf3

File tree

2 files changed

+201
-39
lines changed

2 files changed

+201
-39
lines changed

.github/workflows/rust-release.yml

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,20 @@ jobs:
178178
env:
179179
NEW_VERSION: ${{ steps.next_version.outputs.new_version }}
180180
run: |
181-
# Generate workspace-grouped changelog using custom script
181+
# Get commit range for changelog generation
182182
LATEST_TAG=$(git tag -l "agents-v*" --sort=-version:refname | grep -E "^agents-v[0-9]+\.[0-9]+\.[0-9]+$" | head -1)
183183
184184
if [ -z "$LATEST_TAG" ]; then
185-
CHANGELOG=$(./rust/scripts/generate-workspace-changelog.sh)
185+
COMMIT_RANGE=""
186+
else
187+
COMMIT_RANGE="${LATEST_TAG}..HEAD"
188+
fi
189+
190+
# Generate unified changelog for PR body
191+
if [ -z "$COMMIT_RANGE" ]; then
192+
CHANGELOG=$(./rust/scripts/generate-workspace-changelog.sh --no-header)
186193
else
187-
CHANGELOG=$(./rust/scripts/generate-workspace-changelog.sh "${LATEST_TAG}..HEAD")
194+
CHANGELOG=$(./rust/scripts/generate-workspace-changelog.sh "$COMMIT_RANGE" --no-header)
188195
fi
189196
190197
# Save changelog to file for PR body
@@ -196,6 +203,9 @@ jobs:
196203
echo "$CHANGELOG"
197204
echo 'EOF'
198205
} >> $GITHUB_OUTPUT
206+
207+
# Generate per-workspace CHANGELOG.md files
208+
./rust/scripts/generate-workspace-changelog.sh "$COMMIT_RANGE" "" --write-to-workspace "$NEW_VERSION"
199209
- name: Update version files
200210
working-directory: ./rust/main
201211
env:
@@ -223,26 +233,6 @@ jobs:
223233
cd ../sealevel
224234
cargo update --workspace --offline 2>/dev/null || cargo update --workspace
225235
echo "Updated rust/sealevel/Cargo.lock"
226-
cd ../main
227-
228-
# Prepend new version to CHANGELOG.md
229-
if [ -f CHANGELOG.md ]; then
230-
CURRENT_CHANGELOG=$(cat CHANGELOG.md)
231-
else
232-
CURRENT_CHANGELOG=""
233-
fi
234-
235-
cat > CHANGELOG.md <<EOF
236-
# Changelog
237-
238-
## [$NEW_VERSION] - $(date +%Y-%m-%d)
239-
240-
$(cat /tmp/changelog.md)
241-
242-
$CURRENT_CHANGELOG
243-
EOF
244-
245-
echo "Updated CHANGELOG.md"
246236
- name: Create or update release PR
247237
env:
248238
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -258,8 +248,9 @@ jobs:
258248
# Create branch from current HEAD (which is main)
259249
git checkout -B "$BRANCH_NAME"
260250
261-
# Stage changes
262-
git add rust/main/CHANGELOG.md rust/main/Cargo.toml rust/main/Cargo.lock rust/sealevel/Cargo.lock
251+
# Stage changes (Cargo files and all workspace CHANGELOG.md files)
252+
git add rust/main/Cargo.toml rust/main/Cargo.lock rust/sealevel/Cargo.lock
253+
git add rust/main/*/CHANGELOG.md rust/main/*/*/CHANGELOG.md 2>/dev/null || true
263254
264255
# Commit changes
265256
git commit -m "release: agents v${NEW_VERSION}

rust/scripts/generate-workspace-changelog.sh

Lines changed: 185 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,81 @@
11
#!/usr/bin/env bash
22
# Script to generate workspace-grouped changelog for rust agents
3+
#
4+
# Usage:
5+
# generate-workspace-changelog.sh [COMMIT_RANGE] [WORKSPACE_FILTER] [FLAGS]
6+
#
7+
# Arguments:
8+
# COMMIT_RANGE - Git commit range (e.g., "v1.4.0..HEAD"). Defaults to latest tag..HEAD
9+
# WORKSPACE_FILTER - Optional comma-separated list of workspaces to include (e.g., "agents/relayer,agents/validator")
10+
# If omitted, all workspaces are included
11+
#
12+
# Flags:
13+
# --no-header - Omit the "## What's Changed" header (useful for composing changelogs)
14+
# --write-to-workspace VERSION - Update CHANGELOG.md files in each workspace directory
15+
#
16+
# Examples:
17+
# ./generate-workspace-changelog.sh # All workspaces, latest tag..HEAD
18+
# ./generate-workspace-changelog.sh "v1.4.0..v1.5.0" # All workspaces, specific range
19+
# ./generate-workspace-changelog.sh "v1.4.0..v1.5.0" "agents/relayer" # Single workspace
20+
# ./generate-workspace-changelog.sh "v1.4.0..v1.5.0" "agents/relayer,agents/validator" # Multiple workspaces
21+
# ./generate-workspace-changelog.sh "v1.4.0..v1.5.0" "agents/relayer" --no-header # No header
22+
# ./generate-workspace-changelog.sh "v1.4.0..v1.5.0" "" --write-to-workspace "1.5.0" # Update workspace CHANGELOGs
23+
#
324
set -euo pipefail
425

526
# Determine script directory and repo structure
627
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
728
RUST_MAIN_DIR="$SCRIPT_DIR/../main"
829

30+
# Parse arguments
31+
COMMIT_RANGE=""
32+
WORKSPACE_FILTER=""
33+
SHOW_HEADER=true
34+
UPDATE_CHANGELOGS=false
35+
VERSION=""
36+
37+
# Parse all arguments
38+
i=1
39+
while [ $i -le $# ]; do
40+
arg="${!i}"
41+
42+
if [ "$arg" = "--no-header" ]; then
43+
SHOW_HEADER=false
44+
elif [ "$arg" = "--write-to-workspace" ]; then
45+
UPDATE_CHANGELOGS=true
46+
# Get next argument as version
47+
i=$((i + 1))
48+
if [ $i -le $# ]; then
49+
VERSION="${!i}"
50+
else
51+
echo "Error: --write-to-workspace requires a VERSION argument" >&2
52+
exit 1
53+
fi
54+
elif [ -z "$COMMIT_RANGE" ]; then
55+
COMMIT_RANGE="$arg"
56+
elif [ -z "$WORKSPACE_FILTER" ]; then
57+
WORKSPACE_FILTER="$arg"
58+
fi
59+
60+
i=$((i + 1))
61+
done
62+
963
# Get the commit range
10-
if [ $# -eq 0 ]; then
11-
# No arguments - use unreleased commits
64+
if [ -z "$COMMIT_RANGE" ]; then
65+
# No commit range specified - use unreleased commits
1266
LATEST_TAG=$(git tag -l "agents-v*" --sort=-version:refname | grep -E "^agents-v[0-9]+\.[0-9]+\.[0-9]+$" | head -1 || echo "")
1367
if [ -z "$LATEST_TAG" ]; then
1468
COMMIT_RANGE="HEAD"
1569
else
1670
COMMIT_RANGE="${LATEST_TAG}..HEAD"
1771
fi
72+
fi
73+
74+
# Parse workspace filter into array
75+
if [ -n "$WORKSPACE_FILTER" ]; then
76+
IFS=',' read -ra FILTER_ARRAY <<< "$WORKSPACE_FILTER"
1877
else
19-
COMMIT_RANGE="$1"
78+
FILTER_ARRAY=()
2079
fi
2180

2281
# Temporary directory for categorization
@@ -26,6 +85,25 @@ trap "rm -rf $TEMP_DIR" EXIT
2685
# Extract workspace members from rust/main/Cargo.toml
2786
WORKSPACE_MEMBERS=$(grep -A 100 '^\[workspace\]' "$RUST_MAIN_DIR/Cargo.toml" | sed -n '/^members = \[/,/^\]/p' | grep '"' | sed 's/[", ]//g')
2887

88+
# Helper function to check if a workspace should be included
89+
should_include_workspace() {
90+
local workspace="$1"
91+
92+
# If no filter specified, include all
93+
if [ ${#FILTER_ARRAY[@]} -eq 0 ]; then
94+
return 0
95+
fi
96+
97+
# Check if workspace is in filter list
98+
for filter in "${FILTER_ARRAY[@]}"; do
99+
if [ "$workspace" = "$filter" ]; then
100+
return 0
101+
fi
102+
done
103+
104+
return 1
105+
}
106+
29107
# Get all commits in the range (filter to rust/main directory)
30108
git log --no-merges --format="%H" $COMMIT_RANGE -- rust/main | while read -r commit_hash; do
31109
# Get commit message
@@ -50,9 +128,9 @@ git log --no-merges --format="%H" $COMMIT_RANGE -- rust/main | while read -r com
50128
done
51129
done
52130

53-
# Default to "Other" if no workspace found
131+
# Default to "other" if no workspace found
54132
if [ -z "$workspace" ]; then
55-
workspace="Other"
133+
workspace="other"
56134
fi
57135

58136
# Sanitize workspace name for file system (replace / with __)
@@ -62,20 +140,113 @@ git log --no-merges --format="%H" $COMMIT_RANGE -- rust/main | while read -r com
62140
echo "$workspace|$commit_msg|$short_hash" >> "$TEMP_DIR/$workspace_file"
63141
done
64142

65-
# Process workspace members in the order they appear in Cargo.toml, then "Other"
66-
for workspace in $WORKSPACE_MEMBERS "Other"; do
67-
workspace_file=$(echo "$workspace" | tr '/' '_')
143+
# Function to generate changelog for a specific workspace
144+
generate_workspace_changelog() {
145+
local workspace="$1"
146+
local include_header="${2:-true}" # Default to including header
147+
local workspace_file=$(echo "$workspace" | tr '/' '_')
68148

69149
if [ -f "$TEMP_DIR/$workspace_file" ]; then
70-
echo "### $workspace"
71-
echo ""
72-
73-
# Sort and deduplicate commits (extract workspace name, msg, hash)
150+
if [ "$include_header" = "true" ]; then
151+
echo "### $workspace"
152+
echo ""
153+
fi
74154
sort -u "$TEMP_DIR/$workspace_file" | while IFS='|' read -r ws msg hash; do
75155
echo "* $msg (#$hash)"
76156
done
77-
echo ""
157+
fi
158+
}
159+
160+
# If updating workspace changelogs, update files and exit
161+
if [ "$UPDATE_CHANGELOGS" = true ]; then
162+
if [ -z "$VERSION" ]; then
163+
echo "Error: VERSION is required for --write-to-workspace" >&2
164+
exit 1
165+
fi
166+
167+
echo "Updating workspace CHANGELOG.md files for version $VERSION..."
168+
UPDATED_COUNT=0
169+
170+
for workspace in $WORKSPACE_MEMBERS; do
171+
# Skip if workspace is filtered out
172+
if ! should_include_workspace "$workspace"; then
173+
continue
174+
fi
175+
176+
workspace_file=$(echo "$workspace" | tr '/' '_')
177+
178+
# Skip if no changes for this workspace
179+
if [ ! -f "$TEMP_DIR/$workspace_file" ]; then
180+
continue
181+
fi
182+
183+
# Generate changelog content for this workspace (no header)
184+
WORKSPACE_CHANGELOG=$(generate_workspace_changelog "$workspace" false)
185+
186+
if [ -z "$WORKSPACE_CHANGELOG" ]; then
187+
continue
188+
fi
189+
190+
WORKSPACE_CHANGELOG_FILE="$RUST_MAIN_DIR/$workspace/CHANGELOG.md"
191+
WORKSPACE_DIR=$(dirname "$WORKSPACE_CHANGELOG_FILE")
192+
193+
# Ensure directory exists
194+
mkdir -p "$WORKSPACE_DIR"
195+
196+
# Read existing changelog if it exists
197+
if [ -f "$WORKSPACE_CHANGELOG_FILE" ]; then
198+
CURRENT_WORKSPACE_CHANGELOG=$(cat "$WORKSPACE_CHANGELOG_FILE")
199+
else
200+
CURRENT_WORKSPACE_CHANGELOG=""
201+
fi
202+
203+
# Prepend new version to workspace changelog
204+
{
205+
echo "## [$VERSION] - $(date +%Y-%m-%d)"
206+
echo ""
207+
echo "$WORKSPACE_CHANGELOG"
208+
if [ -n "$CURRENT_WORKSPACE_CHANGELOG" ]; then
209+
echo ""
210+
echo "$CURRENT_WORKSPACE_CHANGELOG"
211+
fi
212+
} > "$WORKSPACE_CHANGELOG_FILE"
213+
214+
echo "Updated $workspace/CHANGELOG.md"
215+
UPDATED_COUNT=$((UPDATED_COUNT + 1))
216+
done
217+
218+
echo "Updated $UPDATED_COUNT workspace changelog(s)"
219+
exit 0
220+
fi
221+
222+
# Generate output (for display/PR body)
223+
if [ "$SHOW_HEADER" = true ]; then
224+
echo "## What's Changed"
225+
echo ""
226+
fi
227+
228+
# Process workspace members in the order they appear in Cargo.toml, then "other"
229+
FIRST_WORKSPACE=true
230+
for workspace in $WORKSPACE_MEMBERS "other"; do
231+
# Skip if workspace is filtered out
232+
if ! should_include_workspace "$workspace"; then
233+
continue
234+
fi
235+
236+
workspace_file=$(echo "$workspace" | tr '/' '_')
237+
238+
if [ -f "$TEMP_DIR/$workspace_file" ]; then
239+
# Add separator between workspaces (except before first one)
240+
if [ "$FIRST_WORKSPACE" = false ]; then
241+
echo ""
242+
fi
243+
FIRST_WORKSPACE=false
244+
245+
generate_workspace_changelog "$workspace"
78246
fi
79247
done
80248

81-
echo "<!-- generated by workspace changelog script -->"
249+
if [ "$SHOW_HEADER" = true ]; then
250+
echo ""
251+
echo "<!-- generated by workspace changelog script -->"
252+
fi

0 commit comments

Comments
 (0)