LoginSignup
8
6

More than 3 years have passed since last update.

circleciのAPIを使って別リポジトリのビルドを実行する

Last updated at Posted at 2018-12-03

目的

  • jobの中で別のリポジトリのビルドを実行したい
  • 実行した別のリポジトリのビルドの完了まで待機し成功・失敗を判定して次のstepへ進むかどうかを制御したい

どんなとき?

  • e2eテスト専用のリポジトリといくつかのマイクロサービスからなるアプリケーションのコード用のリポジトリがあり,いずれかのアプリケーションのリポジトリがpushされるとそこからe2eテストを実行する等

環境設定

  • A をjobを実行する側のリポジトリ
  • B をjobを実行される側のリポジトリとします

API Permissions からトークンを作成する

  • ダッシュボードから B のリポジトリの settingsの API Permissions -> Create Token ボタンからトークンを払い出します スクリーンショット 2018-12-03 22.34.18.png

払い出したトークンをAリポジトリの環境変数へ登録する

  • ダッシュボードから A のリポジトリの settingsの Environment Variables -> Add Variable ボタンから先ほど払い出したトークンを環境変数として登録します
    • 今回は例として B_REPO_TOKEN としました
  • こうすることでトークンを .circleci/config.yml へハードコードせずに済みます スクリーンショット 2018-12-03 22.39.12.png

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経由でビルド実行を柔軟に操作できればさまざまシチュエーションで活用できそうですね.

8
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6