Semantic Release : Springboot, Docker and Gitlab
Retour aux articles

Semantic release permet d’automatiser la génération et le versionnement des releases de vos projets gérées dans un outil d’intégration continue. La documentation officielle de Semantic Release mentionne: “semantic-release is meant to be executed on the CI environment after every successful build on the release branch. This way no human is directly involved in the release process and the releases are guaranteed to be unromantic and unsentimental.” Dans cet exemple, je vais illustrer l’usage de Semantic Release en utilisant Gitlab, mais nous pourrions tout aussi bien utiliser Github, Bitbucket voire Jenkins.   1-1024x670.avif

Prérequis

  Afin de pouvoir suivre cet article, vous devez :

  • Avoir un compte sur gitlab.com
  • Connaître le paramétrage d’un pipeline d’intégration continue dans Gitlab ci (.gitlab-ci.yml)
  • Savoir utiliser git en ligne de commande
  • Avoir lu la documentation de SEMVER sur lequel s’appuie Semantic Release
  • Installer node et Docker sur votre poste de travail (cela permettra de faire quelques tests en local, ce prérequis n’est pas obligatoire pour faire fonctionner Semantic Release dans une CI)

Documentation

 

Création du projet

  Nous allons illustrer l’usage de Semantic Release en nous appuyant sur un projet développé en Java et qui utilise le framework Springboot. Remarque : La plupart des étapes à mettre en place pour utiliser semantic release et décrites ci-dessous seront identiques pour des projets git n’utilisant pas Java ou Springboot. Pour vous simplifier la tâche, nous vous proposons un projet prêt à l’emploi qui s’appelle “parrot”. Il nous servira de base à la suite de cet article. Pour l’utiliser, il suffit d’en faire un fork.     La complexité de notre article réside dans l’usage de Semantic Release, pas dans la nature du projet concerné ! Il n’est pas donc nécessaire de regarder le contenu de ce projet pour comprendre la suite. Mais si vous connaissez Java et Springboot, vous constaterez qu’il s’agit d’un projet très simple. Une fois le projet créé dans votre environnement, vous pouvez le cloner sur votre poste de travail. 2-1024x108.avif

git clone git@gitlab.com:XXXXXXX/parrot.git

Nous pouvons commencer à apprendre à utiliser Semantic Release.  

Semantic Release en mode local

  Afin de faire nos premiers pas avec Semantic Release, nous allons commencer par l’utiliser en mode local (dry run). Attention :

  • Assurez vous que node est bien installé sur votre poste de travail pour pouvoir exécuter Semantic Release en local
  • Toutes les commandes seront exécutées en étant dans le répertoire du repository précédemment cloné

Tapez la commande suivante, et observons ensemble son résultat.

> npx semantic-release -b main -p @semantic-release/commit-analyzer [01:07:39] [semantic-release] › ℹ Running semantic-release version 19.0.5 [01:07:39] [semantic-release] › ✔ Loaded plugin "analyzeCommits" from "@semantic-release/commit-analyzer" [01:07:39] [semantic-release] › ⚠ This run was not triggered in a known CI environment, running in dry-run mode. [01:07:47] [semantic-release] › ⚠ Run automated release from branch main on repository git@gitlab.com:rtg-tmp/parrot.git in dry-run mode [01:07:48] [semantic-release] › ✔ Allowed to push to the Git repository [01:07:48] [semantic-release] › ℹ No git tag version found on branch main [01:07:48] [semantic-release] › ℹ No previous release found, retrieving all commits [01:07:48] [semantic-release] › ℹ Found 2 commits since last release [01:07:48] [semantic-release] › ℹ Start step "analyzeCommits" of plugin "@semantic-release/commit-analyzer" [01:07:48] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: Initial Load [01:07:48] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The commit should not trigger a release [01:07:48] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: Initial commit [01:07:48] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The commit should not trigger a release [01:07:48] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analysis of 2 commits complete: no release [01:07:48] [semantic-release] › ✔ Completed step "analyzeCommits" of plugin "@semantic-release/commit-analyzer" [01:07:48] [semantic-release] › ℹ There are no relevant changes, so no new version is released.

Dans ce premier usage, nous utilisons npx pour démarrer Semantic Release (ce qui permet de l’installer s’il n’a pas encore été installé). Deux paramétres sont passés sur la ligne de commande :

  • -b main : Désigne le nom de la branche qui portera nos releases
  • -p @semantic-release/commit-analyzer : Indique que nous allons nous contacter d’utiliser un seul plugin ici. Nous rajouterons des plugins à mesure de l’avancement dans cet article.

