How do you tag your release versions in git?
Now I have each release identified by build number, but they increment even if there are no changes in the repo. My idea is to have it generated automatically on successful deployment on staging server. E.g.
- run Hudson build
- when successful, add new tag, i.e. 1.0-1
- on next successful build add next tag, 1.0-2
- version tag is displayed then in site footer
This would require:
- Hudson to manage next version numbers
- or script to store last tag in some file
- or parse git tags to determine last
Any tips?
What you are talking about is more akin to a technical revision number like the one a git describe
would generate.
That is different from a true application version, which you should still managed independently from Hudson since it depends on a versioning policy.
I wrote this to help with updating tags incrementally e.g. 1.0.1 to 1.0.2 etc
#!/bin/bash
#get highest tag number
VERSION=`git describe --abbrev=0 --tags`
#replace . with space so can split into an array
VERSION_BITS=(${VERSION//./ })
#get number parts and increase last one by 1
VNUM1=${VERSION_BITS[0]}
VNUM2=${VERSION_BITS[1]}
VNUM3=${VERSION_BITS[2]}
VNUM3=$((VNUM3+1))
#create new tag
NEW_TAG="$VNUM1.$VNUM2.$VNUM3"
echo "Updating $VERSION to $NEW_TAG"
#get current hash and see if it already has a tag
GIT_COMMIT=`git rev-parse HEAD`
NEEDS_TAG=`git describe --contains $GIT_COMMIT`
#only tag if no tag already (would be better if the git describe command above could have a silent option)
if [ -z "$NEEDS_TAG" ]; then
echo "Tagged with $NEW_TAG (Ignoring fatal:cannot describe - this means commit is untagged) "
git tag $NEW_TAG
git push --tags
else
echo "Already a tag on this commit"
fi
Hudson automatically tags the build, if you use the git plugin and let Hudson extract the code. I'm not sure if this gets pushed automatically; in our set up we do extra tagging and include a 'git push --tags' in our build script, so we definitely see the Hudson tags in our central repository.
Really good solution timhc22
The only thing is that it takes the last tag (whatever the branch)
If you work on a project with multiple branches you could have an issue.
I proposed just an improvement with your base.
#!/bin/sh
# retrieve branch name
BRANCH_NAME=$(git branch | sed -n '/\* /s///p')
# remove prefix release
REGEXP_RELEASE="release\/"
VERSION_BRANCH=$(echo "$BRANCH_NAME" | sed "s/$REGEXP_RELEASE//")
echo "Current version branch is $VERSION_BRANCH"
# retrieve the last commit on the branch
VERSION=$(git describe --tags --match=$VERSION_BRANCH* --abbrev=0)
# split into array
VERSION_BITS=(${VERSION//./ })
#get number parts and increase last one by 1
VNUM1=${VERSION_BITS[0]}
VNUM2=${VERSION_BITS[1]}
VNUM3=${VERSION_BITS[2]}
VNUM3=$((VNUM3+1))
#create new tag
NEW_TAG="$VNUM1.$VNUM2.$VNUM3"
echo "Updating $VERSION to $NEW_TAG"
#get current hash and see if it already has a tag
GIT_COMMIT=`git rev-parse HEAD`
NEEDS_TAG=`git describe --contains $GIT_COMMIT`
#only tag if no tag already (would be better if the git describe command above could have a silent option)
if [ -z "$NEEDS_TAG" ]; then
echo "Tagged with $NEW_TAG (Ignoring fatal:cannot describe - this means commit is untagged) "
git tag $NEW_TAG
git push --tags
else
echo "Already a tag on this commit"
fi
This works for example if you have:
- a master branch: will create master-X.Y.Z
- a release/X.Y: will create X.Y.Z
In any case thanks a lot it helped me a lot.
In case if you will need Posix version, almost the same as above answer
#!/bin/sh
#Get the highest tag number
VERSION=`git describe --abbrev=0 --tags`
VERSION=${VERSION:-'0.0.0'}
#Get number parts
MAJOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
MINOR="${VERSION%%.*}"; VERSION="${VERSION#*.}"
PATCH="${VERSION%%.*}"; VERSION="${VERSION#*.}"
#Increase version
PATCH=$((PATCH+1))
#Get current hash and see if it already has a tag
GIT_COMMIT=`git rev-parse HEAD`
NEEDS_TAG=`git describe --contains $GIT_COMMIT`
#Create new tag
NEW_TAG="$MAJOR.$MINOR.$PATCH"
echo "Updating to $NEW_TAG"
#Only tag if no tag already (would be better if the git describe command above could have a silent option)
if [ -z "$NEEDS_TAG" ]; then
echo "Tagged with $NEW_TAG (Ignoring fatal:cannot describe - this means commit is untagged) "
git tag $NEW_TAG
else
echo "Already a tag on this commit"
fi
I am using as below. It is working perfectly with branches. Below snippets inspired from above comments and the gitversion / semver.org.
#!/bin/sh
# This script will be executed after commit in placed in .git/hooks/post-commit
# Semantic Versioning 2.0.0 guideline
#
# Given a version number MAJOR.MINOR.PATCH, increment the:
# MAJOR version when you make incompatible API changes,
# MINOR version when you add functionality in a backwards-compatible manner, and
# PATCH version when you make backwards-compatible bug fixes.
echo "Starting the taging process based on commit message +semver: xxxxx"
#get highest tags across all branches, not just the current branch
VERSION=`git describe --tags $(git rev-list --tags --max-count=1)`
# split into array
VERSION_BITS=(${VERSION//./ })
echo "Latest version tag: $VERSION"
#get number parts and increase last one by 1
VNUM1=${VERSION_BITS[0]}
VNUM2=${VERSION_BITS[1]}
VNUM3=${VERSION_BITS[2]}
# VNUM3=$((VNUM3+1))
# Taken from gitversion
# major-version-bump-message: '\+semver:\s?(breaking|major)'
# minor-version-bump-message: '\+semver:\s?(feature|minor)'
# patch-version-bump-message: '\+semver:\s?(fix|patch)'
# get last commit message and extract the count for "semver: (major|minor|patch)"
COUNT_OF_COMMIT_MSG_HAVE_SEMVER_MAJOR=`git log -1 --pretty=%B | egrep -c '\+semver:\s?(breaking|major)'`
COUNT_OF_COMMIT_MSG_HAVE_SEMVER_MINOR=`git log -1 --pretty=%B | egrep -c '\+semver:\s?(feature|minor)'`
COUNT_OF_COMMIT_MSG_HAVE_SEMVER_PATCH=`git log -1 --pretty=%B | egrep -c '\+semver:\s?(fix|patch)'`
if [ $COUNT_OF_COMMIT_MSG_HAVE_SEMVER_MAJOR -gt 0 ]; then
VNUM1=$((VNUM1+1))
fi
if [ $COUNT_OF_COMMIT_MSG_HAVE_SEMVER_MINOR -gt 0 ]; then
VNUM2=$((VNUM2+1))
fi
if [ $COUNT_OF_COMMIT_MSG_HAVE_SEMVER_PATCH -gt 0 ]; then
VNUM3=$((VNUM3+1))
fi
# count all commits for a branch
GIT_COMMIT_COUNT=`git rev-list --count HEAD`
echo "Commit count: $GIT_COMMIT_COUNT"
export BUILD_NUMBER=$GIT_COMMIT_COUNT
#create new tag
NEW_TAG="$VNUM1.$VNUM2.$VNUM3"
echo "Updating $VERSION to $NEW_TAG"
#only tag if commit message have version-bump-message as mentioned above
if [ $COUNT_OF_COMMIT_MSG_HAVE_SEMVER_MAJOR -gt 0 ] || [ $COUNT_OF_COMMIT_MSG_HAVE_SEMVER_MINOR -gt 0 ] || [ $COUNT_OF_COMMIT_MSG_HAVE_SEMVER_PATCH -gt 0 ]; then
echo "Tagged with $NEW_TAG (Ignoring fatal:cannot describe - this means commit is untagged) "
git tag "$NEW_TAG"
else
echo "Already a tag on this commit"
fi