2018年8月14日火曜日

依存ライブラリの GitHub を Travis CI で定期的に監視して DockerHub Automate Build を実行する(+ Codefresh ジョブを Trigger)

目的
開発中のソフトウェアがなんらかのソフトウェアに依存しており、その依存しているソフトウェアの最新の状態を常に追いたい。
具体的には、筆者が開発中の C++ テスティングフレームワーク iutest は、Google Test との互換性のために常に Google Test の最新の状態と互換性テストを行っています。

iutest では Travis CI や Circle CI といった CI サービスを利用して、変更があるたびにテストが行われる環境が整っています。
しかしながら、iutest は毎日更新があるわけではなく、最近は開発スピードも落ちているので数日変更がないこともザラです。
そのため、その間に Google Test に更新があって、いつの間にか互換性テストが通らない状態になっていたりすることがありました。

長くなりましたが、今回のゴールは
・ Google Test の更新を定期的に監視して
・ 変更があったら Docker image を更新
・ Docker image が更新されたら互換性テストが実行される
です。

構成

* 監視されるリポジトリ→ google test
* 監視するリポジトリ→docker-googletest


DockerHub Automate Build
DockerHub で Google Test の入ったイメージを作成するジョブは以下の記事で作成したものを使用します。
ブログズミ: DockerHub Automated Build を使ってみた

今回はこちらの latest イメージを毎日最新の状態にするのが目的です。
DockerHub に定期ビルド機能があればそれで良かったのですが、ないので別のサービスで実現させます。

次へ進みます。

CI の設定
必要なのは、定期ビルドが可能で、GitHub に push できるサービスです。
今回は Travis CI を使いましたが、選んだ理由は最近 GitHub push をここでやったからです。
実際使用している yml はこちらです。こちらを見ながら説明していきます。
dist: trusty
sudo: false
language: cpp

before_script:
  - git clone https://github.com/google/googletest.git ./gtest
  - cd ./gtest
  - git rev-parse HEAD > ../gtest.hash
  - cd ..

script:
  - git checkout master
  - git add -A
  - git commit -m "update head [ci skip]" || true
  - git push https://${GITHUB_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git ${TRAVIS_BRANCH}

env:
  global:
    secure: OdxIMgUsZyGyOOnV49MkJW5KrGVW7KyCwUkWgC88YmdJPCtNJ9fF69TcM8ek252+yFJsfpUrZaNH6A6igRUreveoA161zy+fsD9mMqIrrthFWx5S2fzBCsiCobreduicCDt5EJ1p8N/QlpEB2ZeUbYWqZf37r5BfYOJI86521qYMiI30IAwxsjPqhcbyFRisTKosd3LlEo4Y+K3qLgdCKEAhsaOrtIgrbxz7cM2sKh8lYTquP1XPtFwsmCoELyeRAVEJbSwADcaw3011S/NB8Kn9+sd878dxBK2iDxSilVz+3XIz+/sKZHNFGug5i2UA2yS8ZfWQhZjF9tiF3quTAzqAFzTbxDKswMLHgD8oI0saIVDmXNxc6PXLYXEjx5p5Z3E1iTb09hcp5wOqJOz+Ynie7EkVyUO2DKJhjeuGffoPxjK35L4c7/ufTNskT3+vUnGG/2U9XMA3OeXoCLp+V7BRgkZtpVZssA4viTWXPG4byaEQaiAMK0ArVOesa86m21xuKSLhdNqQ/WRT8g/eEVqs4XrT1ogIW1nsjYHv6Xmcs8QD2iQxDdWHx4pQojod8lSdwn/HFqXTOf6KxqTk5mpJmcd2ZxyDocynTEtvtt+uNtVyJh+gXt06eGD/rlbV1eC+Uc5FMQE2P1Uya3RdaZvMZjYGzVcZMrPcv/gklbY=

