Skip to content

Instantly share code, notes, and snippets.

@almostearthling
Last active February 1, 2022 23:57
Show Gist options
  • Save almostearthling/7a26d24e5975a6dc5086 to your computer and use it in GitHub Desktop.
Save almostearthling/7a26d24e5975a6dc5086 to your computer and use it in GitHub Desktop.
Script to automatically create Git tags on release change
#!/bin/bash
# Automatically create git tags when the version ID in a certain file changes
# (c) 2015-2016 Francesco Garosi
#
# This script helps to automate the creation of git tags when the project
# version info is discovered to have changed: this is normally done extracting
# such version info from a source file. Version information consists of:
#
# * RELEASE_ID: a string containing version number
# * RELEASE_MSG: a short message containing release highlights
#
# The git tag is constructed by prepending 'v' to the string in RELEASE_ID.
# All characters in RELEASE_ID that are not numbers, letters, dots, dashes and
# underscores will automatically converted to dashes. This also affects tilde.
#
# This script has some prerequisites:
#
# * a variable called PROJECT_HOME must exist, pointing to the project home:
# if this is not set, it is automatically set to the current working dir;
# $PROJECT_HOME is expected to be a git repository
# * there must be a $PROJECT_HOME/.temp directory
# * there must be a $PROJECT_HOME/.temp/autotag file that defines the two
# variables named above: it should either be manually edited or contain
# the code that extracts version information from the source
#
# If these prerequisites are not satisfied, the script exits with an error
# and without performing any actions on the repository. Otherwise it commits
# the most recent changes and automatically creates a new tag in the git repo.
#
# Obviously this design make this script useful to be automated by When!
# Some useful reporting functions first
echo_prompt () {
echo "[`date +%H:%M:%S`]" "$@"
}
echo_err () {
echo "$@" 1>&2
}
# read command line flags
while [ -n "$1" ] ; do
case $1 in
-f)
SHOW_BADGE=1
;;
-p)
MSG_PREFIX="AutoTag: "
;;
esac
shift
done
# find name of script
AUTOTAG=$(basename $0)
# 1. Check that preconditions are met
if [ -z "$PROJECT_HOME" ] ; then
PROJECT_HOME=$(pwd)
if [ ! -d "$PROJECT_HOME/.git" ] ; then
echo_err "$AUTOTAG: the PROJECT_HOME directory is not a git repository"
exit 2
fi
fi
if [ ! -d "$PROJECT_HOME/.temp" ] ; then
echo_err "$AUTOTAG: please create $PROJECT_HOME/.temp directory"
exit 2
fi
if [ ! -f "$PROJECT_HOME/.temp/autotag" ] ; then
echo_err "$AUTOTAG: please create $PROJECT_HOME/.temp/autotag script"
exit 2
fi
# 2. get version information
echo_prompt "$AUTOTAG: running for $PROJECT_HOME"
source $PROJECT_HOME/.temp/autotag
if [ -z "$RELEASE_ID" -o -z "$RELEASE_MSG" ] ; then
echo_err "cannot retrieve version information"
exit 2
fi
echo "found release ID: $RELEASE_ID"
echo "found release MSG: $RELEASE_MSG"
# 3. perform git poerations
RELEASE_ID_CORR="$(echo $RELEASE_ID | sed 's/[^a-zA-Z0-9._-]/-/g')"
RELEASE_TAG="v$RELEASE_ID_CORR"
LAST_TAG=$(git -C $PROJECT_HOME tag -l | sort -V | tail -1)
RELEASE_TAG_PRESENT=$(git -C $PROJECT_HOME tag -l | grep $RELEASE_TAG)
if [ -z "$RELEASE_TAG_PRESENT" ] ; then
echo "release changed since last tag: $LAST_TAG < $RELEASE_ID"
if [ -n "$MSG_PREFIX" ] ; then
RELEASE_MSG="$MSG_PREFIX$RELEASE_MSG"
fi
git -C $PROJECT_HOME commit -am "$RELEASE_MSG"
git -C $PROJECT_HOME tag -m "$RELEASE_MSG" "$RELEASE_TAG" HEAD
if [ -n "$DISPLAY" -a -n "$SHOW_BADGE" ] ; then
notify-send -i info "Autotag" "New tag created: $RELEASE_TAG ($RELEASE_ID), '$RELEASE_MSG'"
fi
else
echo "no tag change since last tag: $LAST_TAG ≥ $RELEASE_ID"
fi
echo_prompt "$AUTOTAG: finished"
# end.
@almostearthling
Copy link
Author

This is the .temp/autotag script for the When repository: it ensures that the tag is in sync with the release number in the main source file. Note that Python 2.x has to be used because there are no parentheses in the print statement.

main_script="share/when-command/when-command.py"
RELEASE_ID=$(echo "`grep ^APPLET_VERSION $main_script`; print APPLET_VERSION" | python)
RELEASE_MSG=$(echo "`grep ^APPLET_TAGDESC $main_script`; print APPLET_TAGDESC" | python)

Of course it's useful using When, as a task (invoke autotag.sh -f from within the project directory) with a triggering condition that monitors file changes in the project directory.

Considering these lines of code in when-command.py:

APPLET_VERSION = '0.9.2~beta.2'
APPLET_TAGDESC = 'Automatic tagging based on version info extraction'

this is what happens when I simply modify one or more files without changing those lines:

autotag_noaction

and the following is the event output when they are modified and when-command.py is saved:

autotag_changed

In fact I could even use the APPLET_VERSION variable alone to decide whether or not to commit changes to the repository.

@almostearthling
Copy link
Author

Fixed on 2016/03/02 to actually find last tag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment