1. sbt で Travis CI を設定する

sbt で Travis CI をセットアップする 

Travis CI は、オープンソースおよびプライベートプロジェクト向けのホスト型継続的インテグレーションサービスです。GitHub でホストされている多くの OSS プロジェクトは、プッシュとプルリクエストを検証するために、Travis CI のオープンソース版を使用しています。ここでは、Travis CI をセットアップするためのベストプラクティスについて説明します。

project/build.properties を設定する 

継続的インテグレーションは、自分のマシン以外でコードが動作するかどうかを確認するのに最適な方法です。まだ作成していない場合は、project/build.properties を作成し、sbt.version 番号を明示的に設定してください。

sbt.version=1.9.8

これで、ビルドは 1.9.8 を使用するようになります。

Travis マニュアルを読む 

Travis の多くのヒントは、Travis の公式ドキュメントにあります。このガイドを参考にしてください。詳細については、公式ソースを参照してください。

基本的なセットアップ 

Travis CI のためのビルドのセットアップは、主に .travis.yml のセットアップです。Scala のページには、基本的なファイルは次のようになると書かれています。

language: scala

jdk: openjdk8

scala:
   - 2.10.4
   - 2.12.18

デフォルトでは、Travis CI は sbt ++$TRAVIS_SCALA_VERSION test を実行します。明示的に指定してみましょう。

language: scala

jdk: openjdk8

scala:
   - 2.10.4
   - 2.12.18

script:
   - sbt ++$TRAVIS_SCALA_VERSION test

script セクションの詳細については、ビルドの設定をご覧ください。

Scala ページに記載されているように、Travis CI は sbt コマンドとして paulp/sbt-extras を使用します。これは、後で説明する JVM オプションをオーバーライドする場合に関連してきます。

プラグインビルドのセットアップ 

sbt プラグインの場合、Scala でのクロスビルドは必要ないため、必要なのは次の設定だけです。

language: scala

jdk: openjdk8

script:
   - sbt scripted

もう 1 つの有益な情報源は、Travis CI 自体が出力する内容を読んで、仮想環境がどのようにセットアップされているかを学ぶことです。たとえば、次の出力から、JVM オプションを渡すために JVM_OPTS 環境変数を使用していることがわかります。

$ export JVM_OPTS=@/etc/sbt/jvmopts
$ export SBT_OPTS=@/etc/sbt/sbtopts

カスタム JVM オプション 

デフォルトの sbt および JVM オプションは、Travis CI の担当者が設定しており、ほとんどの場合で正常に動作します。カスタマイズする場合は、まずデフォルトとして現在使用しているものを読んでください。Travis はすでに環境変数 JVM_OPTS を使用しているため、代わりにファイル travis/jvmopts を作成できます。

-Dfile.encoding=UTF8
-Xms2048M
-Xmx2048M
-Xss6M
-XX:ReservedCodeCacheSize=256M

次に、-jvm-opts オプションを使用して script セクションを書き出します。

script:
   - sbt ++$TRAVIS_SCALA_VERSION -jvm-opts travis/jvmopts test

変更を加えた後、Travis のログでフラグが有効になっているかどうかを確認します。

# Executing command line:
java
-Dfile.encoding=UTF8
-Xms2048M
-Xmx2048M
-Xss6M
-XX:ReservedCodeCacheSize=256M
-jar
/home/travis/.sbt/launchers/1.9.8/sbt-launch.jar

動作しているようです。すべてのパラメーターを設定することの 1 つの欠点は、環境が更新されて、将来デフォルト値でより多くのメモリが得られる場合に、取り残される可能性があることです。

いくつかの JVM オプションを追加する方法を次に示します。

script:
   - sbt ++$TRAVIS_SCALA_VERSION -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M -J-Xms1024M test

sbt-extra スクリプトは、-D または -J で始まる引数を JVM に直接渡します。

再度、Travis のログを確認して、フラグが有効になっているかどうかを確認しましょう。

# Executing command line:
java
-Xms2048M
-Xmx2048M
-Xss6M
-Dfile.encoding=UTF8
-XX:ReservedCodeCacheSize=256M
-Xms1024M
-jar
/home/travis/.sbt/launchers/1.9.8/sbt-launch.jar

: これは意図的に -Xms フラグを複製します。これは最善のことではないかもしれません。

キャッシュ 

Travis CI で キャッシュ機能を使用することで、sbt ビルドを高速化できます。

使用できる cache: 設定のサンプルを次に示します。

cache:
  directories:
    - $HOME/.cache/coursier
    - $HOME/.ivy2/cache
    - $HOME/.sbt

: Coursier は OS によって異なるキャッシュの場所を使用するため、上記は macOS または Windows イメージに応じて変更する必要があります。

不要なキャッシュ更新を避けるために、次のスニペットも必要になります。

before_cache:
  - rm -fv $HOME/.ivy2/.sbt.ivy.lock
  - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete
  - find $HOME/.sbt        -name "*.lock"               -print -delete

上記変更を組み合わせることで、Travis CI はキャッシュされたディレクトリを tar で圧縮し、クラウドストレージプロバイダーにアップロードします。全体として、キャッシングを使用すると、ジョブごとのビルド時間を数分短縮できます。

ビルドマトリックス 

すでに Scala クロスビルドの例を見てきました。

language: scala

jdk: openjdk8

scala:
   - 2.10.4
   - 2.12.18

script:
   - sbt ++$TRAVIS_SCALA_VERSION test

環境変数を使用してビルドマトリックスを形成することもできます。

env:
  global:
    - SOME_VAR="1"

  # This splits the build into two parts 
  matrix:
    - TEST_COMMAND="scripted sbt-assembly/*"
    - TEST_COMMAND="scripted merging/* caching/*"

script:
   - sbt "$TEST_COMMAND"

これで、この sbt プラグインをビルドするために 2 つのジョブが作成され、異なる統合テストが同時に実行されます。この手法は、仮想マシン間でビルドを並列化するで説明されています。

通知 

Travis CI を設定して通知することができます。

デフォルトでは、リポジトリのメンバーである場合、コミッターとコミット作成者にメール通知が送信されます[…].

また、デフォルトでは、特定のブランチで、次の場合にメールを送信します。

  • ビルドが壊れたばかりであるか、まだ壊れている
  • 以前に壊れていたビルドが修正されたばかり

デフォルトの動作は妥当に見えますが、必要に応じて、notifications セクションをオーバーライドして、ビルドが成功した場合にもメールを送信したり、IRC のような他の通信チャネルを使用したりできます。

# Email specific recipient all the time
notifications:
  email:
    recipients:
      - [email protected]
  on_success: always # default: change

また、コマンドライン travis ツールを使用した暗号化について読む良い機会でもあります。

$ travis encrypt [email protected]

不安定なネットワークまたはテストへの対処 

不安定なネットワークまたはテストの影響を受けやすいビルドの場合、Travis CI は、ページビルドがタイムアウトしていますで説明されているいくつかのトリックを作成しました。

コマンドを travis_retry で開始すると、リターンコードが 0 以外の場合、コマンドが 3 回再試行されます。キャッシングを使用すると、不安定なネットワークの影響が軽減されることを願いますが、それでも興味深いものです。ドキュメントからの注意点を次に示します。

travis_retry の使用は慎重に行うことをお勧めします。過度に使用すると、より深い根本的な問題がある場合に、ビルド時間が長くなる可能性があります。

Travis に関するもう 1 つのヒントは、出力タイムアウトです。

ビルドには、グローバルタイムアウトと出力に基づいたタイムアウトがあります。ビルドから 10 分間出力が受信されない場合、原因不明の理由で停止したと見なされ、その後強制終了されます。

これを 20 分に延長できる travis_wait という関数があります。

その他のこと 

データベースを設定するUbuntu パッケージをインストールする継続的にデプロイするなど、他にもできることがあります。

Travis はテストを並行して実行する機能を提供しており、ビルドに時間制限も設けています。特にプラグインのスクリプト化されたテストスイートが長い場合は、たとえば、ディレクトリ内のスクリプト化されたテストのサブセットを実行できます。

    - TEST_COMMAND="scripted tests/*1of3"
    - TEST_COMMAND="scripted tests/*2of3"
    - TEST_COMMAND="scripted tests/*3of3"

ディレクトリtestsに対して、3つのチャンクを作成し、それぞれのチャンクを個別に実行します。

設定例 

以下に、それらを全てまとめたサンプルを示します。ほとんどのセクションはオプションであることを覚えておいてください。

language: scala

jdk: openjdk8

env:
  # This splits the build into two parts
  matrix:
    - TEST_COMMAND="scripted sbt-assembly/*"
    - TEST_COMMAND="scripted merging/* caching/*"

script:
  - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M "$TEST_COMMAND"

before_cache:
  - rm -fv $HOME/.ivy2/.sbt.ivy.lock
  - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete
  - find $HOME/.sbt        -name "*.lock"               -print -delete

cache:
  directories:
    - $HOME/.cache/coursier
    - $HOME/.ivy2/cache
    - $HOME/.sbt