jgitverでMavenのバージョン番号をGitの情報から自動設定する

sbtではsbt-dynverプラグインを使ってGitのタグ、コミット情報から自動でバージョン番号を付与できるのですが、同じようなことをMavenでやるにはどうするのがいいのかなぁと以前から疑問に思っていたので、どのような方法があるのか少し調べてみました。結論としては以下のjgitverを使うのがよさそうかなという感じです。

github.com

Mavenのextensionとして導入すると、デフォルトでは以下のようなルールでバージョンが使用されます(pom.xmlに記述されているバージョン番号は無視されます)。

  • タグ(x.x.x) -> x.x.x
  • masterブランチ -> x.x.y-SNAPSHOT
  • その他のブランチ -> x.x.y-<ブランチ名>-SNAPSHOT

CIでMavenリポジトリにデプロイするようにする場合でも、タグ以外からデプロイする場合は自動的にSNAPSHOTになりますし、ブランチの場合は自動的にブランチ名がバージョン名に含まれるので別ブランチのSNAPSHOTで上書きしてしまうということもなくなります。

導入方法は簡単で、プロジェクトのルートディレクトリに.mvnディレクトリを作成し、そのディレクトリ内にextensions.xmlを以下の内容で作成します。

<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
  <extension>
    <groupId>fr.brouillard.oss</groupId>
    <artifactId>jgitver-maven-plugin</artifactId>
    <version>1.5.1</version>
  </extension>
</extensions>

これだけでpackage、deployなどのゴールを実行する際にデフォルトのルールで自動的にバージョンが付与されます。mvn validateを実行するとどのようなバージョン番号になるかを確認できます。

$ mvn validate
...
[INFO] jgitver-maven-plugin is about to change project(s) version(s)
[INFO]     io.github.gitbucket::markedj::1.0.16 -> 1.0.16-SNAPSHOT

.mvn/jgitver.config.xmlで細かい挙動の設定が可能です。たとえば以下のようにすると未コミットの変更がある場合にバージョン番号にdirtyというフラグメントが含まれるようになります。

<configuration xmlns="http://jgitver.github.io/maven/configuration/1.1.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jgitver.github.io/maven/configuration/1.1.0 https://jgitver.github.io/maven/configuration/jgitver-configuration-v1_1_0.xsd">
    <useDirty>true</useDirty>
</configuration>

また、以下の設定を追加するとmasterブランチの代わりに使用するメインブランチのブランチ名を指定することができます。

<nonQualifierBranches>main</nonQualifierBranches>

設定方法の詳細についてはjgitverのドキュメントを参照してください。

バージョン番号にコミットIDを含めるオプションもあるのですが、このオプションが有効な場合でもSNAPSHOTバージョンの場合はコミットIDを含まないという仕様のようです。このあたりもうちょっと柔軟性があるといいなと思いますが、通常のユースケースでは概ねjgitverの標準の挙動で問題ないのではないかと思います。

ところでこのjgitverの作者のMatthieuはGitBucketの初期の頃によく手伝ってくれていたコミッタだったりします。当時は仕事でGitBucketを使っていたようで、Scalaは書けないとのことでしたがw ユーザサポートを手伝ってくれたり、プラグインの紹介サイトを作ってくれたりしていました。数年ぶりに今度は自分が彼のOSSのお世話になっているというのはなかなか面白い巡り合わせだなと思います。OSSのエコシステムに改めて感謝ですね。