Skip to content

Instantly share code, notes, and snippets.

@damouse
Last active July 22, 2020 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save damouse/f764f2c7046ef1da42c252eea85c8a39 to your computer and use it in GitHub Desktop.
Save damouse/f764f2c7046ef1da42c252eea85c8a39 to your computer and use it in GitHub Desktop.
Script to automatically bump semver version.
#!/bin/bash
# Bumps the semantic version of the git-project.
# If no semantic version tags exist in the project, the version starts out at v0.0.0
# and is incremented by one for the field indicated by the bump command argument.
# Example Usage:
# Show the current tag
# bump -l
# Major bump, like 1.2.3 -> 2.0.0
# bump major This is a new Update for You
# Minor bump, like 1.2.3 -> 1.3.0
# bump minor This is a new Update for You
# Patch bump, like 1.2.3 -> 1.2.4
# bump patch This is a new Update for You
# Install directly with
# sudo wget https://gist.githubusercontent.com/damouse/f764f2c7046ef1da42c252eea85c8a39/raw/bump -O /usr/local/bin/bump && sudo chmod +x /usr/local/bin/bump
find_latest_semver() {
pattern="^$PREFIX([0-9]+\.[0-9]+\.[0-9]+)\$"
versions=$(for tag in $(git tag); do
[[ "$tag" =~ $pattern ]] && echo "${BASH_REMATCH[1]}"
done)
if [ -z "$versions" ];then
echo 0.0.0
else
echo "$versions" | tr '.' ' ' | sort -nr -k 1 -k 2 -k 3 | tr ' ' '.' | head -1
fi
}
# Call with (major | minor | patch) <version>
update_version() {
case $1 in
"major" ) major=true;;
"minor" ) minor=true;;
"patch" ) patch=true;;
esac
shift $(($OPTIND - 1))
version=$2
a=( ${version//./ } )
if [ ! -z $major ]; then
((a[0]++))
a[1]=0
a[2]=0
fi
if [ ! -z $minor ]; then
((a[1]++))
a[2]=0
fi
if [ ! -z $patch ]; then
((a[2]++))
fi
echo "${a[0]}.${a[1]}.${a[2]}"
}
bump() {
latest_ver="${PREFIX}$(find_latest_semver)"
latest_commit=$(git rev-parse "${latest_ver}" 2>/dev/null )
head_commit=$(git rev-parse HEAD)
next_ver=$(update_version $1 $latest_ver)
shift 1
message=$@
if [ "$latest_commit" = "$head_commit" ]; then
echo "refusing to tag; $latest_ver already tagged for HEAD ($head_commit)"
else
echo "bumping $latest_ver to $next_ver with message '$message'"
git tag -a "$next_ver" -m "$message"
git push --tags
fi
}
usage() {
echo "Usage: bump [-p prefix] <major|minor|patch> <message> | -l"
echo "Bumps the semantic version field by one for a git-project."
echo
echo "Options:"
echo " -l list the latest tagged version instead of bumping."
echo " -p prefix [to be] used for the semver tags."
echo ""
echo "Example:"
echo " bump patch 'Fixed many bugs'"
exit 1
}
while getopts :p:l opt; do
case $opt in
p) PREFIX="$OPTARG";;
l) LIST=1;;
\?) usage;;
:) echo "option -$OPTARG requires an argument"; exit 1;;
esac
done
shift $((OPTIND-1))
if [ ! -z "$LIST" ];then
find_latest_semver
exit 0
fi
if [ "$#" -lt 2 ]; then usage; exit 0; fi
bump_type=$1
shift 1
case $bump_type in
major) bump major "$@";;
minor) bump minor "$@";;
patch) bump patch "$@";;
*) usage
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment