LoginSignup
1
1

More than 5 years have passed since last update.

Workflowsに設定されたCircleCIのジョブをAPI経由で叩く方法

Last updated at Posted at 2018-04-25

はじめに

CIツールのスタンダードとなりつつある CircleCIは、Github等のpushをトリガーに設定したCIジョブを実行してくれる便利なツールです。

CircleCIはAPIを公開しています。このAPIによってリポジトリにpushしたりtagの発行がなくてもCIを実行することができます。例えば、複数リポジトリ間のCIトリガーを一括で制御したい!といった場合や、リポジトリ内のコードに変更はないけど、内部でダウンロードしてくるファイルやDockerイメージの中身に変更が生じたためpushせずにテストを回したい!というときに非常に有用です。

しかし、API経由ではCircleCI 2.0で実装されたworkflows機能が働かないということがわかりました。 
というより、workflowsブロックがconfig.ymlに入ったCIをAPI経由で実行すると必ずCIが失敗します。

公式でもそんなことが書いてあります。

Note: It is not yet possible to run Workflows with the API.
https://circleci.com/docs/2.0/api-job-trigger/

この記事ではworkflowsが設定されたCIをAPI経由で実行する方法を共有します。

解決策

CircleCIのAPIではCIの設定単位ではなく、ymlの中で設定されたjob単位でも実行することができます。
この方法だと上記のworkflows問題を回避することができます。

やり方は以下の通り

  • 設定単位
curl https://circleci.com/api/v1.1/project/:vcs-type/:username/:project/tree/:branch?circle-token=${CIRCLE_TOKEN}
  • job単位
curl -d build_parameters[CIRCLE_JOB]=${JOB_NAME} https://circleci.com/api/v1.1/project/:vcs-type/:username/:project/tree/:branch?circle-token=${CIRCLE_TOKEN}

実行例

例として以下のようなconfig.ymlを用意します。
このCIでは必ずjob1が実行され、その後developブランチであればjob2、masterブランチであればjob3が実行されます。

config.yml

version: 2
jobs:
  job1:
    docker:
      - image: circleci/python:3.6.1

    steps:
      - run:
          name: echo1
          command: echo fuwafuwa

  job2:
    docker:
      - image: circleci/python:3.6.1

    steps:
      - run:
          name: echo2
          command: echo mochimochi


  job3:
    docker:
      - image: circleci/python:3.6.1

    steps:
      - run:
          name: echo3
          command: echo pikapika

workflows:
  version: 2
  test-jobs:
    jobs:
      - job1
      - job2:
          requires:
            - job1
          filters:
            branches:
              only: develop
      - job3:
          requires:
            - job1
          filters:
            branches:
              only: master

それではまず、gitのpushをトリガーとしてCIを走らせてみましょう。
masterブランチにpushした結果が以下の通り。

Screenshot from 2018-04-14 14-40-01.png

共通jobのjob1と、masterブランチ限定のjob3が走っていることがわかります。job2はdevelopブランチにpushされたときだけ実行されるので、今回は実行されていません。

API経由で全く同じCIを叩いてみましょう。

curl https://circleci.com/api/v1.1/project/github/smn-ailab/hiranuma_qiita/tree/master?circle-token=${CIRCLE_TOKEN}

下の画像のような結果が出ました。
Screenshot from 2018-04-14 15-04-34.png

ymlのsyntaxエラーのような記述ですね。なにはともあれ、API経由ではworkflowsが設定されたCIは実行できないことが確認できました。

それでは今回のテーマである、job単位での実行をやってみましょう。

curl -d build_parameters[CIRCLE_JOB]=job1 https://circleci.com/api/v1.1/project/github/smn-ailab/hiranuma_qiita/tree/master?circle-token=${CIRCLE_TOKEN}

画面を確認してみると、、
Screenshot from 2018-04-14 15-15-59.png

動作できています!
これでworkflowsを無視してAPIからjobを実行できました!

おまけ: APIでworkflowsの挙動を再現してみた

workflows の機能が使えないため、jobの依存関係を呼び出し側で制御する必要があります。
buildのstatusを参照するAPIを使って依存関係を書いてみます。

依存関係を再現.sh
BUILD_NUM=`curl \
          -d build_parameters[CIRCLE_JOB]=job1 \
          https://circleci.com/api/v1.1/project/github/smn-ailab/hiranuma_qiita/tree/master?circle-token=${CIRCLE_TOKEN} | jq -r '.build_num'`


while true
do
  STATUS=`curl -s -S https://circleci.com/api/v1.1/project/github/smn-ailab/minerva-analysis/${BUILD_NUM}?circle-token=${API_TOKEN} | jq -r '.status'`
  if [ ${STATUS} = "success" ]; then
    echo ${STATUS}
    break 
  elif [ ${STATUS} = "failed" ]; then
    echo ${STATUS}
    exit 1
  else
    echo ${STATUS}
    sleep 60
  fi  
done

curl \
-d build_parameters[CIRCLE_JOB]=job3 \
https://circleci.com/api/v1.1/project/github/smn-ailab/hiranuma_qiita/tree/master?circle-token=${CIRCLE_TOKEN}

CIを実行するAPIでは、返り値としてBuildの情報がjson形式で返ってきます。
ここではCIを実行すると同時にBuild番号を受け取り、番号を元にAPIを叩いて該当BuildのStatusを確認しています。$STATUSが"success"であれば、次のBuildを走らせるcurlコマンドの部分へ移行し、failedであればその時点でシェルは終了します。それ以外の場合は1分待ってから再度STATUS確認に移ります。このようにすればjobの依存関係を再現できます。

おわりに

今回ご紹介した方法ではworkflowsの設定を一切無視するので、branches: only master としているjobをdevelopブランチで実行することも出来てしまいます。
使用する際はご注意下さい。

1
1
0

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
1
1