La sortie indique de nombreuses informations, voici les explications principales :

  • Le plugin est chargé (ce plugin fait parti intégrante de Semantic Release et n’a pas besoin d’être préalablement chargé)
  • Semantic Release détecte qu’il s’exécute en local (ou plus précisément, il détecte qu’il n’est pas dans un environnement connu de CI comme Gitlab ci) et va donc fonctionner en mode dégradé (dry run).
  • Semantic Release ne détecte aucun tag et aucune release.
  • Le plugin parcourt le commit log du repository. Pour le moment, aucun des commits ne justifie la création d’une release.

Modifiez le repository du projet (par exemple : modifiez contenu du fichier README.md), puis ajoutez et commitez cette modification dans le repository local. Pour le moment, il n’est pas utile de pousser ces mofications dans gitlab. Attention : le texte associé au commit devra respecter la norme conventional commit afin que le plugin commit analyser fasse son oeuvre !

git add README.md git commit -m"fix: typo"

Exécutez à nouveau Semantic Release :

npx semantic-release -b main -p @semantic-release/commit-analyzer ... [01:30:27] [semantic-release] › ℹ No git tag version found on branch main [01:30:27] [semantic-release] › ℹ No previous release found, retrieving all commits[01:30:27] [semantic-release] › ℹ Found 3 commits since last release [01:30:27] [semantic-release] › ℹ Start step "analyzeCommits" of plugin "@semantic-release/commit-analyzer" [01:30:27] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: fix: typo [01:30:27] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The release type for the commit is patch [01:30:27] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: Initial Load [01:30:27] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The commit should not trigger a release [01:30:27] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analyzing commit: Initial commit [01:30:27] [semantic-release] [@semantic-release/commit-analyzer] › ℹ The commit should not trigger a release [01:30:27] [semantic-release] [@semantic-release/commit-analyzer] › ℹ Analysis of 3 commits complete: patch release [01:30:27] [semantic-release] › ✔ Completed step "analyzeCommits" of plugin "@semantic-release/commit-analyzer" [01:30:27] [semantic-release] › ℹ There is no previous release, the next release version is 1.0.0 [01:30:27] [semantic-release] › ⚠ Skip v1.0.0 tag creation in dry-run mode [01:30:27] [semantic-release] › ✔ Published release 1.0.0 on default channel ....

Vous observez que le plugin commit-analyser traite différemment le dernier commit (mais continue d’ignorer les autres). Comme aucune release n’existe encore, il annonce qu’il devrait publier la relase 1.0.0 après avoir créé le tag v1.0.0. Étant dans un mode — dry-run aucunes de ces deux actions n’a réellement était exécutée. Un fichier de paramétrage plutôt que la ligne de commande : Regroupons le paramétrage de Semantic Release dans un fichier .release :

plugins:

  • "@semantic-release/commit-analyzer"

branches: ["main"]

Vous obtiendrez le même résultat que précédemment en utilisant :

npx semantic-release

Semantic Release est donc capable - en analysant le commit log — de déterminer le numéro de version de la prochaine release. Le paragraphe How it works de la documentation officielle de Semantic Release explique plus précisément les règles de numérotation automatique. Semantic Release est beaucoup plus complet que la simple numérotation des releases, ces fonctionnalités sont intégrées dans des plugins, nous allons en voir un certain nombre par la suite. Mais avant toute chose, intégrons l’outil dans une CI.  

Intégration à Gitlab CI

  Dans le cadre d’une CI, Semantic Release s’exécute sur le serveur d’intégration continu (gitlab dans notre cas). Pendant son exécution, il aura donc besoin des droits d’accès au référentiel GIT pour pouvoir

  • Créer des tags
  • Créer des releases
  • Modifiez des fichiers du repo

Pour cela, Semantic Release requiert un Personal Access Token (PAT) afin de lui autoriser cet accès. Utilisez le token créé, afin d’initialiser une variable d’environnement GL_TOKEN dans les paramètres du projet parrot dans Gitlab (Settings -> cicd -> Variables). Cette variable d’environnement est nécessaire au fonctionnement de semantic release : cf documentation Pour un usage futur, décochez la case Protect Variable   Nous allons maintenant déléguer à Gitlabci la responsable d’exécuter l’outil Semantic Release. Pour cela, créer le fichier .gitlab-ci.yml suivant : stages: - release 3-1024x746.avif

