背景
Javaプロジェクトを開発している時に、今まではリリースのたびにbuild.gradleのversionを書き換えていました。こういう感じのやつですね。
version = '1.2.0'
この運用だと、以下の点で問題がありました。
- リリースの度にbuild.gradleに対して変更が必要。場合によってはコンフリクトの原因にもなる。
- リリース後に再びbuild.gradleのversionにバージョンを上げて-SNAPSHOTを付ける必要がある(例:1.2.0をリリースしたら、1.3.0-SNAPSHOTに変更する)。これを忘れてpublishすると、リリースしたバージョンが上書きされてしまうので。
- 新しいブランチで開発中に、連携テストをするため暫定的にリリースしたい場合、build.gradleでユニークなバージョンを指定してpublishする必要がある。
- ローカルにコミット漏れがある状態でリリースしてしまったことがある。
最初、build.gradle
内でgitコマンドを利用できるgrgitプラグインを利用して簡単なスクリプトを書こうと思ったのですが、コード量が膨らみそうになりました。そこで、自前のプラグインを書こうか考えていたところ、nebula-releaseプラグインというものを見つけました。非常に機能が豊富そうだったので、これを利用してこの問題を解決することにしました。
build.gradleの設定
nebula-releaseプラグインに関する説明はnebula-release-pluginリポジトリにあります。プラグインの適用は、build.gradleに以下の設定を追加します。設定は他にも色々あるのですが、まずはこれだけ。
plugins {
id 'nebula.release' version '15.3.1'
}
ビルドしてみる
開発時
まずは./gradlew build
を実行してビルドしてみます。すると、以下のファイルが生成されました。
$ ls build/libs/
nebula-test-0.1.0-dev.3+618c605.jar
この命名については、Tasks Providedに記載されており、プロジェクト名の後ろに<major>.<minor>.<patch>-dev.#+<hash>
が付いています。#
が前回リリースからのコミット数、hash
がコミットのハッシュ値の一部となっているため、コンフリクトを起こすことはまずありません。また、コミットされていないファイルがある場合は、nebula-test-0.1.0-dev.3.uncommitted+618c605.jar
のようにuncommitted
が自動的に付与され、この状態ではリリースできないようになっています。
本番環境ではなく開発環境にデプロイしたいような場合に、先ほどのユニークなバージョンではなくSNAPSHOTバージョンでビルドしたい場合は、./gradlew build snapshot
を実行します。
$ ls build/libs/
nebula-test-0.1.0-SNAPSHOT.jar
リリース時
リリース時には、final
パラメタを追加します。こうすると、「プロジェクト名+バージョン」のみが付いたファイル名が生成され、現在のバージョンでタグ付けされます。
$ ./gradlew final
Inferred project: nebula-test, version: 0.1.0
> Task :release
Tagging repository as v0.1.0
Pushing changes in [v0.1.0] to origin
BUILD SUCCESSFUL in 6s
7 actionable tasks: 4 executed, 3 up-to-date
$
$ ls build/libs/
nebula-test-0.1.0.jar
次に再度./gradlew build
を実行すると、次のマイナーバージョンで生成されます。
$ ls build/libs/
nebula-test-0.2.0-dev.0+726f7c6.jar
メジャーバージョン・パッチバージョンのリリース
特にパラメタを指定せずにリリースする場合はマイナーバージョンを上げてリリースされますが、メジャーバージョンやパッチバージョンを上げたい場合は、それぞれ以下のようにパラメタを指定します。
- メジャーバージョン:
./gradlew final -Prelease.scope=major
- 例:0.3.0 -> 1.0.0
- パッチバージョン:
./gradlew final -Prelease.scope=patch
- 例:0.3.0 -> 0.3.1
その他メモ
nebulaプラグインを使っていて気付いた点を共有します。
リリース時にpublishも行う
build.gradle
に以下の行を追加して、依存関係を加えます。
tasks.release.dependsOn tasks.publish
複数のサブプロジェクトから成る場合はこのような感じで。
tasks.release.dependsOn ":sub1:publish", ":sub2:publish", ...
タグ名のプレフィックスを除く
./gradlew final
でリリースする際、通常はv1.2.0
のように先頭にv
が付くのですが、これを付けたくない場合はbuild.gradle
に以下の行を追加します。
project.release.tagStrategy.prefixNameWithV = false
AWS CodeBuildとの連携
nebulaプラグインはgitの履歴から最新のタグを探すため、必ず全てのgitの履歴が必要となります。もしAWS CodeBuildを利用している場合は、ソースの設定の「Gitのクローンの深さ」でFull
を指定することで正しくバージョンを取得することができます。