Travis CIでビルドのアウトプットを外部に保存する
GitHubプロジェクトのContinuous IntegrationにはTravis CIが便利ですね。Travis CIはビルド中の標準出力(とエラー出力)をログに残してくれるので、ビルドが失敗した場合も原因を調べられるようになっています。しかし、テスト実行中のデバッグログなど、あらゆるものを標準出力に流してしまうと、ビルド失敗時の調査に大変な労力がかかってしまうため、ビルドレポートを外部に保存する方が便利でしょう。本稿では、Travis CIでビルドのアウトプットを外部に保存する方法を説明します。
方針
アウトプットの保存先として下記のような選択肢があります。
いずれにしても、第三者に保存先を勝手に変更されないように、クレデンシャルを適切に管理する必要があります。 リポジトリの設定ファイルに平文でクレデンシャルを書いてしまうと悪用されるおそれがあります。 Travis CIは暗号化をサポートしており、あらかじめ暗号化した文字列を設定ファイルに書いておくと、ビルド実行時に自動的に復号された文字列が環境変数にセットされる仕組みがあります。
ここでは、下記の方針でアウトプットを保存することにしましょう。
実現方法
まず、ビルドレポートを保存するためのリポジトリを作成します。 とりあえずindex.htmlをコミットしておきましょう。
GitHubにHTTPSアクセスするためのトークンを取得します。 Settings - Applications - Personal access tokensでトークンを取得できます。
念のため、取得したトークンでHTTPSアクセスできるか確認しておきましょう。
git remote add test https://ユーザ名:トークン@github.com/example/build-report.git git fetch test
そして、ユーザ名と取得したトークンをそれぞれ暗号化します。travis encryptコマンドを使います。表示された文字列はこのあと設定ファイルに書くのでメモしておきます。
travis encrypt GH_LOGIN=ユーザ名 travis encrypt GH_TOKEN=ユーザ名
.travis.yml
を書きます。Gradleの例を挙げますが、他の言語やビルドツールでも似たようなものになると思います。
language: java jdk: - oraclejdk7 script: - ./gradlew build # 下記でビルドレポートを保存する after_script: - ./.travis.sh publish_report # 先ほど暗号化した環境変数を書く env: global: - TERM=dumb - GH_BUILD_REPORT=example/build-report - secure: "xxx"
.travis.sh
を書きます。概ね下記のことをやっています。
~/.netrc
にクレデンシャルを一時的に書き出す。- メールアドレスと名前をconfigに設定する。
- 保存先のリポジトリをcloneする。下記ではGitHub Pagesのブランチを指定している。
- ビルドレポートをaddする。下記ではブランチ名ごとにフォルダを分けてビルドレポートを保存している。
- ブランチ一覧のファイルを生成する。これはビルドレポート一覧ページを生成する時に便利。
- commit & pushする。
#!/bin/bash -xe function publish_report () { if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then set +x echo "machine github.com" >> ~/.netrc echo "login $GH_LOGIN" >> ~/.netrc echo "password $GH_TOKEN" >> ~/.netrc set -x git config --global user.email 'travis@travis-ci.org' git config --global user.name 'travis' git clone --quiet --branch=gh-pages "https://github.com/$GH_BUILD_REPORT.git" gh-pages cd gh-pages git rm -q -r "$TRAVIS_BRANCH" || true mkdir -p "$TRAVIS_BRANCH" [ -d ../reports ] && cp -a ../reports "$TRAVIS_BRANCH" git add "$TRAVIS_BRANCH" grep "$TRAVIS_BRANCH" branch-list || echo "$TRAVIS_BRANCH" >> branch-list git add branch-list git commit -q -m "Automatically updated by Travis build $TRAVIS_BUILD_NUMBER" git push origin gh-pages rm -v ~/.netrc fi } "$@"
以上により、ビルドが実行されたらビルドレポートがGitHub Pagesに保存されるようになりました。
ビルドを試すときは後で消せるように適当なブランチを作ってpushするようにしましょう。gitリポジトリに保存する場合はclone後の状態を考えてaddしないといけないとかハマることが多いので、意外とS3の方が簡単かもしれません。
おまけ:ビルドレポート一覧ページ
先ほどの例ではbranch-list
というファイルにブランチ一覧を書き出しているため、これを使えば一覧ページを簡単に生成できます。
ここではJavaScriptでさくっと動的生成してみます。
$(function () { var computeTemplate = function (template, branchName) { return template.replace(/BRANCH/g, branchName); }.bind(null, $('.branch-template').html()); $('.branch-template').empty(); $.get('/build-report/branch-list').done(function (branchList) { branchList.split(/[\r\n]+/).filter(function (branchName) { return branchName.match(/\w+/); }).forEach(function (branchName) { $(computeTemplate(branchName)).prependTo('.page>ul'); }); }); });
<h1 class="page-title">Build Report</h1> <ul class="branch-template"> <li>BRANCH branch <ul> <li>Test Report: <a href="/build-report/BRANCH/reports/tests/">Unit Test</a>, <a href="/build-report/BRANCH/reports/server-integration-tests/">Server Integration Test</a> and <a href="https://github.com/gradle-ssh-plugin/build-report/blob/gh-pages/BRANCH/reports/acceptance-test.log">Acceptance Test</a></li> <li>Coverage Report: <a href="/build-report/BRANCH/reports/jacoco/test/html/">Unit Test</a> and <a href="/build-report/BRANCH/reports/jacoco/server-integration-tests/html/">Server Integration Test</a></li> <li><a href="/build-report/BRANCH/docs/groovydoc/">API Document</a></li> </ul></li> </ul>
Gradle SSH PluginのContinuous Integrationでは本稿で説明したような仕組みを導入しており、ビルドレポートが簡単に確認できるようになっています。