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

golangでTravis CIを使ってクロスコンパイルするときにハマったところ #golang #travisci

今回作った↓のツールでCIサービスはTravis CIを利用しましたが、多少ハマったところがあるのでメモしておきたいと思います。

github.com

uchimanajet7/rds-try - Travis CI

https://travis-ci.org/uchimanajet7/rds-try

まずはテストから 

こちらを参考にというか、ほぼそのまま使い動作を確認してみました。

CI-as-a-ServiceでGo言語プロジェクトの最新ビルドを継続的に提供する | SOTA

http://deeeet.com/writing/2014/10/16/golang-in-ci-as-a-service/

大きな変更をしないでも実際に動かしてみて動きました。

やはり動作済みのサンプルを公開しているのは便利でいいなーと思いました。

唯一の修正は「go get code.google.com/p/go.tools/cmd/cover」→「go get golang.org/x/tools/cmd/cover」でした。

今回作ったもので実行

テストしたことで大体わかったので、次は実際に作った物で実行してみることに。

するとまず以下のエラーが!

- go test -v -covermode=count -coverprofile=coverage.out ./...

 cannot use test profile flag with multiple packages error

何だこれは?Googel先生に聞いてみました。

mlafeldt.github.io

ふむふむ。なんか複数のパッケージをまとめて実行できない模様。パッケージを個別に指定しないといけないとな!わかりました変更しましょう

go test -v -covermode=count -coverprofile=main.cover.out -coverpkg=./... github.com/uchimanajet7/rds-try
go test -v -covermode=count -coverprofile=utils.cover.out -coverpkg=./... github.com/uchimanajet7/rds-try/utils
go test -v -covermode=count -coverprofile=query.cover.out -coverpkg=./... github.com/uchimanajet7/rds-try/query
go test -v -covermode=count -coverprofile=logger.cover.out -coverpkg=./... github.com/uchimanajet7/rds-try/logger
go test -v -covermode=count -coverprofile=config.cover.out -coverpkg=./... github.com/uchimanajet7/rds-try/config
go test -v -covermode=count -coverprofile=command.cover.out -coverpkg=./... github.com/uchimanajet7/rds-try/command

これでこのエラーは解消したんですが、今度はカバレッジファイルが複数出来たのでこれを1つにまとめないと駄目なので。

ls | grep cover.out | xargs cat | grep -v mode: | sort -r >> coverage.out

な感じで手元のMacで実行して問題ないのでTravis上で実行してみると・・・あれ?Travisが動かない??設定画面を見てみると「missing config」の表示がっ!どうやらtravis.ymlに間違えがある模様。

細かいロードログが見られないしどうしようかと思ってたら以下のサイトを発見。いやー助かりました。

Validate your .travis.yml file

http://lint.travis-ci.org/

いろいろ変更しながらチェックしてるとどーやらこの1行がおかしいらしい

ls | grep cover.out | xargs cat | grep -v mode: | sort -r >> coverage.out

手元で動いてるのになんでだろうなぁーっと思ってたら”:”がダメっぽい?こうしたら問題なく動いたのでまーいいかなと

ls | grep cover.out | xargs cat | grep -v ”mode:” | sort -r >> coverage.out

たったこれだけ!これだけが分かるのにどんだけかかったのか・・・

これで終わったかと思いきや次は↓でエラーがっ!

go tool cover -func coverage.out

どーやら入力ファイルの形式が正しくない様子。1行目に「mode: count」のようなモード指定がないのでダメな予感が。なので1行目に↓を追加することにしました。

echo "mode: count" > coverage.out

が、やっぱりエラーが出るのしRuby力が0なので、このタイミングでYAMLについて調べてみました。

Rubyist Magazine - プログラマーのための YAML 入門 (初級編) 

http://magazine.rubyist.net/?0009-YAML#l4

なるほど。ハッシュとして処理されるので変なエラーが出るんだと納得。なので以下の形で対応してみました。2行とかちょっとアレですが・・・

echo -n "mode:" > coverage.out
echo " count" >> coverage.out 

これも "mode: " のようにハッシュとしてパースされる形だとエラーになるので、" count" にしてあったりします。

これでようやくエラーが出なくなったので無事にビルドが終わりリリースされるわけですが、zipにしないとなぁーと言うことで以下を追加しました。

cd _pkg
find . -maxdepth 1 -mindepth 1 -type d -exec zip -r {}.zip {}/ \; 

出力先ディレクトリに移ってるのは、{} が展開されれるとフルパスになるみたいでそのままのディレクトリ構造でzipになるので、それを避けるためです。

最後にghrを使ってリリースするときにタグを打ちたいわけですが、最初は↓のような感じで書いてましたが結局は静的ファイルを置くことで対応しちゃいました。

TAG=`curl -v "https://api.github.com/repos/uchimanajet7/rds-try/tags" | grep name | awk 'NR==1' | awk '{gsub(/\"/,""); gsub(/,/,""); print $2}’`

まとめ 

エラーはいろいろとありましたが、いい勉強になりました。

そしてRuby力がゼロなのは今回本当に困りました。もうちょっと精進しないとです。

golangのテストで複数パッケージの実行に対応していないのは、ちょっとびっくりしましたが、これもどこかでカイゼンされそうですね。

次の機会にはWerckerを使ってみたいなーと思いました。

wercker.com