TravisCIでGradleを使った自動ビルドをやってみた


始めに

自動ビルドするために悪戦苦闘したので、それについていろいろ書いておこうと思います。
所々に詰みポイントが設置されていたので、僕がどのように抗ったか、その様をお楽しみください。
外部サイト多めです。

対象プロジェクト: https://github.com/Morichan/ClassesGrammar

目標と理由

  • 目標1. ボタン1つでビルドできるようにする
    • Gradleってやつがいいらしいから使いたい
    • でもコマンド上ではやりたくない!(せっかくIDEなんだから)
  • 目標2. GitHubにPushしたらビルドできているか自動で確認する
    • TravisCIっていうのが便利っぽい
    • というかバッジが欲しい!

前提知識

この記事を読むために必要な各項目における大雑把な知識を、次に示します。

Java9
Jigsawが使えるようになって、Deprecatedアノテーションにうるさくなった
JUnit5
Nested便利!public明記いらない!もうJUnit4には戻れない!
IntelliJ
ライブラリの追加やGitHubとの連携はできるけど、実行ボタンの意味はよく知らない
TravisCI
クラウド実行環境?PaaSみたいなものかな?
Gradle
Makefileの凄いやつだよね?とりあえずコマンド上でGradleを実行できるようにはしたし、コマンド上で簡単なプロジェクトは(本を参考に)作ったよ

実際のプロジェクトとの差異

僕が作ったプロジェクトは、ANTLRの構文解析用文法を作るためのものなので、この記事の内容とは別にANTLR用の設定もいろいろしていますが、この記事では扱いません。

目標1. ボタン1つでビルドできるようにする

まずはGradleでビルドできるようにしなければなりません。

IntelliJでGradleプロジェクトの作成

次のサイトにおける、プロジェクトの作成を参考にしました。

参考: http://www.task-notes.com/entry/20150720/1437361200

詰みポイント1. GroupIdとArtifactIdとVersionって何?

次のサイトにおける「マルチプロジェクト」の項目によると、GroupIdとArtifactIdは次のことを意味するらしいです。

rootのbuild.graldeのgroupを「com.example」とした場合、coreプロジェクトから生成されるpom.xmlは「com.example core」になる

参考: http://www.ne.jp/asahi/hishidama/home/tech/groovy/gradle/java.html

つまりはこういうこと(あくまで考え方としては)です。

  • root
    • build.gradle
    • core
      • build.gradle
      • src/main/java

また、Versionについては、次のサイトを参考にしました。
SNAPSHOTは開発中のバージョンを意味するそうです。

参考: http://nisenabe.hatenablog.com/entry/2017/02/15/232219

その後の調査で、次のサイトを見つけました。
次のサイトがそのものズバリを説明しています。

参考: http://improve-future.com/what-are-groupid-artifactid.html

例えば次のように設定すると...

  • GroupId: the.group
  • ArtifactId: artifaction
  • Version: 0.0.1

build.gradleファイルに、グループ名とバージョンが埋め込まれます(後で書き換えることは可能です)。

build.gradle
group 'the.group'
version '0.0.1'
// ...

また、IntelliJにおけるプロジェクト名(ルートファイル名)がartifactionに、ビルドファイルがartifaction-0.0.1.jarになります。

GroupIdは省略が可能なので、マルチプロジェクトでなければ省略するのも手です。

実行プログラムの作成

Gradleプロジェクトの作成と同様、次のサイトにおける、実行プログラムの作成を参考にしました。

参考: http://www.task-notes.com/entry/20150720/1437361200

僕は、Java9とJUnit5を使うので、次のサイトを参考にbuild.gradleファイルを書きました。

build.gradle
apply plugin: 'java'

sourceCompatibility = 9

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0'
  }
}

apply plugin: 'org.junit.platform.gradle.plugin'

repositories {
  mavenCentral()
}

dependencies {
  testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0'
  testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.0.0'
}

参考: http://siosio.hatenablog.com/entry/2017/09/15/075601

このままでは実行ボタンが非アクティブですから、build.gradleを右クリックしてRun 'build'を選択します。
これできっとビルド成功です、楽しみですね!

詰みポイント2. 動いているのかどうかわからない

実行ボタンを押すと、ものすごいスピードで成功してくれます。

terminalOnIntelliJ
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.gradle.internal.reflect.JavaMethod (file:/C:/home/.gradle/wrapper/dists/gradle-4.0-bin/3p92xsbhik5vmig8i90n16yxc/gradle-4.0/lib/gradle-base-services-4.0.jar) to method java.lang.ClassLoader.getPackages()
WARNING: Please consider reporting this to the maintainers of org.gradle.internal.reflect.JavaMethod
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details
:help

Welcome to Gradle 4.0.

To run a build, run gradle <task> ...

To see a list of available tasks, run gradle tasks

