Mavenプロジェクトのversionは、基本的にpom.xml
に書いておきますが、基本的に手動でバージョンを上げなければなりません。
追記2020/04/03
releaseプラグインを使えば、x.y.zのzは自動的にインクリメントしてくれるそうです。
でも、日付やタイムスタンプ、ビルド番号を付与したいって言われたら?
pom.xml
をshスクリプトとかで書き換える?マルチモジュールのとき、大変すぎない?
mvn versions:set -DnewVersion=whatever
で毎回一斉に書き換える?
手間が増えるよね?結局ビルドにスクリプトが必要になっちゃう?
JenkinsとかCIツールだったらプラグインで出来るみたいだけど・・・
なお、ここでやりたいのは、Arfictの生成物であるファイル名をどうにかしたいのではなく、Artifactのバージョンそのものを付ける方法の話です。
Goal
mvn install
などで、モジュールのversion
に自動的に日付とビルド番号を付与する。
例)0.0.1.20200401-2
自前でスクリプトなどを書かずに実現すること。
なお、一部にCIの機能を使うことは許容する。
・・・どういうことかというと、とりあえずversion
のテンプレートなどが定義できていて、一部の値をCIツールからビルドコマンドで渡せればOK、という意味です。
環境
ツールなど | バージョンなど |
---|---|
MacbookPro | macOS Mojave 10.14.5 |
IntelliJ IDEA | Ultimate 2019.3.3 |
Java | AdoptOpenJDK 11 |
apache maven | 3.6.3 |
Spring Framework | 5.2.4.RELEASE |
JUnit | 5.6.0 |
Tomcat | apache-tomcat-8.5.51 |
実現方法
結論から言うと、一部にCIの機能を使うことは許容することで、日付とビルド番号を付与できます。
なお、このプロジェクトは、マルチモジュール構成となっていて、すべてのモジュールが親のバージョンを使い完全にバージョンを一致させる運用としています。
簡単に言うと、サブモジュールでは
<artifactId>some-api</artifactId>
<packaging>war</packaging>
とだけして、version
タグを入れません。ルートのpom.xml
にだけ、入れておきます。
そうすると、サブモジュールもすべて同じバージョンになります。
1.ルートpomへの<version>
の設定
<version>0.0.1.${buildDate}-${revision}</version>
2.ルートpomへの<properties>
の設定
<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- バージョニングに使う日付 -->
<buildDate>${maven.build.timestamp}</buildDate>
<!-- バージョニングに使う日付のフォーマット -->
<timestamp>${maven.build.timestamp}</timestamp>
<maven.build.timestamp.format>yyyyMMdd</maven.build.timestamp.format>
<!-- バージョニングに使うリビジョン番号。
CI/CDツールにて -Drevision=buildNumber で上書きする -->
<revision>SNAPSHOT</revision>
</properties>
コメントにある通り、<revision>
はコマンドラインから指定可能です。省略すると、SNAPSHOT
が付くことになります。
3.サブモジュールの<parent>
の<version>
も変更する
<parent>
<groupId>jp.example.myapp</groupId>
<artifactId>testsample</artifactId>
<version>0.0.1.${buildDate}-${revision}</version>
</parent>
すべてのサブモジュールに対して行うのを忘れないように。
4.ビルド
mvn clean install
と、mvn install -Drevision=2
としてビルドしてみてください。
各モジュールのtarget
フォルダのpom.properties
や、生成されたjar
/war
ファイルのファイル名で確認できます。(<build>/<finalName>
で上書きしていない場合)
(1)revision指定なし
$ mvn clean install
$ ls -la **/target/*.?ar
17:02 submodule/target/submodule-0.0.1.20200402-SNAPSHOT.war
17:02 core/target/core-0.0.1.20200402-SNAPSHOT.jar
#Generated by Maven
#Thu Apr 02 17:02:10 JST 2020
groupId=jp.example.myapp
artifactId=testsample
version=0.0.1.20200402-SNAPSHOT
(2)revision指定あり
$ mvn clean install -Drevision=2
$ ls -la **/target/*.?ar
17:29 submodule/target/some-api-0.0.1.20200402-2.war
17:29 core/target/some-core-0.0.1.20200402-2.jar
#Generated by Maven
#Thu Apr 02 17:29:47 JST 2020
groupId=jp.example.myapp
artifactId=testsample
version=0.0.1.20200402-2
5.CIでビルド番号を付与する
CIでの実行コマンドで、mvn install
などしていると思うので、そこに-Drevision=
オプションを追加すればよいですね。
「その日のビルド番号」は、CIツールでそれぞれ取り方があると思うので、そちらを参照してください。
とりあえず、JenkinsだとVersion Numberというプラグインを使うと、BUILDS_TODAY
というのが使えそうです。(ただ、リセットされるタイムゾーンは不明ですが・・・)
Azure Pipelinesだと、Configure run or build numbersのページによれば、$(Rev:r)
を使えば行けそうです。
参考
-Dreivision
のやり方の参考になりました。
https://stackoverflow.com/questions/18456111/what-is-the-maven-way-for-automatic-project-versions-when-doing-continuous-deliv
マルチモジュールでのバージョニング管理について参考になりました。
https://qiita.com/ms0_mtRiver/items/85593b17d6ebb8fb2cfd