release: image: retengr/ci-semrel:2.3.1 stage: release script:

  • npx semantic-release

L’image retengr/ci-semrel:2.3.1 a été créé par mes soins, et contient node et Semantic Release, plus un certains nombres d’outils (notamment maven). Ajoutez, commitez et poussez les modifications dans gitlab.

git add .gitlab-ci.yml .releaserc git commit -m"feat: Ajout CI" git push

Le résultat obtenu de la CI est similaire au précédent, à l’exception de :

... [7:56:26 AM] [semantic-release] › ✔ Completed step "analyzeCommits" of plugin "@semantic-release/commit-analyzer" 38[7:56:26 AM] [semantic-release] › ℹ There is no previous release, the next release version is 1.0.0 39[7:56:28 AM] [semantic-release] › ✔ Created tag v1.0.0 40[7:56:28 AM] [semantic-release] › ✔ Published release 1.0.0 on default channel ...

Et comme nous pouvons le constater, Semantic Release à posé un tag sur le dernier commit !

git pull --tags From gitlab.com:Rtgr-test/parrot * [new tag] v1.0.0 -> v1.0.0

  Par contre, Semantic Release n’a pas été capable de créer la release dans Gitlab ! En effet, contrairement aux tags, la création d’une release n’est pas possible en utilisant simplement la commande git et nécessite une action dépendant de votre outil d’intégration continue (gitlab pour nous). Pour remédier à cela, il existe un plugin Semantic Release dédié à cette action dans Gitlab : semantic-release-gitlab. J’ai pris le soin d’installer ce plugin dans l’image Docker que nous utilisons, il n’est donc pas nécessaire de l’installer pour l’utiliser. Nous pouvons donc l’utiliser en adaptant notre fichier .releaserc :4.avif

plugins:

  • "@semantic-release/commit-analyzer"
  • "@semantic-release/gitlab"

branches: ["main"]

Ajoutez, commitez et poussez cette modification :

git add .releaserc git commit -m"feat: Ajout gitlab plugin to sem. rel." git push

Remarque : j’utilise un conventional commit de type feat, ce qui donnera lieu à un incrément de la mineure du numéro de version, nous considérons en effet que l’ajout d’un plugin est une nouvelle fonctionnalité. Une fois la CI exécutée, nous obtenons : ... [1:12:50 PM] [semantic-release] › ℹ The next release version is 1.1.0 [1:12:52 PM] [semantic-release] › ✔ Created tag v1.1.0 [1:12:52 PM] [semantic-release] › ℹ Start step "publish" of plugin "@semantic-release/gitlab" [1:12:53 PM] [semantic-release] [@semantic-release/gitlab] › ℹ Published GitLab release: v1.1.0 [1:12:53 PM] [semantic-release] › ✔ Completed step "publish" of plugin "@semantic-release/gitlab" [1:12:53 PM] [semantic-release] › ℹ Start step "success" of plugin "@semantic-release/gitlab" [1:12:53 PM] [semantic-release] › ✔ Completed step "success" of plugin "@semantic-release/gitlab" [1:12:53 PM] [semantic-release] › ✔ Published release 1.1.0 on default channel... Nous voyons que le plugin a été exécutez, et son résultat est bien celui attendu :     il n’existe pas de ligne de commande git pour afficher ce résultat car la notion de release n’existe pas dans git, contrairement aux tags. Conclusion : 🍾 🙌🏽 Nous venons de créer notre première release avec Semantic Release !   5.avif

Les plugins CHANGELOG et GIT

  Un plugin permettant de générer un fichier CHANGELOG.md est proposé : semantic-release-changelog. Ce plugin permet d’automatiser la création et la mise à jour de ce fichier qui contient un suivi des modifications apportées au projet à partir des messages de commit que vous avez saisis. Pour l’activer, il suffit de le déclarer dans le fichier .releaserc :

plugins:

  • "@semantic-release/commit-analyzer"
  • "@semantic-release/release-notes-generator"
  • "@semantic-release/changelog"
  • "@semantic-release/gitlab"

branches: ["main"]

Remarque : le plugin release-notes-generator doit être ajouté afin que changelog fonctionne. Une fois la modification de ce fichier poussez le fans gitlab :

git pull git add .releaserc git commit -m"feat: Ajout CHANGELOG plugin to sem. rel." git push

Nous obtenons :

... [9:11:12 AM] [semantic-release] › ℹ Start step "prepare" of plugin "@semantic-release/changelog" [9:11:12 AM] [semantic-release] [@semantic-release/changelog] › ℹ Create /builds/Rtgr-test/parrot/CHANGELOG.md [9:11:12 AM] [semantic-release] › ✔ Completed step "prepare" of plugin "@semantic-release/changelog"...

Ces lignes indiquent que le plugin a fait son travail, mais nous ne voyons pas apparaitre le fichier CHANGELOG.md généré. En effet, gitlab exécute la ci dans un conteneur, et les fichiers générés ou modifiés par ce conteneur sont détruit en même temps que lui à la fin de la CI ! Tous les fichiers qui ont été crées ou modifiés par la ci doivent donc être commités puis poussés dans notre repository git avant de créer la release ! Pour cela, nous allons utiliser le plugin git de Semantic Release. Contrairement aux plugins que nous avons précédemment utilisés, il va être nécessaire de le paramétrer afin de lui indiquer les fichiers qui doivent-être modifiés dans le registry.

plugins:

  • "@semantic-release/commit-analyzer"
  • "@semantic-release/release-notes-generator"
  • "@semantic-release/changelog"
  • "@semantic-release/gitlab"
  • [ "@semantic-release/git", { "assets": ["CHANGELOG.md"], "message": "chore(release): ${nextRelease.version} [skip ci]", }, ]

branches: ["main"]

La syntaxe du fichier .releaserc est un peu plus complexe. Nous lui précisions ici de commiter puis pousser le fichier CHANGELOG.md, mais nous rajoutons un message qui contient une information particulière : [skip ci]. Contrairement au reste du message qui reste informatif et libre, cette partie est documentée par gitlab comme indiquant que le push qui sera fait par le plugin git de Semantic Release n’entrainera pas l’exécution de la CI (pareil pour la création du tag). Commitez, puis poussez les modifications :

git add .releaserc git commit -m"fix: add git plugin" git push

Remarque : si mon message de commit ne respecte pas le conventionnel commit, Semantic Release ne crééra pas de release ! J’ai choisis un fix car il corrige le problème précédemment évoqué, sans rajouter de fonctionnalité, ce qui aura pour conséquence d’augmenter le numéro de patch. Et on obtient maintenant :   Attention, la ci a modifié le repository distant du projet parrot ! N’oubliez pas de faire un pull sur votre poste de travail afin de voir apparaître ces modifications ! 6.avif

> git pull ... From gitlab.com:Rtgr-test/parrot * [new tag] v1.2.0 -> v1.2.0 * [new tag] v1.2.1 -> v1.2.1

Updating 7de4678..06c2f5b Fast-forward CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 CHANGELOG.md

Le fichier CHANGELOG.md a bien été généré, et appartient maintenant à la release :

## [1.2.1](https://gitlab.com/Rtgr-test/parrot/compare/v1.2.0...v1.2.1) (2023-05-20)

Bug Fixes

