いまどきの.travis.yml

いまさら感もあるのだけど、あまり知られていないようなのでTravis CIの高速化+αなtipsを書いておく。

先に完成形の.travis.ymlはこちら。

language: node_js
node_js:
  - "0.10"
  - "0.12"
  - "io.js"
sudo: false
cache:
  directories:
    - node_modules

Tipsは3つ。

  • io.jsでもテストする(for Node.jsプロジェクト)
  • sudo:false: コンテナベースの環境を使う
  • cache: 依存パッケージをキャッシュする

io.jsでもテストする

これはNode.jsなプロジェクト限定の話。最近はカジュアルにio.jsを使う人/プロジェクトが増えてきている(要出典)ので、特に政治的な理由でもなければnpmパッケージのテストはNode.jsとio.jsの両方で流しておくのが良いと思う。.travis.ymlに書くだけだし、並列にビルドされるのでこれによってすごく遅くなるということはない。

language: node_js
node_js:
  - "0.10"
  - "0.12"
  - "io.js"

Node.js v0.10を切るかどうかはパッケージによる*1

sudo:falseでコンテナベースの環境を使う

Travisではコンテナベースの環境でのビルド実行をサポートしている。ここで言うコンテナっていうのはいわゆるDockerとかの文脈でいうあのコンテナ。

Travis CI: Using container-based infrastructure

.travis.yml

sudo: false

と書き足すだけで良い。ユーザー側からすると、sudoができなくなるぐらいでデメリットはないと思う。

この恩恵はでかくて、Travisインスタンス順番待ち時間がかなり短縮される。例えば、いま実験したところコンテナベースだとgit pushから10秒ぐらいでビルドが開始した。これが非コンテナだと1分以上かかった。いま15:00 JSTでUSはオフタイムだけど、あっちのオンタイムだと10分以上待つこともあってもっと差が開く。

ビルド開始してからの実行時間はほとんど変わらない。後述のキャッシュを除いては。

依存パッケージをキャッシュする

コンテナベースビルドの恩恵はもう一つあって、キャッシュが使えること。

Travis CI: Caching Dependencies and Directories

ビルドの最初のステップで、指定ディレクトリの前回のファイル構成がキャッシュから復元される。主にnpm, Bunlder, CocoaPods, aptなどのパッケージマネージャを想定しているらしい。

効果としては、10秒ぐらいかかっていたnpm install1秒で終わるようになる。依存パッケージが多かったりネイティブビルドが必要なパッケージを使ってるプロジェクトほど効果は高い。

このキャッシュ機能はコンテナベースまたは有償のプライベートビルドでのみ使える。通常のビルドではダメ。

設定は、BunlderやCocoaPodsはネイティブに対応しているので、

language: ruby
cache: bundler

だけでいけるのだけど、npmはネイティブ対応してないのでディレクトリを直接指定する。

cache:
  directories:
    - node_modules

キャッシュの状況はTravisのプロジェクトページから Settings > Caches で見れる。

f:id:teppeis:20150408154007p:plain

キャッシュはgitブランチと言語バージョンの組み合わせごとに保存されるので変に混ざったりしない。もしそのブランチのキャッシュがまだなかったら、masterブランチからキャッシュを取ってくる(かしこい!)。

おかしなことがあったら画面から手動でキャッシュを消せる。あとgemでインストールできるCLIでもtravis cacheでキャッシュを確認したり消したりできる。おかしくなったことも消したことも無いけど。

注意点として、キャッシュはビルド環境のローカルにあるわけではなくS3に保存されているため、キャッシュを復元するときでもネットワーク経由になる。そのため、公式記事によれば数百MBを超える場合は効果が薄いかも、とのこと。

まとめ

USが寝てる時間にビルドするのが一番効果が高い。

*1:ちなみに "0.10" を 0.10 って書くとテストは動くけどTravisの画面で 0.1 って表示されちゃって切ない