Tento příspěvek se zaměří na nastavení automatizace HotFix v projektech Maven pomocí Teamcity.
Aby bylo možné provést HotFix, obvykle je zapotřebí mnoha ručních úkonů:
- Vytvořit branch pro vydání, na které chcete nasadit HotFix
- Opravit chybu ve vydání
- Změnit verzi bugfixu v branchi vydání
- Nasadit tag verze bugfixu
Úkoly 1, 3 a 4 lze automatizovat.
Než přejdeme k tématu, chtěl bych se dotknout důležité a složité oblasti — verzování softwaru. Stručně o Semver se lze dozvědět z tohoto screenshotu. 
Více informací lze nalézt na odkazu: .
Všechny nastavení popsaná v tomto příspěvku se opírají o a .
V Trunk-Based Development je třeba pro každé vydání vytvořit svůj branch. Všechny změny (hotfix) v rámci tohoto vydání se odesílají do tohoto branch.
V rámci tohoto příspěvku automatizujeme následující úkoly:
CI build
Vytvoření nového vydání
Vytvoření branch pro vydání
Změna verze bugfixu

Požadavky:
- Git repozitář pro uložení vašeho kódu. V příspěvku bude použit repozitář .
- Server a agent Teamcity. Můžete nastavit svůj lokální server a agent Teamcity pomocí
- Tam, kde máte agent Teamcity, musí být nainstalovány java, maven a git
Vytvoříme v Teamcity projekt „Automation Maven Hotfix“ a vytvoříme tam 4 úkoly.
CI Build (CI sestavení)
Vytvořit branch pro vydání (Vytvoření branch pro vydání)
Maven increment bugfix (Změna verze bugfixu)
Maven release (Vytvoření nového vydání)
Screenshot projektu:

Obecná nastavení
Ve všech úkolech je třeba zaškrtnout políčko „Clean build: Smazat všechny soubory v adresáři checkout před sestavením“, protože při absenci tohoto zaškrtnutí se objevovaly chyby.
Vytváříme jediný VCS. Vlastnosti VCS jsou zvýrazněny červeně.

Obvykle VCS používá schéma HTTPS. V Specifikace branch: je uvedeno sledovat všechny větve a všechny tagy:
+:refs/heads/*
+:refs/tags/*Je třeba vytvořit 4 konfigurační parametry.
- BRANCH_FOR_INCREMENT
- TAG_FROM_VERSION
- TEAM_USER
- TEAM_USER_EMAIL
Pole value v BRANCH_FOR_INCREMENT a TAG_FROM_VERSION je třeba nechat prázdné.

Je třeba nahrát/přidat privátní klíč. Ve všech úkolech kromě CI Build je potřebný privátní klíč.

V každém úkolu kromě CI Build v sekci Build Features je nutné připojit privátní klíč.
Příklad pro Maven release

CI Build**.
V úkolu CI Build je pouze jeden krok mvn clean test

Maven release
V úkolu Maven release 2 kroky. První krok ověřuje, že branch je master. Pokud branch není master, úkol selže.
BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" != "master" ]]; then
echo 'Branch is not master';
echo 'Aborting';
exit 1;
fi
Druhý krok je standardní mvn release:prepare s možností —režim dávkování

Vytvořit větev pro vydání
Pro vytvoření hotfixu pro vydání je třeba vytvořit větev. To zajišťuje úkol Vytvořit větev pro vydání. Má dva kroky.
První krok kontroluje, že větev není master, a druhý kontroluje, že verze v souboru pom.xml neobsahovala slovo SNAPSHOT
BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" == "master" ]]; then
echo 'Větev je master';
echo 'Zastavuji';
exit 1;
fi
echo "Získávám verzi balíčku z 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 "Kontrola SNAPSHOT"
if [[ $version == "*SNAPSHOT*" ]]; then
echo "******************* UPOZORNĚNÍ *************************"
echo "************ Vytváříte větev pro SNAPSHOTS ******************"
echo "***********************************************************"
exit 1
fi
Druhý krok mění v developerConnection schéma připojení z HTTPS na 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
Oprava chyby inkrementace Maven
Úkol se skládá ze 6 částí. Mohlo to být refaktorizováno, ale i tak to funguje.
První krok — kontrola, že větev není master. Pokud větev master úkol selhává.
BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" == "master" ]]; then
echo 'Větev je master';
echo 'Zastavuji';
exit 1;
fi
# Zde získáváme verzi ze souboru pom.xml
echo "Získávám verzi balíčku z 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)"`
# Musíme provést checkout na potřebnou větev.
# Jinak git status ukazuje detachnutou k požadované větvi.
# Je potřeba, aby git status ukazoval prostě větev
git checkout $BRANCH
# Exportujeme proměnnou bash do proměnné Teamcity pro další použití.
echo "##teamcity[setParameter name='BRANCH_FOR_INCREMENT' value='$BRANCH']"
Druhý Maven krok mění bugfix verzi v souboru pom.xml.
Cíle: u maven všechno na jednom řádku
build-helper:parse-version versions:set -DnewVersion=${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion} versions:commit
Třetí krok — výstup informací Git status a další:
echo 'cat pom.xml'
cat pom.xml
echo 'git status'
git status
echo 'git remote -v'
git remote -v
echo 'git branch'
git branch
Čtvrtý krok mění v developerConnection schéma připojení z HTTPS na GIT.
A posílá změny do větve, uvedené v proměnné Teamcity %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%
Pátý krok získává ze souboru pom.xml verzi a nastavuje ji v Teamcity proměnnou TAG_FROM_VERSION. Všimněte si, že verze ze souboru pom.xml je bez písmene v na začátku. A tag, na jehož základě se už vytváří verze, už začíná písmenem v.
echo "Získávám verzi balíčku z 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']"
Šestý krok — tagování bugfix verze. Dělá se to pomocí Maven s potřebnou možností v Cíl.
Volba Goals:
-Dtag=%TAG_FROM_VERSION% scm:tag
Zdroj: habr.com