* add git plugin ([00c48f4](https://gitlab.com/Rtgr-test/parrot/commit/00c48f43d0300a5046278507ebf531ff6e9810e1))

Remarque 1 : les modifications antérieures à la précédente release ne sont pas prises en compte. Cela ne se serait pas produit si nous avions fais ce paramétrage dès la création du projet, nous aurions alors eu l’historique complet de nos modifications. Remarque 2 : c’est grâce au Personnel Access Token précédemment créé que le plugin GIT est habilité à pousser les fichiers dans notre repository !  

Conclusion

  Nous venons de mettre en place un mécanisme de génération automatique du CHANGELOG.md et sa prise en compte dans notre livrable grace au plugin git de Semantic Release.  

Le plugin MAVEN

  Jusqu’à présent, la nature du projet parrot n’a eu aucune conséquence sur la mise en place de Semantic Release. Mais cette partie va permettre de régler un problème que les développeurs Java ne manqueront pas d’observer. Le fichier pom.xml est un fichier bien connu par les développeur Java, il contient l’ensemble des informations nécessaires au build du projet Java. Parmis ces informations, l’une d’elle est la version de l’artefact produit :

pom.xml ... com.retengr parrot 0.0.1-SNAPSHOT parrot ...

Et comme vous le constatez, ce numéro de version n’est pas du tout en phase avec le numéro de version de la release. Remarque : Les développeurs nodejs auront un problème tout à fait similaire avec leur fichier package.json Le plugin maven-semantic-release permet d’aligner automatiquement la version indiquée dans ce fichier avec le numéro de version de notre release en se chargeant de modifier le fichier pom.xml. Nous prendrons soins de pousser cette modification dans le repository grâce au plugin git précédemment évoqué :

plugins:

  • "@semantic-release/commit-analyzer"
  • "@semantic-release/release-notes-generator"
  • "@semantic-release/changelog"
  • "@conveyal/maven-semantic-release"
  • "@semantic-release/gitlab"
  • [ "@semantic-release/git", { "assets": ["CHANGELOG.md","pom.xml"], "message": "chore(release): ${nextRelease.version} [skip ci]", }, ]

branches: ["main"]

Par défaut, le plugin maven-semantic-release essaye de pousser le résultat du build dans un référentiel d’artefact java comme Maven Central, Artifactory, Nexus, etc. Cette fonctionnalité n’est pas couverte ici, nous allons donc la désactiver en adaptant le fichier .gitlab-ci.yml :

stages:

  • release

release: image: retengr/ci-semrel:2.3.1 stage: release script:

  • npx semantic-release --skip-maven-deploy

Poussez vos modifications dans gitlab :

git add .releaserc .gitlab-ci.yml git commit -m"feat: add maven plugin" git push

Je choisis un convential commit de type feat cat je rajoute une fonctionnalité à mon application. Et nous obtenons une CI :

[INFO] Processing change of com.retengr:parrot:0.0.1-SNAPSHOT -> 1.3.0 [INFO] Processing com.retengr:parrot [INFO] Updating project com.retengr:parrot [INFO] from version 0.0.1-SNAPSHOT to 1.3.0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------

Et nous pouvons vérifier que :

git pull ... From gitlab.com:Rtgr-test/parrot a4d7faf..c857cb8 main -> origin/main * [new tag] v1.3.0 -> v1.3.0 Updating a4d7faf..c857cb8 Fast-forward CHANGELOG.md | 7 +++++++ pom.xml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-)

et

cat pom.xml ... com.retengr parrot 1.3.0 ...

Mission remplie !  

Conclusion

  Nous avons utilisé le plugin maven pour synchroniser la version indiquée dans le pom.xml avec la version de la release. La fonctionnalité de livraison proposée par ce plugin a été désactivée dans cet exemple, car nous avons fait le choix de ne pas livrer le jar produit, mais plutot une image Docker (vu ci-dessous). Remarque : Le plugin npm permet de faire l’équivalent dans le monde du développement nodejs (il en existe pour d’autres langages).  

Le plugin Docker

  Par choix, nous avons opté pour packager notre application java dans une image Docker, puis de la délivrer dans un référentiel prévu à cet effet : dans notre cas, il s’agira de docker hub (cela pourrait être Nexus, Artifactory,…). Il existe plusieurs plugins Semantic Release pour gérer le packaging et la livraison. Nous avons choisi d’utiliser codedependant/semantic-release-docker. Commençons par le début, pour construire une image Docker nous avons besoin de créer le fichier Dockerfile :

FROM openjdk:8u282-jre COPY target/parrot.jar ./ ENTRYPOINT ["java","-jar","parrot.jar"]

Pour simplifier la création du fichier Dockerfile, nous avons forcé le nom du fichier qui sera généré lors du build par maven. Pour cela, nous avons rajouté la ligne suivante dans pom.xml :

${project.name} ...

La commande suivante, exécutée localement sur votre station de travail, vous permet de vérifier que l’on peut fabriquer l’image, et qu’elle fonctionne :

mvn package docker build -t parrot:0.0.1 . docker run -d --rm -p 8181:8181 parrot:0.0.1 curl localhost:8181/repeat?value=John

Revenons maintenant à la construction de notre image par le plugin… Par défaut, ce plugin pousse l’image construite dans docker hub, un rapide coup d’oeil dans la documentation vous indiquera la procédure à suivre pour utiliser un autre registre de stockage. Dans Docker hub, créez un repository parrot. Il devra être déclaré public. Si vous ne créé pas ce répository vous même, alors il sera automatiquement créé par le plugin docker, mais il sera privé, ce qui engendrera ensuite des problèmes.     Remarque : Docker hub impose que le nom de l’image soit préfixée par le nom du compte docker. Dans mon cas, il s’agira de retengr/parrot. Vous changerez “retengr” avec le nom de votre compte docker. Nous précisions ci-dessous que nous souhaitons que Semantic Release génère cette image, et nous paramétrons le nom de l’image qui devra être produite. 7.avif

plugins:

  • "@semantic-release/commit-analyzer"
  • "@semantic-release/release-notes-generator"
  • "@semantic-release/changelog"
  • "@conveyal/maven-semantic-release"
  • [ "@codedependant/semantic-release-docker", { "dockerImage": "retengr/parrot" } ]
  • "@semantic-release/gitlab"
  • [ "@semantic-release/git", { "assets": ["CHANGELOG.md","pom.xml"], "message": "chore(release): ${nextRelease.version} [skip ci]", }, ]

branches: ["main"]

Ainsi, le plugin va construire l’image “retengr/parrot” en utilisant le Dockerfile précédemment créé, en lui ajoutant un tag qui correspond au numéro de version de la release que nous sommes en train de construire. Le plugin Docker ayant besoin de se connecter à Docker hub, il est nécessaire de lui fournir des informations d’authentification; Pour cela, la documentation de ce plugin mentionne que l’on doit déclarer deux variables d’environnement dans gitlab ci :

  • DOCKER_REGISTRY_USER
  • DOCKER_REGISTRY_PASSWORD

Pour simplifier le paramétrage, nous avons choisi de déclarer ces variables directement dans le fichier .gitlab-ci.yml. Nous aurions aussi pu le paramétrer au niveau de la CI comme nous l’avons fait précédemment pour GL_TOKEN. Remarque : Afin d’éviter de mettre votre mot de passe docker hub en dur, nous vous recommandons d’utiliser un Access Token afin de vous connecter au docker hub. Documentation

stages:

  • release

variables: DOCKER_REGISTRY_USER: "YOUR DOCKER HUB ACCOUNT" DOCKER_REGISTRY_PASSWORD: "DOCKER_HUB_ACCESS_TOKEN_HERE" DOCKER_HOST: tcp://docker:2375

release: image: retengr/ci-semrel:2.3.1 services:

  • docker:dind stage: release script:
  • mvn package
  • npx semantic-release --skip-maven-deploy

La CI se chargera maintenant de construire notre projet java afin de fabriquer le fichier parrot.jar, qui sera ensuite utilisé pour construire l’image (cf Dockerfile). Poussez les modifications dans gitlab :

git add .gitlab-ci.yml .releaserc Dockerfile pom.xml git commit -m"feat: add docker plugin" git push

Je choisis un convential commit de type feat cat je considère rajouter une fonctionnalité à mon application. Nous pouvons maintenant vérifier que :

  • Le tag a bien été généré

git pull ... From gitlab.com:Rtgr-test/parrot 22a9c9f..17577e7 main -> origin/main * [new tag] v1.4.0 -> v1.4.0 Updating 22a9c9f..17577e7 Fast-forward CHANGELOG.md | 13 +++++++++++++ pom.xml | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-)

  • La release a bien été générée

  semantic release : springboot docker and gitlab  

  • L’image docker a bien été publiée dans le docker hub

  semantic release : springboot docker and gitlab   Remarques : les tags latest et 1-latest ont aussi été générés dans le docker hub. Il s’agit du comportement par défaut décrit dans la documentation. Il est possible de modifier ce comportement en modifiant .releaserc de la façon suivante :