Google Test の更新検知
まずは肝心の Google Test (監視される側)の更新検知方法です。
いろいろやり方はあると思いますが、今回は push があるたびにトリガーするのではなく、定期的に(1日1回とか)更新があったかどうかがわかればいいので、定期ビルド実行したときの Google Test の HEAD の commit hash を自分のリポジトリに保存する方法を取りました。
更新があれば diff が出るので、これをトリガーにしています。
これを行っているのが、brfore_script の部分になります。

更新を push して他サービスをトリガーする
最新の commit hash を取得したら、それを commit/push します。
docker-googletest (監視する側)のリポジトリが更新されるので、この push をトリガーに他のサービスをキックすることができます。
監視する側のリポジトリは自身の管理下のはずなので、ここから先は自由にやることができます。

ただし、ここで注意点があります。
Travis CI のジョブもこの push をトリガーにより実行されてしまいます。
すると、この Google Test 監視ジョブが再実行されてしまい、最悪の場合は無限にジョブをキックし続けます。(監視される側の更新が止まれば止まるが、最低でも1回無駄にジョブが走る)

定期ビルド設定
最後にこれを定期ビルドするようにしましょう。
こちらは Travis CI の Web ページで設定します。
プロジェクトのページの「More options」から「Settings」を開くと、一番下に Cron Jobs があります。



DockerHub Automate Build の設定
特に必要ありません。
Google Test が更新されると、commit hash が更新されて push されるのでそれをトリガーにビルドが実行されます。

おまけ
ここまでで、当初の目的の GitHub の監視と、変更検知し DockerHub のビルドを回す、という目的は達成していますが、ついでなので、その先も紹介します。

Slack 通知
通知系は定番ですね。詳しくは過去にも記事にしているので、そちらを見てくださいmm
ブログズミ: Dockerhub Automated Build が終わったら Slack に通知する

docker-googletest の通知仲介は Zapier を使ってますが、今は Integromat もおすすめです。
そちらも記事にしているので、よければご覧ください。私的には、今後は IFTTT/Zapier よりも Integromat をメインに使っていくつもりです。

* 「ブログズミ: プレビュー "(WIP)依存ライブラリの GitHub を Travis CI で定期的に監視して DockerHub Automate Build を実行する(+ Codefresh ジョブを Trigger)"
* 「ブログズミ: CIサービスの結果を Twitter に投稿する

Codefresh のジョブを Dockerhub からの Webhook で実行する
Codefresh のトリガーに Webhook トリガーを追加します。
プロジェクトの「Pipeline」ページの真ん中あたりに「Triggers」があるので、そこで追加していきます。


「ADD TRIGGER」ボタンを押すと以下のようなウィンドウが出てくるので、「REGISTRY」を選択して次へ


続いて、「REGISTRY PROVIDER」を Dockerhub に、「NAMESPACE」と「NAME」はトリガーを発行したい Dockerhub のリポジトリを設定してください。
「ACTION」は Image 更新したときにしたいので、 「Push Image」を選択。docker-googletest にはバージョンごとのタグが複数あり、ビルド対象にしたいのは latest だけだったので、「Configure filter」を設定しました。
入力完了したら、「NEXT」ボタンを押します。


四角く囲ったところに、Webhook の URL と鍵が発行されますので、Dockerhub の Webhook に設定します。(下線のリンクから飛べます)


Dockerhub の Webhook 設定を開いたら、${ENDPOINT}&secret=${SECRET KEY} を入力します。(↑の黄色で囲った部分に出てるアドレスです)



これで完成です。


最後に
外部の依存・関係しているプロジェクトが、いつの間にか更新されていて動かなくなっていた。なんてことはよくあることなので、定期的に監視しておくのはいいことだなと思いました。
あと、この仕組がわりといい感じに組めた気がするので、iutest の Google Test 互換性テストを外部に出す対応に利用しようと思います。
では。

0 件のコメント:

コメントを投稿