r-travisでRのCIを高速化

RでCI、あんまりまじめにしないよなあ。。と思ってたら、ふとTravis CIを使うことがあったので、ちょこっとメモっておきます。

追記(10/23):

r-travisを使うのはもう古いやり方のようです。。すみません。

r-travisとは

Dirkがこんな記事を書いてました。

dirk.eddelbuettel.com

依存パッケージが多くてインストールに時間がかかる、という話らしいです。「Hadley Tax」とは言い得て妙です。(Hadleyは反論してた気がしますけど)

遅いのはなぜかというと、Linuxの場合は毎回パッケージのビルドが必要になるためです。(Windowsはバイナリをインストールするだけなのでその点はお手軽です)。 でも、Linuxでもバイナリをインストールする方法があります。それは、OSのパッケージ管理(Ubuntuだとapt)を使うことです。

とりあえず普通にやってみる

まずはr-travisを使わずにやってみます。devtoolsパッケージにデフォルトの.travis.ymlを生成してくれるuse_travis()という関数があるのでそれを使います。

devtools::use_travis()

以下のような.travis.ymlができているはずです。

language: r
warnings_are_errors: true
sudo: required

たった三行。シンプルです。これだけでパッケージをビルドして、テストを走らせてくれます。

warning_are_errorsはデフォルトではtrueになってますが、これはかなり厳しいチェックなので、CRANに送るパッケージでなければfalseにしておいてもいいかもしれません。 たとえば、ひとつでもドキュメントのない関数があるとワーニングが出てビルドが失敗したとみなされます。

ビルドステータスを表示させるには、READMEに下の一行を書いておきます。USER/REPOの部分は実際のユーザ名とレポジトリ名に読み替えてください。

[![Travis-CI Build Status](https://travis-ci.org/USER/REPO.svg?branch=master)](https://travis-ci.org/USER/REPO)

試しにqiitrレポジトリでやってみました。2分半ほどかかっています。

f:id:yutannihilation:20151017233809p:plain (https://travis-ci.org/yutannihilation/qiitr/builds/85903010)

ちなみに、もっと細かいオプションを指定することもできます。たとえば、今回は引っかかりませんでしたが、依存している外部ライブラリがある場合はapt_packagesに指定します。ドキュメントはこれ:Building an R Project - Travis CI

r-travisを使ってみる

r-travisの場合は、以下のような.travis.ymlになります。上で3行だったのが一転、長いです。

sudo: required

language: c

before_install:
  ## r-travis by Craig Citro et al
  - curl -OL http://raw.github.com/craigcitro/r-travis/master/scripts/travis-tool.sh
  - chmod 755 ./travis-tool.sh
  - ./travis-tool.sh bootstrap

install:
  - ./travis-tool.sh install_aptget r-cran-testthat r-cran-XXX r-cran-YYY

script:
  - ./travis-tool.sh run_tests

notifications:
  email:
    on_success: change
    on_failure: change

(https://github.com/yutannihilation/qiitr/blob/master/.travis.yml)

まず、languagecになっています。自力でPPAからRをインストールするためです。

before_installでは、travis-tool.shをダウンロードしてきて、travis-tool.sh bootstrapしています。これによって、R本体やTeXなど、最低限必要なパッケージがインストールされます。

installでは、必要なRのパッケージをインストールしています。ここがちょっと面倒で、language: rにする場合と違って、必要なパッケージは自分で羅列しないといけません。aptのパッケージ名はだいたい「r-cran-パッケージ名」という命名規則になってますが、違ったり、パッケージがないこともありえます。 travis-tool.sh install_depsとするとCRANから必要なパッケージをインストールしてくれるんですが、こっちはやっぱりソースからコンパイルしてしまうので少し時間がかかります。

scriptでは流すテストを書きます。travis-tool.sh run_testsとすると、すべてのテストを流してくれます。

こっちでやると、45秒でおわりました。速い。

f:id:yutannihilation:20151017234842p:plain (https://travis-ci.org/yutannihilation/qiitr/builds/85904062)

感想

どちらがいいかは微妙なところです。r-travisは速いですが、依存パッケージが増えたら自分でインストール対象に書く必要があるのがめんどくさそうです。どっかにベストプラクティスころがってないかな...