Cloud Build から Code Climate にテストレポートを送信する
Cloud Build から Code Climate にテストカバレッジを含むテスト結果を送信しようとしたところ、ひと手間必要だったので、その手順を紹介します。
Code Climate Test Reporterの実行方法
Getting Started にあるように、Test Reporter のバイナリをダウンロードして実行することで、Code Climate にテスト結果を送信できます。
Linux 環境であれば、Git リポジトリ内で下記のコマンドを実行します。 (事前に Code Climate 側でリポジトリの設定とトークンの発行をしておく必要があります)
# 実行ファイルの取得 curl -L \ https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 \ ./cc-test-reporter chmod +x ./cc-test-reporter # 実行前の準備 ./cc-test-reporter before-build # テスト結果の送信(SimpleCovの場合) CC_TEST_REPORTER_ID=XXXXXXXXXXXXXXX ./cc-test-reporter after-build -t simplecov
今回はテストレポートを SimpleCov で出力したため -t simplecov
としていますが、このオプションはテスト環境に応じて置き換えてください。
Cloud Buildでの実行
GitHub から Cloud Build への連携は GitHub Apps として Cloud Build に登録しておきます。
Cloud Build で実行する場合も手順は変わりませんが、Cloud Build で取得されるリポジトリには .git
ディレクトリが含まれていないことに注意する必要があります。
cc-test-reporter
は実行時に、Git リポジトリの下記の情報を利用しています。
- ブランチ名(
GIT_BRANCH
) - コミットハッシュ(
GIT_COMMIT_SHA
) - コミットタイムスタンプ(
GIT_COMMITED_AT
)
.git
ディレクトがないとこれらの情報が取得できないので、手動で与えるか、別の手段で .git
ディレクトリを取得する必要があります。
手動で与える場合
手動で必要な情報を与える場合は、下記のスクリプトのように GIT_COMMITED_AT
を手動で与える必要があります。
今回は .git
ディレクトリがなく本来のコミットタイムスタンプを取得でないため、現在時刻を代わりに与えています。
なお、このタイムスタンプは Unixtime で与える必要があります。
#! /bin/sh set -ex curl \ -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 \ > ./cc-test-reporter chmod +x ./cc-test-reporter GIT_COMMITTED_AT=$(date +%s) ./cc-test-reporter $@
このスクリプトを使う場合の、cloudbuild.yml
は下記のようになります。
steps: # テスト用のイメージのビルド - name: gcr.io/cloud-builders/docker args: - build - -t - gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA - . # Test Reporter実行前の準備 - name: gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA dir: /app entrypoint: sh args: - scripts/test_report.sh - before-build # テストの実行 - name: gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA dir: /app args: - bundle - exec - rake - spec volumes: - name: coverage path: /app/coverage # テスト結果の送信 - name: gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA entrypoint: sh dir: /app args: - scripts/test_report.sh - after-build - -t - simplecov env: - CC_TEST_REPORTER_ID=XXXXXXXXXXXXXXX - GIT_COMMIT_SHA=$COMMIT_SHA - GIT_BRANCH=$BRANCH_NAME volumes: - name: coverage path: /app/coverage
GIT_COMMIT_SHA
と GIT_BRANCH
は Cloud Build でのビルド実行時に変数として与えるために変数名を変えて与えています。
一応、結果は送信されているようですが、コミットタイムスタンプに適当なものを与えている点が気になります。
.git
ディレクトリを取得する場合
.git
ディレクトリなしでパラメーターを与える場合、どうしてもコミットタイムスタンプなどのリポジトリ固有の情報を取得できません。
コミットタイムスタンプの正しい値を取得するためには、Git リポジトリの情報(.git
ディレクトリ)が必要になります。
これを取得するアプローチを取った cloudbuild.yml
は次のようになります。
steps: # リポジトリの取得 - name: gcr.io/cloud-builders/git dir: /git args: - clone - https://github.com/user/repo.git - . volumes: - name: git path: /git # コミットタイムスタンプをボリュームに書き出す - name: gcr.io/cloud-builders/git entrypoint: sh dir: /git args: - -c - "git show -s --format=%ct $COMMIT_SHA > /git/timestamp" volumes: - name: git path: /git # テスト用のイメージのビルド - name: gcr.io/cloud-builders/docker args: - build - -t - gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA - . # Test Reporter実行前の準備 - name: gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA dir: /app entrypoint: sh args: - scripts/test_report.sh - before-build volumes: - name: git path: /git # テストの実行 - name: gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA dir: /app args: - bundle - exec - rake - spec volumes: - name: coverage path: /app/coverage # テスト結果の送信 - name: gcr.io/$PROJECT_ID/$REPO_NAME:$SHORT_SHA entrypoint: sh dir: /app args: - scripts/test_report.sh - after-build - -t - simplecov env: - CC_TEST_REPORTER_ID=XXXXXXXXXXXXXXX - GIT_COMMIT_SHA=$COMMIT_SHA - GIT_BRANCH=$BRANCH_NAME volumes: - name: coverage path: /app/coverage - name: git path: /git
この処理では、git
コマンドが使えるコンテナ内でリポジトリを取得し、以降の処理で必要になる情報をボリュームにファイルとして書き出しています。
このようにすることで、リポジトリのコミット情報を以降の処理で再利用できます。
リポジトリの情報であれば同様の手順で利用できるので、例えばコミットメッセージを利用したい場合は下記のステップを追加することで実現できます。
steps: # コミットメセージをボリュームに書き出す - name: gcr.io/cloud-builders/git entrypoint: sh dir: /git args: - -c - "git log --format=%B -n 1 $COMMIT_SHA > /git/message" volumes: - name: git path: /git
取得した値の参照は下記のようなスクリプトで利用できます。
#! /bin/sh set -ex curl \ -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 \ > ./cc-test-reporter chmod +x ./cc-test-reporter GIT_COMMITTED_AT=$(cat /git/timestamp) ./cc-test-reporter $@
まとめ
CI サービスでは、.git
ディレクトリがないためリポジトリに関する情報を CI で再利用しにくいことがあります。
Cloud Build では上記の手順でボリュームに一時的に書き出すことでリポジトリの情報を利用できます。