- [ "@codedependant/semantic-release-docker", { "dockerImage": "retengr/parrot", "dockerTags": [ "{{#if prerelease.[0]}}latest-{{prerelease.[0]}}{{else}}latest{{/if}}", "{{version}}", ], }, ]

Prerelease

  Une prerelease se matérialise par une branche différente de main qui contiendra le code correspondant à une version de prerelease (une béta, ou une alpha, selon vos souhaits). Il est évidemment de votre responsabilité de déterminer le gitflow d’usage normal d’une telle branche (qui a le droit de pousser dessus, …). Le rôle de Semantic Release sera simplement de mettre en place mécanisme de versionnement de la release qui tiendra compte du fait que c’est une béta. Afin de mettre en place une prerelease, il convient de déclarer dans .releaserc la branche qui fera office de béta Remarque : le nom de la branche est à votre choix

plugins:

  • "@semantic-release/commit-analyzer"
  • "@semantic-release/release-notes-generator"
  • "@semantic-release/changelog"
  • "@conveyal/maven-semantic-release"
  • [ "@codedependant/semantic-release-docker", { "dockerImage": "retengr/parrot" } ]
  • "@semantic-release/gitlab"
  • [ "@semantic-release/git", { "assets": ["CHANGELOG.md","pom.xml"], "message": "chore(release): ${nextRelease.version} [skip ci]", }, ]

