Skip to content

Commit 9dc4b79

Browse files
Publishing: add set-version.sh script
1 parent a3f128e commit 9dc4b79

1 file changed

Lines changed: 154 additions & 0 deletions

File tree

scripts/set-version.sh

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# This script has a regular and a `--release` mode.
5+
#
6+
# In regular mode this script will:
7+
# - update `versionNumber` in `/build.gradle.kts`
8+
# - in `CHANGELOG.md`, if it doesn't exist, add a next release heading
9+
# - on confirmation, commit the changes
10+
# - suggest a git command to push the changes
11+
#
12+
# In release mode:
13+
# - ask to confirm `versionNumber` in `/build.gradle.kts`
14+
# - in `BoxStore.java` update `JNI_VERSION` to match `VERSION`
15+
# - in `README.md` update version numbers in known locations
16+
# - in `CHANGELOG.md` change the next version header to the new version and date
17+
# - on confirmation, commit the changes, create a release tag
18+
# - suggest git commands to push the changes
19+
20+
# Parse optional --release flag
21+
releaseFlag=false
22+
for arg in "$@"; do
23+
case "$arg" in
24+
--release) releaseFlag=true ;;
25+
esac
26+
done
27+
28+
buildScriptFile="../build.gradle.kts"
29+
propVersionNumber="versionNumber"
30+
31+
boxStorePath="$(dirname "$0")/../objectbox-java/src/main/java/io/objectbox/BoxStore.java"
32+
readmePath="$(dirname "$0")/../README.md"
33+
changelogPath="$(dirname "$0")/../CHANGELOG.md"
34+
nextReleaseHeading="## Next release"
35+
36+
# Extract the value of `versionNumber` in build.gradle.kts and store it in the versionCurrent variable
37+
buildScriptPath="$(dirname "$0")/$buildScriptFile"
38+
# Regex matches 'versionNumber = "..."', \K to only capture the version string inside the quotes
39+
versionCurrent=$(grep --only-matching --perl-regexp "$propVersionNumber"' = "\K[^"]+' "$buildScriptPath" || true)
40+
if [[ -z "$versionCurrent" ]]; then
41+
echo "Error: could not find '$propVersionNumber' in '$buildScriptFile'"
42+
exit 1
43+
fi
44+
45+
echo ""
46+
echo "Maven artifacts version ($propVersionNumber in $buildScriptFile)"
47+
echo "Current: $versionCurrent"
48+
49+
if $releaseFlag; then
50+
# Release: Confirm the current version
51+
read -r -p "Press enter to confirm the current version, or enter a custom one: " versionInput
52+
if [[ -n "$versionInput" ]]; then
53+
versionNew="$versionInput"
54+
else
55+
versionNew="$versionCurrent"
56+
fi
57+
else
58+
# Suggest a next version
59+
# Increment the last number in the version string (like 5.4.2 -> 5.4.3, 5.4.2-preview1 -> 5.4.2-preview2)
60+
# Regex: captures the trailing digits and replaces them with a value increased by 1
61+
[[ "$versionCurrent" =~ ^(.*[^0-9])([0-9]+)$ ]] || { echo "Error: $propVersionNumber '$versionCurrent' does not end with a number"; exit 1; }
62+
versionSuggested="${BASH_REMATCH[1]}$(( BASH_REMATCH[2] + 1 ))"
63+
echo "Suggested: $versionSuggested"
64+
read -r -p "Press enter to use the suggested version, or enter a custom one: " versionInput
65+
if [[ -n "$versionInput" ]]; then
66+
versionNew="$versionInput"
67+
else
68+
versionNew="$versionSuggested"
69+
fi
70+
fi
71+
echo "Version will be $versionNew"
72+
73+
# Change the value of `versionNumber` in build.gradle.kts to the value of versionNew
74+
sed --in-place "s/$propVersionNumber = \"$versionCurrent\"/$propVersionNumber = \"$versionNew\"/" "$buildScriptPath"
75+
76+
if $releaseFlag; then
77+
# In BoxStore.java set JNI_VERSION to the value of VERSION (not using versionNew!) and print the used value
78+
# Regex matches 'String VERSION = "...", \K to only capture the version string inside the quotes
79+
versionJni=$(grep --only-matching --perl-regexp 'String VERSION = "\K[^"]+' "$boxStorePath" || true)
80+
if [[ -z "$versionJni" ]]; then
81+
echo "Error: could not find VERSION in BoxStore.java"
82+
exit 1
83+
fi
84+
echo "Release: setting BoxStore.JNI_VERSION to $versionJni"
85+
sed --in-place "s/String JNI_VERSION = \".*\"/String JNI_VERSION = \"$versionJni\"/" "$boxStorePath"
86+
87+
# Change version strings in README.md to versionNew
88+
echo "Release: updating README.md version strings"
89+
sed --in-place "s/objectbox = \".*\"/objectbox = \"$versionNew\"/g" "$readmePath"
90+
sed --in-place "s/id(\"io.objectbox\") version \".*\"/id(\"io.objectbox\") version \"$versionNew\"/g" "$readmePath"
91+
sed --in-place "s/val objectboxVersion by extra(\".*\")/val objectboxVersion by extra(\"$versionNew\")/g" "$readmePath"
92+
sed --in-place "s/ext.objectboxVersion = \".*\"/ext.objectboxVersion = \"$versionNew\"/g" "$readmePath"
93+
94+
# Change header "Next release" in CHANGELOG.md to "versionNew - YYYY-MM-DD"
95+
echo "Release: updating CHANGELOG.md heading"
96+
today=$(date +"%Y-%m-%d")
97+
if grep --quiet "^$nextReleaseHeading" "$changelogPath"; then
98+
sed --in-place "s/^$nextReleaseHeading/## $versionNew - $today/" "$changelogPath"
99+
else
100+
echo "⚠️ '$nextReleaseHeading' heading not found in CHANGELOG.md, check it contains changes for this release!"
101+
fi
102+
else
103+
# In CHANGELOG.md, if the first secondary heading is not "## Next release", add it
104+
firstHeading=$(grep --max-count=1 "^## " "$changelogPath" || true)
105+
if [[ "$firstHeading" != "$nextReleaseHeading" ]]; then
106+
echo "Adding '$nextReleaseHeading' to CHANGELOG.md"
107+
sed --in-place "0,/^## /{s/^## /$nextReleaseHeading\n\n## /}" "$changelogPath"
108+
fi
109+
fi
110+
111+
# After confirmation commit any changes and for a release create a tag
112+
# Example for a release:
113+
# git commit --all --message="Prepare release 5.4.0"
114+
# git tag V5.4.0
115+
# For a regular run:
116+
# git commit --all --message="Publishing: increase version 5.4.0 -> 5.4.1"
117+
if $releaseFlag; then
118+
commitMessage="Prepare release $versionNew"
119+
else
120+
commitMessage="Publishing: increase version $versionCurrent -> $versionNew"
121+
fi
122+
tagRelease="V$versionNew"
123+
124+
echo ""
125+
echo "About to run git commands:"
126+
echo " git commit --all --message=\"$commitMessage\""
127+
if $releaseFlag; then
128+
echo " git tag $tagRelease"
129+
fi
130+
131+
read -r -p "Reviewed changes? Proceed? [y/N] " confirm
132+
if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then
133+
echo "Aborted."
134+
exit 1
135+
fi
136+
137+
git commit --all --message="$commitMessage"
138+
if $releaseFlag; then
139+
git tag "$tagRelease"
140+
fi
141+
142+
# Print suggested git commands to push the changes
143+
# Note: add `--push-option=ci.skip` to avoid running CI
144+
# Examples:
145+
# git push origin publish --push-option=ci.skip
146+
# git push origin V5.4.0 --push-option=ci.skip
147+
148+
currentBranch=$(git rev-parse --abbrev-ref HEAD)
149+
echo ""
150+
echo "Suggested commands to push these changes:"
151+
echo " git push origin $currentBranch --push-option=ci.skip"
152+
if $releaseFlag; then
153+
echo " git push origin $tagRelease --push-option=ci.skip"
154+
fi

0 commit comments

Comments
 (0)