目的
- jobの中で別のリポジトリのビルドを実行したい
- 実行した別のリポジトリのビルドの完了まで待機し成功・失敗を判定して次のstepへ進むかどうかを制御したい
どんなとき?
- e2eテスト専用のリポジトリといくつかのマイクロサービスからなるアプリケーションのコード用のリポジトリがあり,いずれかのアプリケーションのリポジトリがpushされるとそこからe2eテストを実行する等
環境設定
-
A
をjobを実行する側のリポジトリ -
B
をjobを実行される側のリポジトリとします
API Permissions からトークンを作成する
- ダッシュボードから
B
のリポジトリの settingsのAPI Permissions
->Create Token
ボタンからトークンを払い出します
払い出したトークンをAリポジトリの環境変数へ登録する
- ダッシュボードから
A
のリポジトリの settingsのEnvironment Variables
->Add Variable
ボタンから先ほど払い出したトークンを環境変数として登録します- 今回は例として
B_REPO_TOKEN
としました
- 今回は例として
- こうすることでトークンを
.circleci/config.yml
へハードコードせずに済みます
jobの設定
-
A
リポジトリの.circleci/config.yml
を書いていきます
.circleci/config.yml
steps:
- checkout
- run:
name: install jq
command: |
# APIのレスポンスを解析するためにjqがあったほうがいいです
apk add --no-cache --update jq
- run:
command: |
base_path='https://circleci.com/api/v1.1/project/<ここに:vcs-type>/<ここは:username>/<ここに:project>'
target_branch='ここにBリポジトリのビルド対象になるブランチ名(大体はmasterが一般的でしょう)'
# Bリポジトリのビルドを実行
build_num=$(wget --header='Accept: application/json' --post-data='' \
"${base_path}/tree/${target_branch}?circle-token=${B_REPO_TOKEN}" -O - 2>/dev/null | jq -r -e '.build_num')
# 特定のjobのみを実行したい場合は build_parameters[CIRCLE_JOB] を指定します
# build_num=$(wget --header='Accept: application/json' --post-data='build_parameters[CIRCLE_JOB]=実行したいjob名' \
# "${base_path}/tree/${target_branch}?circle-token=${B_REPO_TOKEN}" -O - 2>/dev/null | jq -r -e '.build_num')
if [ "$build_num" = "" ]; then
exit 1
fi
# ビルド実行APIはリクエストするとすぐレスポンスが返ってくる非同期なものなのでビルドの状況をポーリングして完了するまで待機
# ループの数はお好みで
for i in `seq 1 10`; do
echo "[Try ${i}] Waiting for build: ${base_path}/${build_num}"
response=$(wget --header='Accept: application/json' "${base_path}/${build_num}?circle-token=${B_REPO_TOKEN}" -O - 2>/dev/null)
if [ "`echo "$response" | jq -r -e '.lifecycle'`" = "finished" ]; then
if [ "`echo "$response" | jq -r -e '.status'`" = "success" ]; then
# ビルドが正常完了したので次のstepに進ませます
exit 0
fi
break
fi
if [ $i -eq 1 ]; then
# ある程度ビルドに時間がかかるようであれば1回目の待機は長い秒数にしておくとAPIの問い合わせ回数が減らせてよいでしょう
sleep 120
else
sleep 15
fi
done
# 終了ステータスを1以外にすることで次のstepに進ませないようにします
exit 1
- run:
name: after B repo build
command: |
echo 'Bリポジトリのビルドが正常に完了したのでそのあとに何かやりたい処理...'
まとめ
ビルドの実行から待機までを別のシェルファイルに切り出して共通化しておくと保守性が高まると思います.
API経由でビルド実行を柔軟に操作できればさまざまシチュエーションで活用できそうですね.