その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

Git の Tag が打たれる毎に Travis CI を使って fat-jar を GitHub Releases にリリースする

Java で書かれた CLI ツールやアプリケーションを配布する時,依存するモジュールを全部まとめて1つの jar ファイルに固めて,単独で実行可能にしておくと何かと便利です.巷ではこうした jar ファイルを fat-jar と呼ぶようです.

この fat-jar ファイルをどこにホスティングしようかと考えた時,Perl だと fatpacked なスクリプト (fat-jar のように全部の依存を1つにまとめたスクリプト) をモジュールのコンポーネントに含めてそれごと CPAN にアップロードして CPAN 経由で配布するというのが一般的だったんですが,Maven Central ではどうやらそういう方法は人気が無いようなので,今回は GitHub Releases で配布することにしました.

今回は Git の Tag が切られて push された時 (つまりリリース処理がされた時) に自動的に fat-jar をビルドして GitHub Releases にリリースしたかったので,Travis CI の deploy 機能 (まじ便利!!) を利用して実現することにしました.


以下,その為に実行した手順です.
java-mysql-diff で同様のことを行っているので,適宜参照してもらうと良いと思います.

Releases · moznion/java-mysql-diff · GitHub

1. fat-jar な jar ファイルを maven でビルドする

Maven で fat-jar を生成する為に, pom.xml を以下のように記述しました.

...
<profiles>
  <profile>
    <id>fatjar</id>
    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.5.3</version>
          <configuration>
            <descriptorRefs>
              <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
          </configuration>
          <executions>
            <execution>
              <id>make-assembly</id>
              <phase>package</phase>
              <goals>
                <goal>single</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>
...

maven-assembly-plugin を使い, jar-with-dependencies を有効にしておいて,package フェイズで走らせるようにする設定にしておくと,fat-jar を 生成する事が出来ます *1

以下のようにコマンドを走らせると fat-jar を生成することが出来ます.-P fatjar は profile の id です.

$ mvn -P fatjar package

参考: java - Building Maven fat jar conditionally - Stack Overflow

2. .travis.yml を編集して,tag が打たれて push される毎に GitHub Releases にリリースするようにする

手始めに travis コマンドをインストールします.travis コマンドは Ruby Gems で配布されているので適宜やっていきます.
travis | RubyGems.org | your community gem host

$ gem install travis

次に travis setup コマンドを実行して,リリースに必要な .travis.yml の内容を生成します.
今回は GitHub Releases にリリースするので,travis setup releases を実行します.

$ travis setup releases
Detected repository as your/repository, is this correct? |yes|
Username: foobar
Password for foobar: ******************************
File to Upload: target/fat.jar
Deploy only from your/repository? |yes|
Encrypt API key? |yes|

コマンドを実行すると色々訊かれるので適宜答えます.デフォルト値が yes になってるところは大体 yes で良いような気がしています.
正常に完了すると,以下の様な内容が .travis.yml に追加されると思います.

deploy:
  provider: releases
  api_key:
    secure: <SECRET KEY>
  file: target/$TRAVIS_TAG.jar
  on:
    repo: your/repository

これに色々足していきます.

deploy:
  provider: releases
  api_key:
    secure: <SECRET KEY>
  file: target/$TRAVIS_TAG.jar
  skip_cleanup: true
  on:
    repo: your/repository
    all_branches: true
    tags: true

all_branchestags が有効になってないと,tag を切った時にリリースというのが上手く動かなかったので追記しておきます.skip_cleanup: true はまあ適当にという感じ.


あとは .travis.yml に before_deploy のフェイズでデプロイ対象となる fat-jar (今回の場合は file: target/$TRAVIS_TAG.jar) を生成してやる設定を追記します.

before_deploy:
    - mvn -P fatjar clean package -DskipTests=true -Dproject.finalName=$TRAVIS_TAG

環境変数 $TRAVIS_TAG には git の tag 名が入っているので,それを上手いこと使ってやると mvn release:prepare のようなコマンドでリリース処理を行う時に,自動的に切られる tag 名と噛み合って便利だったりします.まあここらへんはお好みでという感じです.

3. tag を切って push

後は git の tag を切って push すると自動的にテスト・ビルドが走って自動的に GitHub Releases にリリースされます.




手順は以上です.

このように,リリースするたびに自動的に fat-jar をリリースするようにしておくと結構便利です.
今回は Travis CI を利用しましたが,wercker 等の他のサービスでも同様のことが出来ると思います *2

ぜひお試し下さい.

*1:build の設定で maven-jar-plugin を併せて利用する必要があると思います

*2:しかし wercker は tag が切られるタイミングでごにょごにょする,みたいなのをやるのがちょっと面倒くさくて見送ったという経緯が……