22set -euo pipefail
33
44# Script to bump and tag semantic versions
5- # Usage: ./scripts/tag-version.sh [major|minor|patch|rc|release] [--dry-run]
5+ # Usage: ./scripts/tag-version.sh [major|minor|patch|rc|release] [--dry-run] [--push]
66
77SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
88PROJECT_ROOT=" $( cd " ${SCRIPT_DIR} /.." && pwd) "
@@ -15,6 +15,18 @@ if [[ "${@}" =~ --dry-run ]]; then
1515 DRY_RUN=true
1616fi
1717
18+ # Check for push flag (defaults to false)
19+ PUSH=false
20+ if [[ " ${@ } " =~ --push ]]; then
21+ PUSH=true
22+ fi
23+
24+ # Check for yes/auto-confirm flag (defaults to false)
25+ YES=false
26+ if [[ " ${@ } " =~ -y ]] || [[ " ${@ } " =~ --yes ]]; then
27+ YES=true
28+ fi
29+
1830# Get current version from conanfile.py
1931get_current_version () {
2032 if [ -f " ${CONANFILE} " ]; then
@@ -154,9 +166,17 @@ create_tag() {
154166 echo " Warning: Tag ${tag} already exists"
155167 fi
156168
157- # Check for uncommitted changes
158- if ! git diff-index --quiet HEAD --; then
159- echo " Warning: Uncommitted changes detected"
169+ # Check for uncommitted changes (excluding version files)
170+ local git_root=$( git rev-parse --show-toplevel)
171+ local conanfile_rel=" ${CONANFILE# ${git_root} / } "
172+ local cmakelists_rel=" ${CMAKELISTS# ${git_root} / } "
173+ local all_changed=$( git diff --name-only HEAD 2> /dev/null || true)
174+ local all_staged=$( git diff --name-only --cached 2> /dev/null || true)
175+ local other_changes=$( echo " $all_changed " | grep -v -E " ^${conanfile_rel} $|^${cmakelists_rel} $" | grep -v ' ^$' || true)
176+ local other_staged=$( echo " $all_staged " | grep -v -E " ^${conanfile_rel} $|^${cmakelists_rel} $" | grep -v ' ^$' || true)
177+
178+ if [ -n " $other_changes " ] || [ -n " $other_staged " ]; then
179+ echo " Warning: Uncommitted changes detected (excluding version files)"
160180 git status --short
161181 fi
162182 return
@@ -165,21 +185,46 @@ create_tag() {
165185 # Check if tag already exists
166186 if git rev-parse " ${tag} " > /dev/null 2>&1 ; then
167187 echo " Warning: Tag ${tag} already exists" >&2
168- read -p " Continue anyway? (y/N) " -n 1 -r
169- echo
170- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
171- exit 1
188+ if [ " $YES " != true ]; then
189+ read -p " Continue anyway? (y/N) " -n 1 -r
190+ echo
191+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
192+ exit 1
193+ fi
194+ else
195+ echo " Continuing anyway (--yes flag set)" >&2
172196 fi
173197 fi
174198
175- # Check for uncommitted changes
176- if ! git diff-index --quiet HEAD --; then
177- echo " Warning: You have uncommitted changes" >&2
199+ # Check for uncommitted changes (excluding version files that will be committed)
200+ # Get paths relative to git root
201+ local git_root=$( git rev-parse --show-toplevel)
202+ local conanfile_rel=" ${CONANFILE# ${git_root} / } "
203+ local cmakelists_rel=" ${CMAKELISTS# ${git_root} / } "
204+
205+ # Get all changed files
206+ local all_changed=$( git diff --name-only HEAD 2> /dev/null || true)
207+ local all_staged=$( git diff --name-only --cached 2> /dev/null || true)
208+
209+ # Filter out version files
210+ local other_changes=$( echo " $all_changed " | grep -v -E " ^${conanfile_rel} $|^${cmakelists_rel} $" || true)
211+ local other_staged=$( echo " $all_staged " | grep -v -E " ^${conanfile_rel} $|^${cmakelists_rel} $" || true)
212+
213+ # Remove empty lines
214+ other_changes=$( echo " $other_changes " | grep -v ' ^$' || true)
215+ other_staged=$( echo " $other_staged " | grep -v ' ^$' || true)
216+
217+ if [ -n " $other_changes " ] || [ -n " $other_staged " ]; then
218+ echo " Warning: You have uncommitted changes (excluding version files)" >&2
178219 git status --short
179- read -p " Continue with tag anyway? (y/N) " -n 1 -r
180- echo
181- if [[ ! $REPLY =~ ^[Yy]$ ]]; then
182- exit 1
220+ if [ " $YES " != true ]; then
221+ read -p " Continue with tag anyway? (y/N) " -n 1 -r
222+ echo
223+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
224+ exit 1
225+ fi
226+ else
227+ echo " Continuing anyway (--yes flag set)" >&2
183228 fi
184229 fi
185230
@@ -188,6 +233,52 @@ create_tag() {
188233 echo " Created git tag: ${tag} "
189234}
190235
236+ # Commit version changes
237+ commit_version_changes () {
238+ local new_version=" $1 "
239+ local commit_message=" Bump version to ${new_version} "
240+
241+ if [ " $DRY_RUN " = true ]; then
242+ echo " [DRY RUN] Would commit version changes:"
243+ echo " Message: \" ${commit_message} \" "
244+ git status --short
245+ return 0
246+ fi
247+
248+ # Stage the version files
249+ if [ -f " ${CONANFILE} " ]; then
250+ git add " ${CONANFILE} "
251+ fi
252+ if [ -f " ${CMAKELISTS} " ]; then
253+ git add " ${CMAKELISTS} "
254+ fi
255+
256+ # Check if there are staged changes
257+ if ! git diff --staged --quiet; then
258+ git commit -m " ${commit_message} "
259+ echo " ✓ Committed version changes"
260+ return 0
261+ else
262+ echo " No changes to commit"
263+ return 0
264+ fi
265+ }
266+
267+ # Push git tag
268+ push_tag () {
269+ local version=" $1 "
270+ local tag=" v${version} "
271+
272+ if [ " $DRY_RUN " = true ]; then
273+ echo " [DRY RUN] Would push git tag: ${tag} "
274+ return
275+ fi
276+
277+ # Push the tag
278+ git push origin " ${tag} "
279+ echo " Pushed git tag: ${tag} "
280+ }
281+
191282# Main execution
192283main () {
193284 local bump_type=" "
@@ -202,6 +293,12 @@ main() {
202293 --dry-run)
203294 DRY_RUN=true
204295 ;;
296+ --push)
297+ PUSH=true
298+ ;;
299+ -y|--yes)
300+ YES=true
301+ ;;
205302 major|minor|patch)
206303 bump_type=" $arg "
207304 # Check if next argument is "rc"
@@ -231,7 +328,7 @@ main() {
231328 done
232329
233330 if [ -z " $bump_type " ]; then
234- echo " Usage: $0 [major|minor|patch|rc|release] [rc] [--dry-run]" >&2
331+ echo " Usage: $0 [major|minor|patch|rc|release] [rc] [--dry-run] [--push] [-y|--yes] " >&2
235332 echo " " >&2
236333 echo " Examples:" >&2
237334 echo " $0 major # 1.2.3 -> 2.0.0" >&2
@@ -245,6 +342,8 @@ main() {
245342 echo " " >&2
246343 echo " Options:" >&2
247344 echo " --dry-run Show what would change without making changes" >&2
345+ echo " --push Push the git tag to remote after creating it" >&2
346+ echo " -y, --yes Auto-confirm all prompts (skip interactive questions)" >&2
248347 exit 1
249348 fi
250349
@@ -290,27 +389,59 @@ main() {
290389 # Update all version files
291390 update_version_files " $NEW_VERSION "
292391
392+ # Commit version changes
393+ commit_version_changes " $NEW_VERSION "
394+
293395 if [ " $DRY_RUN " = true ]; then
294396 echo " "
295397 create_tag " $NEW_VERSION "
398+ if [ " $PUSH " = true ]; then
399+ push_tag " $NEW_VERSION "
400+ fi
296401 echo " "
297402 echo " === DRY RUN COMPLETE ==="
298403 echo " Run without --dry-run to apply changes."
299404 exit 0
300405 fi
301406
302407 # Create git tag
303- read -p " Create git tag v${NEW_VERSION} ? (y/N) " -n 1 -r
304- echo
305- if [[ $REPLY =~ ^[Yy]$ ]]; then
408+ if [ " $YES " = true ]; then
409+ # Auto-confirm, skip prompt
306410 create_tag " $NEW_VERSION "
307- echo " "
308- echo " ✓ Version bumped to ${NEW_VERSION} "
309- echo " ✓ Git tag v${NEW_VERSION} created"
310- echo " "
311- echo " To push the tag: git push origin v${NEW_VERSION} "
411+
412+ # Push tag if --push flag was set
413+ if [ " $PUSH " = true ]; then
414+ echo " "
415+ push_tag " $NEW_VERSION "
416+ echo " "
417+ echo " ✓ Version bumped to ${NEW_VERSION} "
418+ echo " ✓ Git tag v${NEW_VERSION} created and pushed"
419+ else
420+ echo " "
421+ echo " ✓ Version bumped to ${NEW_VERSION} "
422+ echo " ✓ Git tag v${NEW_VERSION} created"
423+ fi
312424 else
313- echo " Tag creation cancelled. Version updated in files only."
425+ read -p " Create git tag v${NEW_VERSION} ? (y/N) " -n 1 -r
426+ echo
427+ if [[ $REPLY =~ ^[Yy]$ ]]; then
428+ create_tag " $NEW_VERSION "
429+
430+ # Push tag if --push flag was set
431+ if [ " $PUSH " = true ]; then
432+ echo " "
433+ push_tag " $NEW_VERSION "
434+ echo " "
435+ echo " ✓ Version bumped to ${NEW_VERSION} "
436+ echo " ✓ Git tag v${NEW_VERSION} created and pushed"
437+ else
438+ echo " "
439+ echo " ✓ Version bumped to ${NEW_VERSION} "
440+ echo " ✓ Git tag v${NEW_VERSION} created"
441+ fi
442+ else
443+ echo " Tag creation cancelled. Version updated in files only."
444+ fi
314445 fi
315446}
316447
0 commit comments