To see a list of command-line options, run gradle --help

To see more detail about a task, run gradle help --task <task>

BUILD SUCCESSFUL in 5s
1 actionable task: 1 executed

Process finished with exit code 0

前半のWARNINGは問題ありません。
Java9による、Deprecatedアノテーションの警告です。

なんと、BUILD SUCCESSFULですよ!
この項はこれで終わりですね。

...はい、:helpと書いてあります。
これは、コマンド上で次のコマンドを打った場合とほぼ同じです。

コンソール
$ gradle

どうやら、タスクが設定されていないようです。

次のサイトを参考に、タスクの設定箇所を見つけました。
Program argumentsの項目にタスクを設定すればいいです。

参考: http://difficultposition.info/blog/2013/09/247/

また、設定する項目は、次のサイトを参考にしました。

参考: https://qiita.com/navekazu/items/af886fa200be8a683132

僕はとりあえずProgram argumentsにbuildと入力し、再び実行ボタンを押しました。
すると、実行結果が次のようになります。

terminalOnIntelliJ(WARNINGは省略)
:compileJava NO-SOURCE
:processResources NO-SOURCE
:classes UP-TO-DATE
:jar
:assemble
:compileTestJava NO-SOURCE
:processTestResources NO-SOURCE
:testClasses UP-TO-DATE
:test NO-SOURCE
:check UP-TO-DATE
:build

BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

Process finished with exit code 0

実行できました!

目標2. GitHubにPushしたらビルドできているか自動で確認する

とりあえずGitHubにあげる前に、.gitignoreファイルなどの設定はしておきます。

GitHubとTravisCIの連携設定

次のサイトを参考にしました。

参考: http://sue445.hatenablog.com/entry/2013/06/01/170607

また、次のサイトも参考に、.travis.ymlファイルを書いてみました。

参考: https://qiita.com/kazuki43zoo/items/3718ee05fa526d048a86

.travis.yml
language: java

sudo: required
dist: trusty

jdk:
  - oraclejdk9

これでPushすればきっとTravisで自動ビルドしてくれるはずです、楽しみですね!

詰みポイント3. gradle assembleでCould not determine java version from '9.0.1'.

次の記事を参考にしました。
どうやら、TravisCIにおけるGradleのバージョンが古いようです。

参考: https://qiita.com/Kaoru_Yamamoto/items/dcb3815795d6e752cff3

ローカルで成功していたのは、新しいGradleを導入していたからで、これは偶然の産物だったのでしょう。
gradle-wrapper.propertiesファイルを書き換えればいいようです。

詰みポイント4. gradle-wrapper.propertiesファイルがない

恐らくIntelliJ特有の問題かもしれません。

IntelliJでGradleプロジェクトを作成すると、gradle-wrapper.propertiesやgradlewファイルといったバッチファイルは作ってくれないようです。
新しく作ればいいのですが、でもそうなると、今後新しくGradleプロジェクトを作成するたびにそれらをつくる羽目になるため面倒です。

ローカルではうまくいってるのだから、TravisCI上のGradleのバージョンをあげればいいのです。

次の記事を参考に、.travis.ymlを書き換えました。

.travis.yml
language: java

sudo: required
dist: trusty

jdk:
  - oraclejdk9

# Gradleを最新版にする(古い場合はJava9に未対応)
before_install:
  - curl -s api.sdkman.io | bash
  - source /home/travis/.sdkman/bin/sdkman-init.sh # ターミナル上での表示結果
  - sdk list gradle
  - sdk install gradle 4.4.1 # gradle version 4.2.1 以降を使う
  - sdk default gradle 4.4.1

参考: https://qiita.com/saba1024/items/967ee3d8a79440a97336

古いサイトではgvmを使うと書いてあることがあるので気を付けてください。
僕は当然のように引っかかりました。

バッジをREADMEに追加

GitHubとTravisCIの連携設定の項目と同様に、次のサイトを参考に設定しました。

参考: http://sue445.hatenablog.com/entry/2013/06/01/170607

詰みポイント5. フォーマットが違う

これは項目を設けるほどでもないとは思いますが、僕は躓いたので書きます。

TravisCIのリポジトリのページにあるバッジをクリックしてください。

すると項目が出てきます。
欲しいブランチを設定しMarkdown形式を選んで、フォーマットされたテキストをコピーし、READMEに貼り付けましょう。

現在

所要時間: 約30時間(3ヶ月前にも別のプロジェクトで挑戦して挫折した時間込み)

終わりに

僕はスクリプト言語をよく触るため、ビルドがこんなに大変だとは思いませんでした。
結果としては満足です。

ここまで読んでくださって、ありがとうございます。
もしおかしい点、気づいた点がありましたら教えてください。
特に、GradleやTravisCIについては誤字脱字、根本的な間違いなどがあると思います。