Skip to content

Commit 40eab2b

Browse files
version-bump: Add version-bump reusable workflow
Automates version bump pull requests by detecting unreleased changes in CHANGELOG.md, determining the next semantic version, updating the changelog with the release date, and creating a PR from a fork to the upstream repository. Supports configurable release dates, custom git identity, and optional update scripts for projects that maintain version numbers in multiple files. Updates release-version-extract action to expose unreleased_changes output, making changelog entries available for use in commit messages and PR bodies. Co-Authored-By: roachdev-claude <roachdev-claude-bot@cockroachlabs.com>
1 parent 99c2178 commit 40eab2b

7 files changed

Lines changed: 547 additions & 10 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
# Save current directory (where CHANGELOG.md is expected)
6+
WORK_DIR="$(pwd)"
7+
8+
# Change to script directory for relative sourcing
9+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10+
cd "$SCRIPT_DIR"
11+
12+
source ../../actions_helpers.sh
13+
14+
# Check arguments
15+
if [ -z "$1" ]; then
16+
log_error "Usage: $0 <version> [release_date]"
17+
exit 1
18+
fi
19+
20+
version="$1"
21+
release_date="${2:-$(date +%Y-%m-%d)}"
22+
23+
# Go back to work directory where CHANGELOG.md is
24+
cd "$WORK_DIR"
25+
26+
# Insert new version header under [Unreleased] header
27+
awk -v version="$version" -v date="$release_date" '
28+
/^## \[Unreleased\]/ {
29+
print
30+
print ""
31+
print "## [" version "] - " date
32+
next
33+
}
34+
{ print }
35+
' CHANGELOG.md > CHANGELOG.md.tmp && mv CHANGELOG.md.tmp CHANGELOG.md
36+
37+
log_notice "Updated CHANGELOG.md with version $version dated $release_date"
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
#!/usr/bin/env bash
2+
# Tests for update-changelog.sh
3+
set -euo pipefail
4+
trap 'echo "Error occurred at line $LINENO"; exit 1' ERR
5+
6+
cd "$(dirname "${BASH_SOURCE[0]}")"
7+
source ../../test_helpers.sh
8+
source ../../actions_helpers.sh
9+
10+
# Set up temporary directory for test outputs
11+
TMPDIR_TEST=$(mktemp -d)
12+
trap 'rm -rf "$TMPDIR_TEST"' EXIT
13+
14+
# Test helper: creates a test CHANGELOG and runs update-changelog.sh
15+
test_update_changelog() {
16+
local version="$1"
17+
local release_date="$2"
18+
local changelog_content="$3"
19+
20+
# Create test directory
21+
local test_dir="${TMPDIR_TEST}/test_$(date +%s%N)"
22+
mkdir -p "$test_dir"
23+
24+
# Write test CHANGELOG
25+
echo "$changelog_content" > "$test_dir/CHANGELOG.md"
26+
27+
# Run script from test directory
28+
(cd "$test_dir" && bash "${OLDPWD}/update-changelog.sh" "$version" "$release_date")
29+
30+
# Return the updated content
31+
cat "$test_dir/CHANGELOG.md"
32+
}
33+
34+
# =============================================
35+
# Basic functionality tests
36+
# =============================================
37+
38+
test_basic_update() {
39+
local result
40+
result=$(test_update_changelog "1.0.0" "2026-03-31" "# Changelog
41+
42+
## [Unreleased]
43+
44+
### Added
45+
- New feature
46+
47+
## [0.9.0] - 2026-03-01
48+
- Old feature")
49+
50+
check_contains "## [Unreleased]" <<<"$result"
51+
check_contains "## [1.0.0] - 2026-03-31" <<<"$result"
52+
check_contains "### Added" <<<"$result"
53+
check_contains "- New feature" <<<"$result"
54+
check_contains "## [0.9.0] - 2026-03-01" <<<"$result"
55+
}
56+
expect_success "basic update: inserts version below Unreleased" test_basic_update
57+
58+
test_custom_release_date() {
59+
local result
60+
result=$(test_update_changelog "1.5.0" "2025-12-25" "# Changelog
61+
62+
## [Unreleased]
63+
64+
### Added
65+
- Holiday release
66+
67+
## [1.4.0] - 2025-11-01
68+
69+
### Added
70+
- Previous feature")
71+
72+
check_contains "## [1.5.0] - 2025-12-25" <<<"$result"
73+
}
74+
expect_success "uses custom release date" test_custom_release_date
75+
76+
test_default_release_date() {
77+
local result today
78+
today=$(date +%Y-%m-%d)
79+
80+
result=$(test_update_changelog "3.0.0" "" "# Changelog
81+
82+
## [Unreleased]
83+
84+
### Added
85+
- Latest change")
86+
87+
check_contains "## [3.0.0] - $today" <<<"$result"
88+
}
89+
expect_success "defaults to current date when not provided" test_default_release_date
90+
91+
# =============================================
92+
# Edge cases
93+
# =============================================
94+
95+
test_empty_unreleased_section() {
96+
local result
97+
result=$(test_update_changelog "1.1.0" "2026-03-31" "# Changelog
98+
99+
## [Unreleased]
100+
101+
## [1.0.0] - 2026-03-01
102+
103+
### Added
104+
- First release")
105+
106+
check_contains "## [Unreleased]" <<<"$result"
107+
check_contains "## [1.1.0] - 2026-03-31" <<<"$result"
108+
check_contains "## [1.0.0] - 2026-03-01" <<<"$result"
109+
}
110+
expect_success "handles empty Unreleased section" test_empty_unreleased_section
111+
112+
test_multiple_subsections() {
113+
local result
114+
result=$(test_update_changelog "2.1.0" "2026-03-31" "# Changelog
115+
116+
## [Unreleased]
117+
118+
### Added
119+
- New API endpoint
120+
121+
### Changed
122+
- Updated dependencies
123+
124+
### Fixed
125+
- Bug fix
126+
127+
## [2.0.0] - 2026-02-01")
128+
129+
check_contains "## [2.1.0] - 2026-03-31" <<<"$result"
130+
check_contains "### Added" <<<"$result"
131+
check_contains "### Changed" <<<"$result"
132+
check_contains "### Fixed" <<<"$result"
133+
}
134+
expect_success "preserves multiple subsections" test_multiple_subsections
135+
136+
test_version_with_leading_zeros() {
137+
local result
138+
result=$(test_update_changelog "0.1.0" "2026-03-31" "# Changelog
139+
140+
## [Unreleased]
141+
142+
### Added
143+
- Initial release")
144+
145+
check_contains "## [0.1.0] - 2026-03-31" <<<"$result"
146+
}
147+
expect_success "handles version with leading zeros" test_version_with_leading_zeros
148+
149+
test_multi_digit_version() {
150+
local result
151+
result=$(test_update_changelog "10.20.30" "2026-03-31" "# Changelog
152+
153+
## [Unreleased]
154+
155+
### Added
156+
- Major milestone")
157+
158+
check_contains "## [10.20.30] - 2026-03-31" <<<"$result"
159+
}
160+
expect_success "handles multi-digit version numbers" test_multi_digit_version
161+
162+
# =============================================
163+
# Error cases
164+
# =============================================
165+
166+
test_missing_version_argument() {
167+
local test_dir="${TMPDIR_TEST}/test_missing_arg"
168+
mkdir -p "$test_dir"
169+
echo "# Changelog" > "$test_dir/CHANGELOG.md"
170+
171+
# Should fail when no version argument provided
172+
! (cd "$test_dir" && bash "${OLDPWD}/update-changelog.sh" 2>&1) | check_contains "Usage:"
173+
}
174+
expect_success "fails with usage message when version missing" test_missing_version_argument
175+
176+
print_results

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ jobs:
77
test:
88
runs-on: ubuntu-latest
99
steps:
10-
- uses: actions/checkout@v5
10+
- uses: actions/checkout@v6
1111
- run: ./test.sh

0 commit comments

Comments
 (0)