HotFix automation in Maven projects using TeamCity

This post will describe how to set up HotFix automation in Maven projects using Teamcity.

To make a HotFix there is usually a lot of manual work involved:

  1. Create a branch for the release you want to push HotFix to
  2. Fix bug in release
  3. Change bugfix version in release branch
  4. Roll out version bugfix tag

Items 1,3,4 can be automated.

Before we move on to the topic, I want to touch on an important and complex topic - versioning software. Briefly about Semver can be understood in this screenshot. HotFix automation in Maven projects using TeamCity

You can read more at the link: 1.

All settings described in this post are based on Semver и Trunk Based Development.

In Trunk-Based Development, you need to create your own branch for each release. All changes (hotfix) within this release are committed to this branch.

As part of this post, we will automate the following things:

  • CI assembly

  • Create a new release

  • Create a branch for a release

  • Change bugfix version

HotFix automation in Maven projects using TeamCity

Requirements:

Let's create the "Automation Maven Hotfix" project in Teamcity and create 4 tasks there.

  • CI Build (CI build)

  • Create branch for release

  • Maven increment bugfix (Change bugfix version))

  • Maven release (Creating a new release)

Project screenshot:

HotFix automation in Maven projects using TeamCity

General Settings

In all tasks, you must check the box "Clean build: Delete all files in the checkout directory before the build“Because when this checkbox was missing, I got errors.

We create a single VCS. VCS features circled in red.

HotFix automation in Maven projects using TeamCity

Typically, VCSs use the HTTPS scheme. IN branch specification: it is indicated to watch all brunches and all tags:

