Gradle でバージョン名を自動的に付ける 〜 git-describe とのコラボ
よく訓練されたアップル信者、都元です。暑いっすね。 先週は Developers.IO 2017 イベントで登壇いたしました。ご来場頂きましたみなさま、感謝感激ありがとうございました。
さて突然ですが、Gradle で管理する Java ライブラリのプロジェクトがあるとします。
Gradleプロジェクトには version
というプロパティがあり、その値は「そのビルド時点でのバージョン番号」とするのが一般的です。
よくある Gradle プロジェクトの version の指定
たいていは gradle.properties
等に値を定義しておいて…
currentVersion = 1.0-SNAPSHOT
build.gradle
の中で値を参照したりして、プロパティにセットしたりしていることでしょう。
... version = currentVersion ...
そして、リリースタグを打つ直前に値を 1.0
に書き換えてコミット。
タグを打ったら次期開発バージョン 1.1-SNAPSHOT
に書き換えてコミット…。
なーんてことを。私もやっておりました。
git-describe
git describe
というコマンドをご存知でしょうか? 一言で言えば、「現在のコミットを表すいい感じの文字列」をくれるコマンドです。
例えば git describe
の結果 1.0-12-g33bf9c0
という値が帰ってきたとします。
これは「直近のタグが 1.0
で、そこから 12
回のコミットを経た 33bf9c0
という abbrev-commit ID を持つコミット」
という意味です。
なんかいい感じですね。
Gradle 内で describe の値を取得する
ではこの値が Gradle 内から参照できれば、それを version
プロパティに入れておけばいいじゃないですか。
ということでこんなスクリプトを作って、gradle/version.gradle
ファイルとして配置してみました。
buildscript { repositories.mavenCentral() dependencies.classpath 'org.ajoberstar:grgit:1.7.2' } ext { git = org.ajoberstar.grgit.Grgit.open(file('.')) describedCommit = git.describe().toString().trim() } version = describedCommit + (describedCommit.matches(".*-[0-9]+-g[0-9a-f]{7}") ? "-SNAPSHOT" : "") + (git.status().isClean() ? "" : "+dirty") task showVersion { doLast { println version } }
Java 界の慣習で「正規リリースではないもの(=タグがついていないもの)のバージョンは "-SNAPSHOT" を付ける」 というものがあるので、ちゃんとそれに従っておきました。 また、未コミットのファイルが存在する場合はさらに "+dirty" を付ける、などの工夫もしてみました。
まぁこのあたりはお好みでスクリプトを書き換えてください。
build.gradle
ファイルからは下記のようにこのスクリプトを参照します。
apply from: 'gradle/version.gradle'
さて、showVersion
タスクを実行してみると…
$ ./gradlew showVersion > Task :showVersion 1.0-12-g33bf9c0-SNAPSHOT+dirty BUILD SUCCESSFUL in 1s 1 actionable task: 1 executed
タグを打った、まさに「正規のリリースバージョン」のコミット上でこのコマンドを実行すれば、シンプルに「1.0」等、タグ名と同じバージョン番号になります。
というわけで、リリース時にバージョン番号を繰り上げてコミット。リリース時にバージョン番号を繰り上げてコミット。 という非人道的な作業がまたひとつ、駆逐されたかと思います。
ご注意
- 当然のことながら、gitでバージョン管理しているプロジェクトでなければ、このしくみは使えませんw
- また、タグを一度も打ったことがないプロジェクトだと、ちょっと残念な感じになってしまいます。それでも上手く動くようにするには、
version.gradle
にいい感じの工夫を入れて頂ければ…(丸投げ)