Automatisation de HotFix dans les projets Maven à l'aide de TeamCity
Cet article décrira la configuration de l'automatisation HotFix dans les projets Maven à l'aide de Teamcity.
Pour exécuter HotFix, de nombreuses étapes manuelles sont généralement effectuées :
Créez un brunch pour la version sur laquelle vous souhaitez déployer HotFix
Correction d'un bug dans la version
Changer la version du correctif dans la branche release
Déployer la balise de version de correction de bug
Les points 1,3,4 peuvent être automatisés.
Avant de passer au sujet, je voudrais aborder un sujet important et complexe : gestion des versions logiciel. Vous pouvez brièvement comprendre Semver dans cette capture d'écran.
Dans le développement basé sur le tronc, vous devez créer votre propre branche pour chaque version. Toutes les modifications (correctifs) dans cette version sont validées dans cette branche.
Dans le cadre de cet article, nous allons automatiser les choses suivantes :
Serveur et agent Teamcity. Vous pouvez augmenter votre serveur et votre agent Teamcity locaux en utilisant docker-compose
Là où vous avez l'agent Teamcity, java, maven, git doivent être installés
Créons le projet « Automation Maven Hotfix » dans Teamcity et créons-y 4 tâches.
Construction CI
Créer une branche pour la publication
Correction de bug d'incrémentation Maven (Modifier la version de correction de bug))
Version Maven (Création d'une nouvelle version)
Capture d'écran du projet :
Paramètres généraux
Dans toutes les tâches vous devez cocher la case "Clean build : supprimez tous les fichiers du répertoire de paiement avant la build", car sans cette case à cocher, j'ai eu des erreurs.
Nous créons un seul VCS. Les fonctionnalités VCS sont entourées en rouge.
Généralement, les VCS utilisent le schéma HTTPS. DANS Spécification de la branche : indiqué pour surveiller tous les brunchs et tous les tags :
+:refs/heads/*
+:refs/tags/*
Il est nécessaire de créer 4 paramètres de configuration.
BRANCH_FOR_INCREMENT
TAG_FROM_VERSION
ÉQUIPE_USER
TEAM_USER_EMAIL
Le champ de valeur dans BRANCH_FOR_INCREMENT et TAG_FROM_VERSION doit rester vide.
Vous devez télécharger/ajouter une clé privée. Toutes les tâches, à l'exception de CI Build, nécessitent une clé privée.
Dans chaque tâche, à l'exception de CI Build, dans la section Build Features, vous devez connecter une clé privée.
Exemple pour Version Maven
Construction CI**.
Dans une tâche Construction CI juste une étape test propre mvn
Version Maven
Dans une tâche Version Maven 2 étapes. La première étape consiste à vérifier que le brunch est maître. Si le brunch n'est pas maître, alors la tâche tombe.
BRANCH=$(git branch | grep * | cut -d ' ' -f2)
echo "$BRANCH"
if [[ "$BRANCH" != "master" ]]; then
echo 'Branch is not master';
echo 'Aborting';
exit 1;
fi
La deuxième étape est standard version mvn:préparer avec possibilité --temps différé
Créer une branche pour la publication
Pour créer un correctif pour une version, vous devez créer une branche. C'est ce que fait la taska Créer une branche pour la publication. Elle a 2 marches.
La première étape vérifie que le brunch n'est pas maître, et le second vérifie que la version est dans le fichier pom.xml ne contenait pas le mot INSTANTANÉ
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
La deuxième étape modifie le schéma de connexion dans DeveloperConnection de HTTPS à 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
Correction d'un bug d'incrémentation Maven
La tâche se compose de 6 parties. Cela aurait pu être refactorisé, mais cela fonctionne toujours.
La première étape est de vérifier que le brunch n'est pas maître. Si le brunch maître la tâche tombe.
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']"
La deuxième étape Maven consiste à modifier la version du correctif dans le fichier pom.xml.
La quatrième étape modifie le schéma de connexion dans DeveloperConnection de HTTPS à GIT.
Et pousse les modifications vers la branche spécifiée dans Teamcity par la 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%
La cinquième étape consiste à extraire du fichier pom.xml version et l'installe dans Ville d'équipe variable TAG_FROM_VERSION. Notez que la version du fichier pom.xml sans la lettre v devant. Et la balise, basée sur cette version, comporte déjà la lettre v au début.
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']"
Sixième étape : le marquage bugfix versions. Cela se fait en utilisant Maven avec l'option requise dans Objectif.