branches: ["main", { name: "beta", prerelease: true }]

Sur votre poste de travail, créez cette branche, puis ajoutez, commitez et poussez toutes les modifications que vous aurez apporté au projet. Seul le fichier .releaserc a été modifié, mais cela nous suffit pour vérifier le fonctionnement :

git checkout -b beta git add .releaserc git commit -m"feat: prerelease branch" git push --set-upstream origin beta

A l’issue du traitement de la CI : Nous pouvons maintenant vérifier que :

  • Un tag “béta” a bien été généré

git pull ... From gitlab.com:Rtgr-test/parrot 5c4249c..3a94172 beta -> origin/beta * [new tag] v1.5.0-beta.1 -> v1.5.0-beta.1 Updating 5c4249c..3a94172 Fast-forward CHANGELOG.md | 7 +++++++ pom.xml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-)

  • La release a bien été générée

semantic release : springboot docker and gitlab  

  • L’image docker a bien été publiée dans le docker hub

semantic release : springboot docker and gitlab   Evidemment, dans le processus de test de vos applications, un fois que la béta a été validée, il convient alors de faire un merge request afin que ces modifications soient reportées dans la branche main.   semantic release : springboot docker and gitlab   Editez le message de commit du merge request avant de faire le merge. Vérifiez qu’il n’y a pas le mot [skip ci], car sinon, la CI ne sera pas exécuté et Semantic Release ne génèrera pas la release !   semantic release : springboot docker and gitlab   Une fois le merge accepté, la CI se met en route sur la branch main, et donne lieu à la création de la release issue de la béta (dans notre cas, c’est donc la v1.5.0 qui est générée avec le tag, la release et évidemment l’image Docker associée.  

git pull ... From gitlab.com:Rtgr-test/parrot 17577e7..3d48d04 main -> origin/main * [new tag] v1.5.0 -> v1.5.0 Your configuration specifies to merge with the ref 'refs/heads/beta' from the remote, but no such ref was fetched.

semantic release : springboot docker and gitlab   semantic release : springboot docker and gitlab  

Conclusion

  Cet article illustre un usage simple mais assez complet de Semantic Release pour gérer le versionnement des releases de vos projet Gitlab. Afin de focaliser notre étude sur Semantic Release, je me suis affranchi d’un certain nombre de points qu’il sera préférable de prendre en compte dans vos projets :

  • Je n’ai pas mis en place un gitflow rigoureux
  • Je pousse mes modification directement sur la branche main sans avoir préalablement fait de branche. Il s’agit d’une mauvaise pratique la modification de main doit passer par un merge request (comme dans la dernière partie traitant de prerelease)
  • Je n’ai créé qu’un seul stage dans le workflow de build (.gitlab-ci.yaml), Une réflexion doit être menée pour avoir un workflow adapté à votre gitflow.
  • J’ai assimilé les modifications de paramétrage de Semantic release a des modifications de mon application. Normalement, l’ajout d’un plugin dans Semantic release n’est pas supposé générer une nouvelle release !

 

Pour aller plus loin

  Cet article n’a pas vocation à expliquer le cycle de vie (release steps) des différents plugins utilisés par Semantic Release. Si vous souhaitez approfondir cette partie, nous vous invitons à consulter la documentation officielle. De nombreux plugins complémentaires existent, une liste est visible ici : https://semantic-release.gitbook.io/semantic-release/extending/plugins-list On trouve notamment :

  • Des plugins de notication dans slack ou telegram,
  • Un plugin permettant de faire des substitions de texte dans n’importe quel fichier de votre projet (intéressant pour insérer dynamiquement le numéro de version dans un document du projet)
  • Un plugin permettant de gérer le versionnement des charts Helm pour Kubernetes

Remarque : vous pouvez créez assez simplement vos propres plugins Si cet article vous a plu, n’hésitez pas à laisser un commentaire !

Prêt(e) à vous former ? Demandez l'excellence

  1. Vous remplissez ce formulaire
  2. Nous vous recontactons sous 48h
  3. Nous finalisons ensemble votre inscription