Maven tombe dans les POM

Bon, j’avais besoin d’en parler, de poser ma réflexion ici, au cas où cela servirait à quelqu’un d’autre que moi.

Les applications sur lesquelles je travaille sont toutes sous Git. Les commits forment l’histoire d’un projet, assurent son suivi. Les tags quant à eux, figent un moment de cette histoire : c’est une version.

Dès lors, je ne vois aucun intérêt à mettre à jour la version du projet dans le pom.xml de Maven (que l’on soit sur un mono-repo, ou découpé en modules). Je n’ai donc pas envie d’avoir des commits spécifiques à ce changement de fichier (coucou mvn release, coucou semantic release).

Finalement, la version Maven du projet n’aurait-elle pas de sens uniquement pour distribuer un livrable ? Personnellement, j’y crois. Ça ne m’est pas utile en local.

Déplacer le versionning du livrable en dehors du suivi du code source en fait alors une problématique de déploiement continu.

Solution proposée

<version>unused</version>

Définir un placeholder dans le POM, à la place des versions habituelles, va me permettre de ne plus m’en soucier localement. D’un point de vue local d’ailleurs, ça aura l’avantage de me faire gagner de l’espace disque. En effet, à chaque fois que j’exécuterai des tâches (package, install, verify et autres commandes magiques), j’écraserai toujours la même version.

Si je dois travailler sur une version spécifique, Git est toujours là pour m’aider, je reviens sur un tag en particulier et je peux travailler tranquillement.

Ainsi, je n’ai plus qu’à me soucier de la version Maven dans ma CI/CD. Voici un exemple simplifié en GitHub action :

name: deploy
run-name: Deploy to registry
on:
  push:
    tags:
      - '[0-9]+.[0-9]+.[0-9]+'
      - '[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+'
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: '17'
          cache: Maven
      - name: Set POM version with tag name
        run: mvn versions:set -DnewVersion=${{ github.ref_name }}
      - name: Deploy to registry
        run: echo "Some more actions to do"

Dès lors qu’un tag qui suit semantic versioning est créé, le pipeline est enclenché. Le numéro du tag est ensuite passé à Maven pour définir la version du POM qui sera modifié le temps du job. À la suite de ça, il ne reste qu’à faire les actions de déploiement vers le registry qui nous plait.

Et voilà, la version du livrable correspond à la version du tag sans qu’aucun commit de release supplémentaire n’eut été nécessaire.

Cette méthode peut s’appliquer à d’autres langages. Je pense notamment à l’écosystème Node avec le package.json pour lequel je peux rencontrer la même problématique.

En espérant que ça puisse vous être utile ! Si vous avez des remarques, des retours d’expériences similaires, n’hésitez pas à les mettre en commentaire.