x10のCI環境構築


x10言語でアプリケーションを書いた時にgithubとTravisを使ってどのようにCIを回せばよいか試行錯誤した結果について記載する。
一般的なC++やRubyなどの言語とは異なり、x10用の環境はデフォルトではTravisCIに用意されていない。ここで行うことは

  1. コードがgithubにコミットされたタイミングで、TravisCIでx10のコンパイラでビルドを行う
  2. テストを実行する
  3. x10でコンパイルしたバイナリをgithubのリリースページにアップロードする

の3つである。これらを実現したサンプルリポジトリはこちら

x10のコンパイラを準備する

まず、通常のTravisの手順通りにTravisの画面から、対象となるgithubリポジトリをCIの対象にする。
その後、ビルド手順を指定するためにtravis.ymlを準備する。

当然ながらx10のビルド環境はTravisでは提供されていないので、x10コンパイラを自分で用意する必要がある。
また今回は生成物を配布することも考えるので、x10ランタイムに静的リンクする。参考:x10のプログラムを静的リンクする
そのためにx10コンパイラとライブラリを自分でビルドする必要がある。そのために以下のようなスクリプトをリポジトリに追加する。

buildx10.sh
#!/bin/bash -eux

X10_RELEASE=SF_RELEASE_2_6_1
if [ ! -d "x10/x10.dist/bin" ]; then
  wget https://github.com/x10-lang/x10/archive/$X10_RELEASE.zip -O x10src.zip
  unzip -q x10src.zip
  rm -rf x10  # clear the empty dir made by travis cache
  mv x10-$X10_RELEASE x10
fi
if [ ! -f "x10/x10.dist/bin/x10c" ]; then
  cd x10/x10.dist/
  export X10_STATIC_LIB=1
  NPROC=${NPROC:-$(getconf _NPROCESSORS_ONLN)}
  ant -Davailable.procs=$NPROC -Doptimize=true -DNO_CHECKS=true dist-cpp
  rm -f lib/libgc.so*
  cd -
fi

また.travis.ymlには以下のように記述する。

.travis.yml
env:
- NPROC=4   # 並列ビルドのプロセス数
install:
- ./buildx10.sh
before_script:
- export PATH=$PWD/x10/x10.dist/bin:$PATH

これによってx10のコンパイラが使えるようになる。

x10のビルドとテスト実行

以下のようにtravis.ymlを設定。

.travis.yml
script:
- test/build_run_test.sh

build_run_test.sh の中身は以下の通り。x10c++コマンドのパスが通っているので、普通にビルドするだけ。
その後、ビルドしたものを実行してみて、それが期待された出力になっているかどうかを確認するためdiffを取っている。(x10にはデファクトのユニットテストフレームワークは無いので、このような対応にしている)

build_run_test.sh
#!/bin/bash -eux

SCRIPTDIR=$(cd $(dirname $BASH_SOURCE); pwd)
x10c++ -sourcepath $SCRIPTDIR/../src -d , $SCRIPTDIR/TestRunner.x10
,/a.out > test_out.txt
cat test_out.txt
diff test_out.txt $SCRIPTDIR/expected.txt

githubに生成物をアップロード

x10のコードをコンパイルするというのは、多くの人にとって面倒だし、コンパイラの使い方すらわからないので、ビルドの生成物をgithubにあげることにした。
https://docs.travis-ci.com/user/deployment/releases/
の手順にそってtravis.ymlを更新していく。

具体的には

gem install travis   # travisコマンドを準備
travis setup releases

これを実行すると、githubのユーザー名やパスワードなどが求められる。入力すると、githubにアクセスするためのトークンが生成され、.travis.ymlの"deploy"セクションに追加される。

.travis.yml
deploy:
  provider: releases
  api_key:
    secure: YOUR_API_TOKEN
  file: a.out
  skip_cleanup: true
  on:
    repo: yohm/x10_sample

さらにTravisのドキュメントに書いてある通り、skip_cleanup: trueの行も追加した。
これでgithubにリリースされるようになった。

このままではすべてのコミットに対してアップロードされてしまうので、tagが付いているときのみdeployするようにした。

.travis.yml
   skip_cleanup: true
   on:
     repo: yohm/x10_sample
+    tags: true

これでtagが新規についた時にだけdeployされるようになる。
例えば、

git tag -a v0.0.1 -m 'version 0.0.1'
git push --tags

を実行すると、そのタグに紐づいた生成物がアップロードされる。

Cacheを利用したビルドの高速化

毎回x10をビルドすると、実行時間がかかるのでTravisのcacheを利用して高速化する。

.travis.yml
cache:
  directories:
  - x10/x10.dist

これでx10.distディレクトリがcacheされる。
注意点として、初回実行時(cacheが無い場合)にも x10/x10.dist に空のディレクトリが作成される。buildx10.shの中での条件判定に気をつける。