この記事は CircleCI Advent Calendar 2018 2日目の記事です。
前回は @miyajan さんの CircleCI Orbs 入門 でした。
TL;DR
- CircleCI の Only build pull requests を
off
にしていると、プルリクエストを作った時に動いて欲しい CircleCI の job を設定できない - そこで GitHub の webhook を利用して、プリリクエストが作られたら CircleCI の Job を実行する serverless アプリ を作って設定した
- CircleCI の Only build pull requests を
off
にした理由 と、作った serverless アプリと設定方法 ついて説明する
Only build pull requests とは
CircleCI には Only build pull requests という設定があります。
名前の通り、プルリクエストが作らられている時だけ CircleCI のビルドが実行されます。
この設定を on
にしておけば、無駄にビルドして CircleCI のキューを圧迫することもなくて良いのですが、私は次の理由で off
に設定しています。
CircleCI の Only build pull requests を off
にする理由
master
ブランチのデプロイを自動化したい
master
ブランチが更新されたらデプロイしたいのですが、master
ブランチからプルリクエストを作ることはないので、 Only build pull requests
が on
になっていると CicleCI のビルドが実行されません。
さっさとテストを実行しておきたい
CircleCI で UT を実行していますが、これが少々時間がかかってしまいます。
なので push したらさっさとテストを実行して、プルリクエストを作る頃にはある程度終わってくれている方が嬉しいです。
Only build pull requests を off
にする弊害
では Only build pull requests を off
にすると万事解決かというと、そうもいきません。
私は次の問題に直面しました。
キューが詰まる
push する度にジョブが実行されるのですから、当然、ビルドのキューが増えて詰まります。
これはお金の力で解決しました
reviewdog が働かない
reviewdog というツールがあります。
これは、 rubocop
や golint
などの静的解析ツールの結果を、GitHubのプルリクエストにコードへのコメントとして登録してくれるツールです。
私はこのツールを使って機械的なコードレビューを自動化しています。↓のような感じです。
ただ、GitHubの プルリクエスト にコメントを登録するツールですから、プルリクエストがなければ機能しません。
しかし Only build pull requests を off にしていると、プルリクエストを作る前に CircleCI のビルドが実行されますから reviewdog を実行するとエラーになってしまいます。
対策として GitHub のプルリクエストが作られたら CircleCI のジョブをAPI経由で実行する仕組みを作ることにしました。
プルリクエストが作られたら reviewdog だけ実行する serverless アプリケーション
というわけで、プルリクエストが作られたら reviewdog だけを実行する仕組みを serverless で作りました。
↓の図の黒い部分です。
作った serverless
アプリの説明
https://github.com/yasuhiroki/serverless-gh-hook-circle-job に公開しています。
AWS を使う前提の serverless です。
CircleCI の API トークンを設定
また、CircleCIのジョブをAPI経由で実行するにはトークンが必要なので取得します。
トークンは User setting -> Personal API tokens から取得できます。
取得したら serverless.yml
に記述して deploy します。
functions:
lint:
handler: index.handler
description: hook circleci job by web hook of github pull-request
events:
- http:
path: circleci
method: post
environment:
CIRCLECI_TOKEN: # ここに取得したトークンを書く
TARGET_JOB: eslint
TARGET_REPO: yasuhiroki/serverless-gh-hook-circleci-job
IGNORE_BRANCHES: master
生トークンを書くことにリスクがあるのであれば AWS KMS を使うと良いですね。
今回の実装では使っていませんが、いずれ対応したいと思います。 1
API Gateway Endpoint を GitHub の webhook に登録
作った API Gateway の URL を GitHub の webhook に登録します。
プルリクエストのイベントだけ Hook されれば良いので、そのように設定しておきましょう。
CircleCI の config.yml を設定
reviewdog は プルリクエストが作られた時にだけ実行してほしいので config.yml を調整します。
プルリクエストが作られていれば環境変数 CI_PULL_REQUEST
に値が入るのでチェックすれば良いですね。
serverless_golang_lint:
steps:
- run:
name: Run golint and reviewdog
command: |
test ${CI_PULL_REQUEST} || exit 0 # プルリクエストが作られていない時は skip
golint ./... | tee golint.txt || true
cat golint.txt | reviewdog -f=golint -reporter=github-pr-review
まとめ
CircleCI の Only build pull requests を off
にした状態で、プルリクエストが作られた時に CircleCI のジョブを実行する方法を serverless で実現してみました。
この方法以外にも、プルリクエストを作った後に適当なcommitをpushして CircleCI のビルドを走らせる方法でも良いかもしれませんね。
CircleCI Advent Calendar の明日の記事は @tomonorimatsumura さんです
-
自社ではKMSを使った実装にしていますが、ハードコーディングされてるので公開できず... ↩