生産性向上ブログ@miyajan

圧倒的生産性向上を目指すエンジニアのためのブログ

CircleCI 2.0 で定期実行ジョブ(Nightly Builds)を実現する

今回は、CircleCI の小ネタです。

CI を行っていると、cron 的な定期実行ジョブを実現したいときがあります。例えば、毎回実行される CI/CD に入れるには重すぎる、セキュリティチェックや性能検証などを夜間にデイリーで実行したいような場合です。今回は、CircleCI 2.0 で定期実行ジョブを実現する方法について書きます。

CircleCI 1.0

まず、これまでとの比較のために CircleCI 1.0 のときにどうやって実現していたかを書きます。CircleCI 1.0 のときは、公式ドキュメントの Nightly Builds というページに定期実行ジョブを実現する方法が書かれていました。

https://circleci.com/docs/1.0/nightly-builds/

簡単に3行でまとめると、

  1. 自前で cron (もしくは AWS Lambda とか) を用意
  2. ビルドスクリプト内で環境変数で条件分岐
  3. 自前 cron から環境変数を指定してビルドを実行するAPIを定期的に叩く

となります。

CircleCi 2.0

まず、現時点では1.については変わっておらず、これまで通り自前で cron の役割を果たすものを用意する必要があります。

2.については、2.0 では複数のジョブを定義できるようになったので、めんどくさい条件分岐を書かなくてもよくなりました。

version: 2
jobs:
  build:
    docker:
      - image: buildpack-deps:trusty
    steps:
      - run:
          command: echo 'build'
  nightly-build:
    docker:
      - image: buildpack-deps:trusty
    steps:
      - run:
          command: echo 'nightly-build'

上記のように書くと、通常コミット時は build で定義されたジョブだけが実行されます。

nightly-build で定義されたジョブを実行するためには、ジョブ名を指定して API を叩きます。この方法については、新しくドキュメントが用意されています。

https://circleci.com/docs/2.0/api-job-trigger/

今回の場合、curl で以下のように叩くと nightly-build ジョブのみが実行されます。

curl -u ${CIRCLE_API_TOKEN}: \
     -d build_parameters[CIRCLE_JOB]=nightly-build \
     https://circleci.com/api/v1.1/project/github/miyajan/circleci-2.0-nightly-build/tree/master

AWS Lambda なりで上記のコマンドを定期実行させるようにすれば、CircleCI 2.0 で定期実行ジョブが実現できます。

APIのトークン作成は、プロジェクトの設定画面の Permissions -> API Permisions から作成できます。

f:id:miya-jan:20170723165125p:plain

Scope は All を選択しないとビルドをトリガできないです。

f:id:miya-jan:20170723165137p:plain

ちなみに、CircleCI 2.0 には Workflows というパイプライン的なフローを実現する機能がありますが、残念ながら API 経由だとこの機能は使えません。

https://discuss.circleci.com/t/workflows-job-build-not-found/13549

定期実行ジョブでそこまで複雑なフローを組むことはあまりないとは思いますが、注意が必要です。

まとめ

CircleCI 2.0 で定期実行ジョブを実現する方法について説明しました。

大まかな流れは 1.0 のときと変わらないですが、ジョブを複数定義できるようになったので 2.0 の方が自然に定期実行ジョブを記述できるようになったと思います。

CircleCI 側が Travis CI の Cron Jobs のような定期実行ジョブの仕組みを作ってくれるのが一番望ましいのですが、計画としてはあるようなので、今はこれまで通り自力で API を叩く運用で回避するしかなさそうです。