La livraison d'une application est souvent une étape qui met du temps à être automatisée. Et malheureusement les outils existants n'aident pas forcément dans ce sens, à moins de parfaitement les maîtriser. Dans ce cadre, sbt-dynver offre une souplesse et facilité de mise en œuvre en reléguant notamment la gestion du numéro de version... à Git. Et ça change pas mal de chose dans le process de livraison !

Numéro de version

La particularité de sbt-dynver réside dans sa façon de numéroter les versions. Cette numérotation varie en fonction de l'état du code au sein de Git. Tout en restant compatible avec SemVer.

Si au moins un tag sous Git est présent, c'est le dernier tag créé qui préfixera le numéro de version. Il faut utiliser v1.2.3 ou v3.4 comme format de tag ; la lettre v est nécessaire et est automatiquement retirée dans le numéro de version.

Si des commits ont été ajoutés depuis le dernier tag, sbt-dynver ajoutera dans le numéro de version le nombre de commits créés depuis le dernier tag, ainsi que l'ID du dernier commit.

Si des modifications apparaissent, mais n'ont pas été committées, sbt-dynver ajoutera un timestamp.

sbt-dynver intervient sur les settings version in ThisBuild, isSnapshot in ThisBuild et isVersionStable in ThisBuild. Voici un tableau présentant les différents formats.

Format Exemple Description Snapshot Stable
<tag> 1.2 Un tag vient d'être apposé sur le dernier commit
<tag>+<delta>-<last_commit_id> 1.2+3-c5114f99 Un tag existe. Il y a eu des commits depuis le dernier tag (ici 3).
<tag>+<delta>-<last_commit_id>-<timestamp> 1.2+3-c5114f99-20190603-1337 Un tag existe. Il y a eu des commits depuis le dernier tag (ici 3). Et des modifications non-commitées sont apparues depuis
<delta>-<last_commit_id> 2-f217ecb6 Il y a des commits (ici 2), mais pas de tag
<delta>-<last_commit_id>-<timestamp> 2-f217ecb6-20190603-1337 Des commits sont présents (ici 2). Pas de tag. Et des modifications non-commitées sont apparues depuis.
HEAD-<timestamp> HEAD-20190603-1337 Le projet n'est pas géré sous Git ou il n'y a aucun commit à l'heure actuel

sbt-dynver donne ainsi plus de précisions sur l'état du projet, même lorsque le produit est livré. Le plugin permet d'indiquer ainsi s'il s'agit d'une version officielle (format <tag>), d'une version en cours de développement comme pour les snapshots/canary releases/nightly builds (format <tag>+<delta>-<last_commit_id>) ou d'une version livrée en urgence sans passer par les process de livraison habituels (formats incluant le <timestamp>). Cette numérotation facilite la mise en place de process de livraison continue.

Livraison

Le process de livraison permis par sbt-dynver est d'ailleurs plus simple. Il permet de se passer de la déclaration du numéro de version dans le fichier build.sbt ou dans le fichier version.sbt, comme le recommande de son côté sbt-release. En fait, il ne faut surtout pas déclarer de version.

Supposons maintenant que vous ayez un serveur d'intégration continue à l'écoute des push sur votre repo Git. Et que le workflow qui se déclenche passe par un sbt publish.

Du coup, pour livrer une version officielle, vous devez faire :

$ git tag v1.2
$ git push --follow-tags

Si vous avez fait git config --global push.followTags true, l'option --follow-tags n'est pas nécessaire.

Le process permis par sbt-dynver diffère du process de livraison à la Maven, dans lequel les divers snapshots ne sont pas différenciés. Il diffère aussi du process proposé par sbt-release dans la mesure où c'est le développeur qui gère les tags de version.

Le plugin sbt-release-early se base sur sbt-dynver pour la gestion des numéros de version. sbt-release-early s'assure en plus que la livraison est faite dans le contexte d'un serveur d'intégration continue et est compatible avec Sonatype OSSRH et JFrog Bintray. C'est intéressant dans un cadre Open Source et permet de livrer souvent, même des versions intermédiaires !