Skip to content

Instantly share code, notes, and snippets.

@jonaseberle
Last active January 31, 2024 12:53
Show Gist options
  • Save jonaseberle/e796f160f014b2a915b00e10c2dd6ac9 to your computer and use it in GitHub Desktop.
Save jonaseberle/e796f160f014b2a915b00e10c2dd6ac9 to your computer and use it in GitHub Desktop.
bin/gitTagRelease: Bash script that helps tagging commits like "live-1.2.3"; asks to push the tag and run ‹ddev surf deploy ...›.
#!/bin/bash
## Description: Create and push new git release tag. Deploy via ‹ddev surf deploy ...›.
## Requirements: You use release tags of the form <releaseChannel>-<major>.<minor>.<bugfix>
# saner programming env: these switches turn some bugs into errors
set -o errexit -o pipefail -o noclobber -o nounset
usage() {
echo "Usage:"
echo " $0 --help"
echo " $0 [‹prefix›] [‹raise›]"
echo " Arguments:"
echo " ‹prefix›: the tag prefix (aka release/stability channel), for example 'live'"
# Note: ‹prefix› cannot have the value of any of the ‹raise› constants
echo " default: prefix from last used release tag of the form ‹prefix›-x.y.z"
echo " ‹raise›: bugfix|fix: raise the last digit"
echo " feature|feat|minor: raise the middle digit"
echo " breaking|major: raise the left digit"
echo " default: bugfix"
echo
echo "You will be asked for confirmation before tags are created and pushed."
echo
echo "Examples:"
echo " $0"
echo " -> If the last tag on the current branch was live-1.2.3, this would create a new tag live-1.2.4"
echo " $0 live feature (or $0 feature)"
echo " -> If the last tag was live-1.2.3, this would create a new tag live-1.3.0"
echo " $0 staging major"
echo " -> If the last tag was staging-1.2.3, this would create a new tag staging-2.0.0"
echo
echo "Any action (tag, push tag, run ‹ddev suf deploy›) will ask for confirmation before being executed."
}
if [[ "${1:-}" =~ ^(--help|-h)$ ]]; then
usage
exit 1
fi
prefix="${1:-}"
raise="${2:-bugfix}"
if grep -Eq '^(bugfix|fix|feature|feat|breaking|minor|major)$' <<<"$prefix"; then
# only ‹raise› was given
raise="$prefix"
prefix=
fi
if ! grep -Eq '^(bugfix|fix|feature|feat|breaking|minor|major)$' <<<"$raise"; then
echo "Second argument must be one of ‹bugfix|fix|feature|feat|breaking|minor|major›" >&2
usage
exit 1
fi
if [ -z "$prefix" ]; then
prefix="$(git describe --tags --abbrev=0 | sed -E 's/-[0-9]+\.[0-9]+\.[0-9]+$//')"
if [ -z "$prefix" ]; then
echo "Did not find a previous tag of the form ‹prefix›-x.y.z. Please specify." >&2
exit 1
else
printf "Assuming prefix ‹%s› because the most recent tag in this branch used it.\n" "$prefix"
fi
fi
lastTag=$(
git ls-remote --sort=version:refname . refs/tags/"$prefix*" |
tail --lines=1 |
sed -E 's#^.*refs/tags/([^^]*).*$#\1#'
)
if [ -z "$lastTag" ]; then
printf "WARNING: no release tag matching ‹%s*› found yet.\n" "$prefix" >&2
lastTag="$prefix-0.0.0"
raise=${2:-feature}
else
printf "Most current tag with prefix ‹%s›: %s\n" "$prefix" "$lastTag"
fi
delimiter=$(echo "$lastTag" | sed -E 's#^'"$prefix"'([-_]?)([0-9]+\.[0-9]+\.[0-9]+)$#\1#')
if ! grep -Eq '^[-_]?$' <<<"$delimiter"; then
printf "ERROR: Could not derive a version number from tag ‹%s› for prefix ‹%s›\n" "$lastTag" "$prefix" >&2
exit 1
fi
versionPart=$(sed -E 's#^'"$prefix"'([-_]?)([0-9]+\.[0-9]+\.[0-9]+)$#\2#' <<<"$lastTag")
previousVersion="$versionPart"
versionMajor=$(sed -E 's#^([0-9]+)\.([0-9]+)\.([0-9]+)$#\1#' <<<"$versionPart")
versionMinor=$(sed -E 's#^([0-9]+)\.([0-9]+)\.([0-9]+)$#\2#' <<<"$versionPart")
versionBugfix=$(sed -E 's#^([0-9]+)\.([0-9]+)\.([0-9]+)$#\3#' <<<"$versionPart")
case "$raise" in
bugfix | fix)
((++versionBugfix))
;;
feature | feat | minor)
((++versionMinor))
versionBugfix=0
;;
breaking | major)
((++versionMajor))
versionMinor=0
versionBugfix=0
;;
esac
tag="$prefix$delimiter$versionMajor.$versionMinor.$versionBugfix"
printf "Current/next release version: %s -> %s\n" "$previousVersion" "$versionMajor.$versionMinor.$versionBugfix"
printf "Suggestion:\n git tag %s\n" "$tag"
read -p "Shall I tag now? [yN]? " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
git tag "$tag"
remote="$(git branch --list "$(git branch --show-current)" "--format=%(upstream:remotename)")"
read -p "Shall I push now ($remote)? [yN]? " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
git push "$remote" "$tag"
fi
fi
read -p "Shall I ‹ddev surf deploy $prefix› now? [yN]? " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
# make sure ssh-agent has keys:
ddev exec 'ssh-add -l' &>/dev/null || ddev auth ssh
while ! ddev surf deploy "$prefix"; do
read -p "Shall I do that again? ‹ddev surf deploy $prefix› now? [yN]? " -n 1 -r
echo
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
break
fi
done
fi
# vim: tabstop=2 expandtab shiftwidth=2 softtabstop=2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment