December 08, 2012

Git project's version auto increment

If you have a project which is under Git control and you have some configuration file containing current project's version, then you may wish to automate the process of it's updating.

You need to setup a git hook to do this. In general, any executable file can be a hook, but commonly it's a bash-script. The only requirement is to set a proper name for your hook, because it's execution time depends on it: before commit, after commit and so on. I suppose that the best way to update project's version is to do an automated commit after your manual commit is successfully done. The reason is you may have another hooks which can run some tests or check something before commit. If they will fail, there will be no reason to update current version. This seems to be quite logical.

So, we decided to update project's version after only after successful commit. To do this we need to create a hook with "post-commit" name specified. As you know, project's root directory contains ".git" subdirectory. The onle thing you need to install post-commit hook is to place it to ".git/hooks" directory. It can already contain some hooks samples. So, hook's path will look like:

/path/to/my/repo/.git/hooks/post-commit

If your project has submodules and you want to specify the hook for some of them, then path will look like:

/path/to/my/repo/.git/modules/MySubModule/hooks/post-commit

Make sure you can execute your hook:

chmod +x post-commit

So, let's see an example hook:

#!/bin/sh

MESSAGE=$(git log -1 HEAD --pretty=format:%s)
PRO_PATH=`git rev-parse --show-toplevel`"/Commander/Commander.pro"

VER_TOCKEN="VERSION"
VER_STR=$(grep "^$VER_TOCKEN" $PRO_PATH | awk '{print $3}')

VER_MAJ=$(echo $VER_STR | awk -F. '{print $1}')
VER_MIN=$(echo $VER_STR | awk -F. '{print $2}')
VER_PAT=$(echo $VER_STR | awk -F. '{print $3}')

applyVersion()
{
  VER_STR=$VER_MAJ"."$VER_MIN"."$VER_PAT
  VER_LINE=$VER_TOCKEN" = "$VER_STR
  sed -i 's/^'"$VER_TOCKEN"'.*/'"$VER_LINE"'/' $PRO_PATH
  git add $PRO_PATH
  git commit -m "version update: "$VER_STR
}

onVMAJ()
{
  let VER_MAJ++
  VER_MIN=0
  VER_PAT=0
  applyVersion
}

onVMIN()
{
  let VER_MIN++
  VER_PAT=0
  applyVersion
}

onVPAT()
{
  let VER_PAT++
  applyVersion
}

case "$MESSAGE" in
  *vmaj++* ) onVMAJ;;
  *vmin++* ) onVMIN;;
  *vpat++* ) onVPAT;;
  * );;
esac

exit

You can find this script in Horus Commander's repository, which is a Horus System subproject. Horus Commander is a Qt project and you can find it's configuration file here.

  • "MESSAGE" contains your last commit's message.
  • "PRO_PATH" is an absolute path to "Commander.pro" file, where the version is specified as "VERSION = x.y.z". "x" is for major version (VER_MAJ), "y" is for minor version (VER_MIN) and "z" is for path version (VER_PAT). This is a Semantic Versioning model.
  • If MESSAGE contains "vmaj++" then major version increases. "vmin++" increases minor version and "vpat++" increases patch version.
  • Then new version is written to the configuration file and new commit is done.

Usage exapmles:

# Imagine that current version is "0.0.0"

# Increase version to "0.0.1"
git commit -m "some nasty bug was fixed. #vpat++"

# Increase version to "0.1.0"
git commit -m "some nice feature was provided. #vmin++"

# Increase version to "1.0.0"
git commit -m "new mega release came out. #vmaj++"

No comments:

Post a Comment