はじめに
みなさんはCIツールに何を導入されていますか?
現在、アイスタイルではかねてから利用しているJenkinsの他に、Atlassian Bambooを一部のプロジェクトで利用し始めております。
そんなBambooなのですが、Go言語の自動テスト及びカバレッジが表示できるようにしてみようとしたところ、色々とハマりどころがありましたので備忘録も兼ねて紹介したいと思います。
なお、Bambooについて特に詳しいわけでもなんでもありませんので、有識者の皆様に、至らぬ点は教えていただけるとありがたいと思います。
テスト対象
今回はテスト対象として、すでにテストとカバレッジがそれぞれTravis CIとCOVERALLで担保されている弊社製のライブラリ、gomniを使いたいと思います。ちなみに、gomniは弊社でのGoプロダクト開発においてよく使われる共通関数を集めたライブラリです。
Bamboo上で設定していく
今回はBamboo自体の細かな説明は省略しますが、Bambooでビルドするにあたっては、
- Plan(ビルドプロセス)
- Project(Planを束ねたもの)
といったものを作る必要があります。
今回はプロジェクトとして色々試せるように用意したサンドボックスプロジェクトに、「テストとカバレッジレポート」というPlanを作成して作業していきます。
事前インストール
Bambooがインストールされているサーバーに事前に以下のものをインストールしておきます
cobertura-clover-transformがなぜ必要なのかは後ほど
ソースコードのチェックアウトタスクを修正
Planを作成するタイミングで、ソースコードのチェックアウトを行うタスクはPlanに追加されていると思いますので、選択し一部の設定の修正を行います。
弊社ではGoプロダクトのビルドを行うにあたって、GOPATHは各Projectのワーキングディレクトリ直下にgo/src
を作成して設定していますので、ここでCheckout Directory
の欄にgo/src/github.com/istyle-inc/gomni
と入力しています。
お使いの環境でGOPATHを別なディレクトリにしたい場合は、そこに合わせて設定してあげてください。
テストとカバレッジレポートを作成するスクリプトタスクを追加
ソースコードのチェックアウト先を適切に設定したところで、テスト実行とカバレッジレポートの作成をするためにスクリプト実行のタスクを追加します。
ちなみに、Bamboo用のGo言語に関するプラグインを検索すると
github.com/edwinakatosh/go-bamboo-plugin というのが出てくるのですが、以下の事由から社内のGoプロジェクトのビルド環境に合致しないため今回は使用しません。
- 依存関係解決を行うタスクが追加できるが、Godepのみの対応となっている
GOPATH
でなくGOROOT
を必須パラメータとしている
さて、スクリプト実行タスクを追加したら以下のようなスクリプトを挿入します
export GOPATH={bamboo.build.working.directory}/go
export PATH={PATH}:{GOPATH}/bin
go get github.com/modocache/gover
go get github.com/t-yuki/gocover-cobertura
cd{GOPATH}/src/github.com/istyle-inc/gomni
glide install
rm -f *.cover.coverprofile
go test -v -covermode=count -coverprofile=numerics_float32.cover.coverprofile github.com/istyle-inc/gomni/numerics/float32
go test -v -covermode=count -coverprofile=numerics_float64.cover.coverprofile github.com/istyle-inc/gomni/numerics/float64
go test -v -covermode=count -coverprofile=numerics_int.cover.coverprofile github.com/istyle-inc/gomni/numerics/int
go test -v -covermode=count -coverprofile=numerics_int16.cover.coverprofile github.com/istyle-inc/gomni/numerics/int16
go test -v -covermode=count -coverprofile=numerics_int32.cover.coverprofile github.com/istyle-inc/gomni/numerics/int32
go test -v -covermode=count -coverprofile=numerics_int64.cover.coverprofile github.com/istyle-inc/gomni/numerics/int64
go test -v -covermode=count -coverprofile=numerics_int8.cover.coverprofile github.com/istyle-inc/gomni/numerics/int8
go test -v -covermode=count -coverprofile=numerics_uint16.cover.coverprofile github.com/istyle-inc/gomni/numerics/uint16
go test -v -covermode=count -coverprofile=numerics_uint32.cover.coverprofile github.com/istyle-inc/gomni/numerics/uint32
go test -v -covermode=count -coverprofile=numerics_uint64.cover.coverprofile github.com/istyle-inc/gomni/numerics/uint64
go test -v -covermode=count -coverprofile=numerics_uint8.cover.coverprofile github.com/istyle-inc/gomni/numerics/uint8
go test -v -covermode=count -coverprofile=strings.cover.coverprofile github.com/istyle-inc/gomni/strings
go test -v -covermode=count -coverprofile=times.cover.coverprofile github.com/istyle-inc/gomni/times
go test -v -covermode=count -coverprofile=types.cover.coverprofile github.com/istyle-inc/gomni/types
gover
gocover-cobertura < gover.coverprofile > cobertura.xml
cobertura-clover-transform cobertura.xml > clover.xml
rm -rf {bamboo.build.working.directory}/target
mkdir -p{bamboo.build.working.directory}/target/site/clover
go tool cover -html=gover.coverprofile -o {bamboo.build.working.directory}/target/site/clover/index.html
cp clover.xml{bamboo.build.working.directory}/target/site/clover/clover.xml
スクリプトを解説
1,2行目はGOPATHやPATHを設定しています。
4,5行目
go get github.com/modocache/gover
go get github.com/t-yuki/gocover-cobertura
github.com/modocache/gover は拡張子.coverprofile
のファイルをすべて集約して一つのファイルに吐き出すツール、github.com/t-yuki/gocover-coberturaはgoのカバレッジプロファイルをcoberturaが読み取れる形式に変換してくれるツールです。事前にインストールしておいたcobertura-clover-transformと組み合わせるために利用します。
7-9行目
cd ${GOPATH}/src/github.com/istyle-inc/gomni
glide install
rm -f *.cover.coverprofile
依存関係の解決と、カバレッジプロファイルを前回のものが残っているケースや、誤ってコミットされてしまっている可能性を考慮し、念のため削除します。
11-24行目ではライブラリ内の各パッケージについてテストを実行しています。ご存知かと思いますが、カバレッジを出力する場合に複数のパッケージをワンライナーでテストしようとするとエラーが出力されてしまうので、それぞれ別なレポートファイルに出力するよう記述していきます。
26-29行目
gover
gocover-cobertura < gover.coverprofile > cobertura.xml
cobertura-clover-transform cobertura.xml > clover.xml
先程のgover, gocover-cobertura, cobertura-clover-transformを実行しています。
※ gocover-cobertura -> cobertura-clover-transformとする理由
Bambooには、Goのカバレッジプロファイルにきれいに対応されているカバレッジレポートツールがまだ無いので、Bambooに標準搭載されているCloverを使ってなんとか対応しようと思いましたが、Cloverに対応するカバレッジプロファイルを出力するツールも特にない(個人的に開発中ではありますが)状況でした。
ひとまず、goprofile -> cobertura用のXML -> Clover用のXML
という経路で変換することで確認までこぎつけています。
最後に31-34行目
rm -rf {bamboo.build.working.directory}/target
mkdir -p{bamboo.build.working.directory}/target/site/clover
go tool cover -html=gover.coverprofile -o {bamboo.build.working.directory}/target/site/clover/index.html
cp clover.xml{bamboo.build.working.directory}/target/site/clover/clover.xml
ここでは最終的にCloverのレポートを使ってカバレッジを表示させたいので、ワーキングディレクトリの下に
target/site/clover
ディレクトリを作成し、その配下に
- clover用のXML(clover.xml)
- coverツールを利用して出力できるHTMLファイル(index.html)
を配置しています。このディレクトリがtarget/site/clover
である理由は後述します。
Jobの設定でCloverを有効にする
ここまで来たらもう一息です。
Jobの設定画面の右側にあるMiscellaneous
タブの設定をします。
この画面で以下の設定を行います。
Use Clover to collect Code Coverage for this build.
のチェックボックスをONIntegrationOptions
の項目にある、Clover is already integrated into this build and a clover.xml file will be produced.
ラジオボタンを選択Clover XML Location
の欄にtarget/site/clover/clover.xml
を入力
保存したらいよいよ実行です。
Run plan
をクリックしましょう!
結果を確認する
正常にスクリプトが実行されたら、Planのトップページを表示しましょう。
Clover
というタブがPlan summary
のタブがあるエリアの右側にあると思いますので、そこをクリックしてください。
無事カバレッジ率が表示されています。
続いて、画面中ほどにClover Report (System) HTML
というリンクが表示されていると思いますのでクリックしてみましょう。
無事カバレッジ表示のHTMLまで表示されていると思います。
レポート出力先をtarget/site/clover
にする理由
先程レポートファイルの出力先をtarget/site/clover
にする旨を記載しましたが、これはカバレッジのHTMLファイルを出力するのに必要な手順でした。
カバレッジの%表示については、先の手順にてJobのMiscellaneous
ページで設定したClover XML Location
が参照されるのでどこに出力しても問題なく表示されますが、HTMLについてはこのtarget/site/clover
配下のディレクトリを参照しに行っているようで、実際のところClover XML Location
に設定するパスはファイルさえ正常に出力されさえすれば任意の場所を指定してかまわないのですが、HTML表示までしたいという場合はtarget/site/clover
ディレクトリが必要になるということでこのようにしています。
なお、target/site/clover
配下を再帰的に参照しに行っているようなので、配下にディレクトリを作成してもかまわないのですが、index.htmlとして作成しておかないと、最初から表示されるようにはならないということだけ注意していただければと思います。
終わりに
いかがでしたでしょうか?
個人的にドキュメントや前例を検索してみた限りの感想を申し上げると、皆さんがGoでの開発プロジェクトをBambooでインテグレーションすることはほぼ無いかもしれませんが、利用することになったときに参考になれば幸いです。
ここまでご覧いただきありがとうございました!