I det här inlägget kommer vi att beskriva hur man ställer in HotFix-automatisering i Maven-projekt med hjälp av Teamcity.
För att göra en HotFix görs vanligtvis många manuella åtgärder:
- Skapa en gren för den version som du vill släppa HotFix för
- Korrigera felet i versionen
- Ändra bugfix-versionen i versionsgrenen
- Släpp en tagg för bugfix-versionen
Punkterna 1, 3 och 4 kan automatiseras.
Innan vi går vidare till ämnet vill jag ta upp ett viktigt och komplext ämne — versionshantering av mjukvara. En kort översikt av Semver kan fås från denna skärmdump. 
Mer information kan läsas via länken: .
Alla inställningar som beskrivs i detta inlägg bygger på och .
I Trunk-Based Development måste en egen gren skapas för varje version. Alla ändringar (hotfixar) inom denna version kommittas till denna gren.
I detta inlägg automatiserar vi följande saker:
CI-bygg
Skapa en ny version
Skapa en gren för versionen
Ändra bugfix-versionen

Krav:
- Git-repo för att lagra din kod. Inlägget kommer att använda repot .
- Teamcity-server och agent. Du kan sätta upp din lokala Teamcity-server och agent med hjälp av
- Där du har Teamcity-agenten måste Java, Maven, Git vara installerade.
Vi skapar ett projekt i Teamcity kallat "Automation Maven Hotfix" och skapar där 4 uppgifter.
CI Build (CI-bygg)
Create branch for release (Skapa gren för version)
Maven increment bugfix (Ändra bugfix-version)
Maven release (Skapa ny version)
Skärmdump av projektet:

Allmänna inställningar
I alla uppgifter måste du markera rutan “Clean build: Radera alla filer i checkout-katalogen före byggandet“, eftersom jag fick fel utan denna ruta.
Vi skapar en enda VCS. Funktionerna för VCS markeras med rött.

Vanligtvis används HTTPS-schema för VCS. I Branch specification: anges att alla grenar och alla taggar ska inkluderas:
+:refs/heads/*
+:refs/tags/*Det är nödvändigt att skapa 4 konfigurationsparametrar.
- BRANCH_FOR_INCREMENT
- TAG_FROM_VERSION
- TEAM_USER
- TEAM_USER_EMAIL
Fältet value i BRANCH_FOR_INCREMENT och TAG_FROM_VERSION bör lämnas tomt.

Det är nödvändigt att ladda upp/lägga till en privat nyckel. I alla uppgifter utom CI Build krävs en privat nyckel.

I varje uppgift utom CI Build måste privat nyckel kopplas i avsnittet Byggfunktioner.
Exempel för Maven release

CI Build**.
I uppgiften CI Build finns det bara ett steg mvn clean test

Maven release
I uppgiften Maven release 2 steg. Det första steget kontrollerar att grenen är master. Om grenen inte är master, misslyckas uppgiften.
BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" != "master" ]]; then
echo 'Branch is not master';
echo 'Aborting';
exit 1;
fi
Det andra steget är standard mvn release:prepare med alternativet —batch-mode

Skapa en gren för release
För att skapa en hotfix för releasen måste en gren skapas. Detta hanteras av uppgiften Skapa en gren för release. Den består av 2 steg.
Det första steget kontrollerar att grenen inte master, och det andra kontrollerar att versionen i filen pom.xml inte innehöll ordet SNAPSHOT
BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" == "master" ]]; then
echo 'Gren är master';
echo 'Avbryter';
exit 1;
fi
echo "Hämta version paket från 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 "Kontrollera SNAPSHOT"
if [[ $version == "*SNAPSHOT*" ]]; then
echo "******************* V A R N I N G *************************"
echo "************ Du skapar gren för SNAPSHOTS ******************"
echo "***********************************************************"
exit 1
fi
Det andra steget ändrar developerConnection anslutningsschema från HTTPS till 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
Maven ökar bugfix
Uppgiften består av 6 delar. Det skulle ha kunnat refaktoreras, men det fungerar som det är.
Det första steget — kontrollera att grenen inte master. Om grenen master uppgiften misslyckas.
BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" == "master" ]]; then
echo 'Gren är master';
echo 'Avbryter';
exit 1;
fi
# Här hämtar vi versionen från filen pom.xml
echo "Hämta version paket från 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)"`
# Måste göra checkout på rätt gren.
# Annars visar git status detached för rätt gren.
# Det bör så att git status helt enkelt visar grenen
git checkout $BRANCH
# Exportera bash variabel till Teamcity variabel för vidare användning.
echo "##teamcity[setParameter name='BRANCH_FOR_INCREMENT' value='$BRANCH']"
Det andra Maven steget ändrar bugfix-versionen i filen pom.xml.
Mål: i Maven är allt i en rad
build-helper:parse-version versions:set -DnewVersion=${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion} versions:commit
Det tredje steget — skriv ut Git status och andra:
echo 'cat pom.xml'
cat pom.xml
echo 'git status'
git status
echo 'git remote -v'
git remote -v
echo 'git branch'
git branch
Det fjärde steget ändrar developerConnection anslutningsschema från HTTPS till GIT.
Och pusha ändringarna till den gren som anges i Teamcity variabeln %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%
Det femte steget hämtar från filen pom.xml versionen och ställer in den i Teamcity variabel TAG_FROM_VERSION. Observera att versionen från filen pom.xml utan bokstaven v framför. Och taggen, baserad på denna version, har redan bokstaven v i början.
echo "Hämta version paket från 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']"
Det sjätte steget — taggning bugfix version. Det görs med hjälp av Maven med rätt alternativ i Mål.
Alternativ Mål:
-Dtag=%TAG_FROM_VERSION% scm:tag
Källa: habr.com