+:refs/heads/*
+:refs/tags/*

You need to create 4 Configuration Parameters.

  • BRANCH_FOR_INCREMENT
  • TAG_FROM_VERSION
  • TEAM_USER
  • TEAM_USER_EMAIL

The value field in BRANCH_FOR_INCREMENT and TAG_FROM_VERSION must be left empty.

HotFix automation in Maven projects using TeamCity

You need to upload/add a private key. All tasks except CI Build require a private key.

HotFix automation in Maven projects using TeamCity

In each task, except for CI Build, in the Build Features section, you need to connect a private key.

Example for Maven release

HotFix automation in Maven projects using TeamCity

CI Build**.

In a task CI Build just one step mvn clean test

HotFix automation in Maven projects using TeamCity

Maven release

In a task Maven release 2 steps. The first step is checking what the brunch is master. If brunch is not master, then the task falls.

BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" != "master" ]]; then
  echo 'Branch is not master';
  echo 'Aborting';
  exit 1;
fi

HotFix automation in Maven projects using TeamCity

The second step is standard mvn release:prepare with option --batch mode

HotFix automation in Maven projects using TeamCity

Create branch for release

To create a hotfix for a release, you need to create a branch. This is what a task does Create branch for release. She has 2 steps.

The first step checks that the brunch is not master, and the second checks that the version in the file pom.xml did not contain a word SNAPSHOT

BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" == "master" ]]; then
  echo 'Branch is master';
  echo 'Aborting';
  exit 1;
fi

echo "Get version package from pom.xml"
version=`python -c "import xml.etree.ElementTree as ET; print(ET.parse(open('pom.xml')).getroot().find('{http://maven.apache.org/POM/4.0.0}version').text)"`

echo "Check SNAPSHOT"
if [[ $version == "*SNAPSHOT*" ]]; then
    echo "******************* W A R N I N G *************************"
    echo "************ You are create branch for SNAPSHOTS ******************"
    echo "***********************************************************"
    exit 1
fi

HotFix automation in Maven projects using TeamCity

The second step changes the connection scheme in developerConnection from HTTPS to GIT.

# Здесь получаем developerConnection из файла pom.xml
developerConnection=$(xmllint -xpath "/*[local-name() = 'project' ]//*[local-name() = 'developerConnection']/text()" pom.xml | sed  's|scm:git:ssh://||')
echo developerConnection
echo $developerConnection
# Здесь меняем / на : в URL для git_remote_url
git_remote_url=$(echo $developerConnection| sed 's/gitlab.com//gitlab.com:/g')
echo git_remote_url
echo $git_remote_url

git remote set-url origin $git_remote_url

# Если вы не используете ввстроенную возможность Teamcity получения user и email из ~/.gitconfig, то можно указать их здесь
echo 'git config user.name %TEAM_USER%'
git config user.name %TEAM_USER%
echo 'git config user.email %TEAM_USER_EMAIL%'
git config user.email %TEAM_USER_EMAIL%

# Здесь получаем версию из файла pom.xml
echo "Get version package from pom.xml"
version=`python -c "import xml.etree.ElementTree as ET; print(ET.parse(open('pom.xml')).getroot().find('{http://maven.apache.org/POM/4.0.0}version').text)"`
echo $version

# Почему-то без fetch выдавало ошибку.
git fetch

if [ `git branch -a | egrep "${version}$"` ]
then
    echo "Branch exists"
    exit 1
fi

# Создаем бранч той версии, который был в файле pom.xml
echo "Create branch"
git checkout -b $version

# Чистый git всегда предлагает настроить политику отправки.
git config --global push.default simple

# Пушим в ветку совпадающую с версией в pom.xml
echo "Push release branch"
git push --set-upstream origin $version

HotFix automation in Maven projects using TeamCity

Maven increment bugfix

The task consists of 6 parts. It could have been refactored, but it still works.

The first step is to check that the brunch is not master. If brunch master the cart falls.

BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" == "master" ]]; then
  echo 'Branch is master';
  echo 'Aborting';
  exit 1;
fi

# Здесь получаем версию из файла pom.xml
echo "Get version package from pom.xml"
BRANCH=`python -c "import xml.etree.ElementTree as ET; print(ET.parse(open('pom.xml')).getroot().find('{http://maven.apache.org/POM/4.0.0}version').text)"`
# Приходится делать checkout на нужный бранч.
# Иначе git status показывает detached к нужному бранчу.
# Нужно чтобы git status показывал просто бранч
git checkout $BRANCH
# Экспортируем переменную bash в переменную Teamcity для дальнейшего использования.
echo "##teamcity[setParameter name='BRANCH_FOR_INCREMENT' value='$BRANCH']"

HotFix automation in Maven projects using TeamCity

The second Maven step is to change the bugfix version in the pom.xml file.

Goals: maven has everything in one line

build-helper:parse-version versions:set -DnewVersion=${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion} versions:commit

HotFix automation in Maven projects using TeamCity

The third step is to output Git status information and others:

echo 'cat pom.xml'
cat pom.xml
echo 'git status'
git status
echo 'git remote -v'
git remote -v
echo 'git branch'
git branch

HotFix automation in Maven projects using TeamCity

The fourth step changes the developerConnection connection scheme from HTTPS to GIT.

And pushes changes to the branch specified in the Teamcity variable %BRANCH_FOR_INCREMENT%

# Здесь получаем developerConnection из файла pom.xml
developerConnection=$(xmllint -xpath "/*[local-name() = 'project' ]//*[local-name() = 'developerConnection']/text()" pom.xml | sed  's|scm:git:ssh://||')
echo developerConnection
# Здесь меняем / на : в URL для git_remote_url
git_remote_url=$(echo $developerConnection| sed 's/gitlab.com//gitlab.com:/g')
echo git_remote_url
echo $git_remote_url

git remote set-url origin $git_remote_url

# Если вы не используете ввстроенную возможность Teamcity получения user и email из ~/.gitconfig, то можно указать их здесь
echo 'git config user.name %TEAM_USER%'
git config user.name %TEAM_USER%
echo 'git config user.email %TEAM_USER_EMAIL%'
git config user.email %TEAM_USER_EMAIL%
echo 'git add .'
git add .
echo 'git commit -m "Increment bugfix"'
git commit -m "Increment bugfix"

git push --set-upstream origin %BRANCH_FOR_INCREMENT%

HotFix automation in Maven projects using TeamCity

Fifth step get from file pom.xml version and install it in teamcity variable TAG_FROM_VERSION. Note that the version from the file pom.xml without a v in front. A tag based on this version is already with the letter v at the beginning.

echo "Get version package from pom.xml"
VERSION_AFTER_CHANGE=`python -c "import xml.etree.ElementTree as ET; print(ET.parse(open('pom.xml')).getroot().find('{http://maven.apache.org/POM/4.0.0}version').text)"`
echo $VERSION_AFTER_CHANGE
echo "##teamcity[setParameter name='TAG_FROM_VERSION' value='v$VERSION_AFTER_CHANGE']"

HotFix automation in Maven projects using TeamCity

Sixth step - tagging bugfix versions. This is done using Maven with the desired option Goal.

Option Goals:

-Dtag=%TAG_FROM_VERSION% scm:tag

HotFix automation in Maven projects using TeamCity

Source: habr.com

Add a comment