x10のCI環境構築

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

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

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

https://github.com/yohm/x10_sample

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

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

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

```bash: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には以下のように記述する。

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

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

# x10のビルドとテスト実行

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

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

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

```bash: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"セクションに追加される。

```yaml:.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にリリースされるようになった。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/28792/bdb84f06-3c87-e524-b5e9-5dbd6029a82b.png)

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

```diff:.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
```

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

![image.png](https://qiita-image-store.s3.amazonaws.com/0/28792/e1431f36-baa5-5069-fe37-413b6c1e22db.png)

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

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

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

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