Last active
August 9, 2022 16:34
-
-
Save mvsantos/4a11a830f796d21583a66c16e274e755 to your computer and use it in GitHub Desktop.
Bump a git repo semver tag.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -o errexit | |
set -o nounset | |
set -o pipefail | |
__THIS_FILE__="$(basename "${BASH_SOURCE[0]}")" | |
SEMVER_REGEX="^[vV]?(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(\\-[0-9A-Za-z]+){0,1}$" | |
SEMVER_MAJOR=0 | |
SEMVER_MINOR=0 | |
SEMVER_PATCH=0 | |
SEMVER_SUFFIX="" | |
NEW_SUFFIX="" | |
LIGHTWEIGHT_TAG=1 | |
VERSION_BUMPED=0 | |
NEW_VERSION="" | |
PUSH_TAGS_TO_REPO="" | |
PREVIOUS_HIGHEST_VERSION="" | |
function print-usage () { | |
cat <<USAGE | |
Usage: bash ${__THIS_FILE__} [OPTIONS] | |
OPTIONS | |
--release Creates an annotated tag, instead of the default lightweight git tag. | |
For more information regarding annotated and lightweight tags see https://git-scm.com/book/en/v2/Git-Basics-Tagging | |
--major Bumps the 'major' part of the version string. May be used multiple times. | |
--minor Bumps the 'minor' part of the version string. May be used multiple times. | |
--patch Bumps the 'patch' part of the version string. May be used multiple times. | |
This is option is assumed by default if no other option is passed when the script runs. | |
--suffix <alphanum value> Sets the suffix of the version - e.g. rc1, beta | |
--push-to <repository> Name of the remote repository to which the newly created tag will be pushed to. e.g. --push-to remote-source-of-truth | |
USAGE | |
} | |
function exit-error () { | |
echo "$(date +'%Y-%m-%d %H:%M:%S') ERROR: ${1}" 1>&2; | |
exit 127 | |
} | |
function set-version-variable () { | |
NEW_VERSION="v${SEMVER_MAJOR}.${SEMVER_MINOR}.${SEMVER_PATCH}${NEW_SUFFIX}" | |
} | |
function extract-version () { | |
local VERSION=${1} | |
if [[ "${VERSION}" =~ ${SEMVER_REGEX} ]]; then | |
SEMVER_MAJOR=${BASH_REMATCH[1]} | |
SEMVER_MINOR=${BASH_REMATCH[2]} | |
SEMVER_PATCH=${BASH_REMATCH[3]} | |
SEMVER_SUFFIX=${BASH_REMATCH[4]} | |
else | |
exit-error "Invalid semver string passed to 'extract-version'" | |
fi | |
} | |
function bump-version () { | |
case "${1}" in | |
major) | |
SEMVER_MAJOR=$((SEMVER_MAJOR + 1)) | |
SEMVER_MINOR="0" | |
SEMVER_PATCH="0" | |
;; | |
minor) | |
SEMVER_MINOR=$((SEMVER_MINOR + 1)) | |
SEMVER_PATCH="0" | |
;; | |
patch) | |
SEMVER_PATCH=$((SEMVER_PATCH + 1)) | |
;; | |
suffix) | |
if [[ "${2:-}" =~ ^[0-9A-Za-z]+$ ]]; then | |
NEW_SUFFIX="-${2}" | |
else | |
exit-error "Invalid suffix string." | |
fi | |
;; | |
*) | |
exit-error "Unknown option passed to 'bump-version'" | |
;; | |
esac | |
VERSION_BUMPED=1 | |
} | |
function find-last-tag-in-current-repo () { | |
PREVIOUS_HIGHEST_VERSION=$(git tag -l --sort=-version:refname "v*" | head -n1) | |
if [[ "x" != "x${PREVIOUS_HIGHEST_VERSION}" ]]; then | |
echo "This repo's current highest version is ${PREVIOUS_HIGHEST_VERSION}" | |
echo "This branch's highest version is $(git describe --tags --always --first-parent)" | |
fi | |
} | |
function add-new-tag-to-repo () { | |
set-version-variable; | |
if [[ $(git tag -l "${NEW_VERSION}") ]]; then | |
exit-error "The tag ${NEW_VERSION} already exist." | |
else | |
if [[ 1 -eq ${LIGHTWEIGHT_TAG} ]]; then | |
echo "Creating lightweight tag ${NEW_VERSION}" | |
git tag "${NEW_VERSION}" | |
else | |
echo "Creating annotated tag ${NEW_VERSION}" | |
git tag -a "${NEW_VERSION}" -m "Release version ${NEW_VERSION}" | |
fi | |
fi | |
} | |
# | |
# *** MAIN *** | |
# | |
if [[ $# -eq 0 ]]; then | |
print-usage | |
exit 0 | |
fi | |
while [[ $# -gt 0 ]]; do | |
find-last-tag-in-current-repo | |
extract-version ${PREVIOUS_HIGHEST_VERSION} | |
case ${1} in | |
--major|--minor|--patch ) | |
bump-version ${1//-/} | |
shift | |
;; | |
--suffix ) | |
bump-version suffix ${2} | |
shift | |
shift | |
;; | |
--release ) | |
LIGHTWEIGHT_TAG=0 | |
shift | |
;; | |
--push-to ) | |
PUSH_TAGS_TO_REPO=${2} | |
shift | |
shift | |
;; | |
-h|--help ) | |
print-usage | |
exit 0 | |
;; | |
* ) | |
echo "Error: Unknown option \"${1}\"" | |
exit 127 | |
esac | |
done | |
if [[ 1 -eq ${VERSION_BUMPED} ]]; then | |
[[ -f ./.VERSION ]] && rm -f ./.VERSION | |
add-new-tag-to-repo | |
if [[ "x" != "x${PUSH_TAGS_TO_REPO}" ]]; then | |
echo "# git push --tags \"${PUSH_TAGS_TO_REPO}\" HEAD" | |
git push --tags "${PUSH_TAGS_TO_REPO}" "refs/tags/${NEW_VERSION}" | |
fi | |
echo ${NEW_VERSION} > ./.VERSION | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment