読者です 読者をやめる 読者になる 読者になる

いまどきの.travis.yml

travis node.js io.js npm

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

先にNode.js向けの完成形の.travis.ymlはこちら。

language: node_js
node_js:
  - "0.12"
  - "4"
  - "6"
sudo: false
cache:
  directories:
    - node_modules

Tipsは3つ。

  • テスト対象のNode.jsバージョンを指定する
  • sudo: false: コンテナベースの環境を使う
  • cache: 依存パッケージをキャッシュする

テスト対象のNode.js/io.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

追記 (20160309)

その後の変化

  • io.jsはNode.jsに統合されてNode.js v4, v5がリリースされた。
  • LTSという概念が導入され、LTSであるv4は2年半(2018/4/1)までサポートされる。
  • v5はLTSではないので、v6が出てしばらくするとサポートが切れる。

ということを踏まえて、最近は以下のようにバージョン指定している。

node_js:
  - "0.12"
  - "4"
  - "5"

v0.10はさすがに減ってきているので削除。 "5"ではなく"stable"と指定するとv6が出たらv6でテストしてくれるのだけど、その場合はv5のテストが実行されないので、そんなに長くはないけどトラブルが起こりがちな併存期間にうまくいかない。 本当は、Node.jsでサポート中のバージョン全部、みたいに指定したいんだけどね。

追記 (20160911)

その後の変化

  • Node.js v6がリリースされた
  • 10月にはv7がリリースされ、v5がサポート終了し、v6がLTSに
  • AWS Lambdaがv4をサポート
  • v0.12は新規パッケージではさすがにサポート不要な印象

ということを踏まえて、v7が出るまではこのぐらいで良さそう。

node_js:
  - "4"
  - "6"

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 って表示されちゃって切ない