えいのうにっき

a-knowの日記です

自動で・定期的に CI を実行させてリポジトリが "腐る" のを防ぐ with CircleCI

三行で

背景・目的

例えば開発が活発なプロジェクトだと別に問題ないんだけど、そうじゃないプロジェクトの場合、「久々にプルリクエストを作ったら、変更箇所以外のところでテストが通らなくなってる」、みたいなことが稀にあったりする。いわゆる "腐る" 、というやつだ。

せっかくテストを書いていて、変更が入るたびに CI するようにしていても、"変更" そのものがないと CI も動かない。それは、ものすごい勢いで起こっている "プロジェクトを取り巻く外部環境の変化" に、いつのまにか追随できていなくなっていることに気づけない、という状況を生み出す。

これを防ぐ(気づく)ためにはどうすればいいか。...という経緯で、CI を自動で・定期的に実行できるようにしたい、という状況になった。

あ、CircleCI の話、ということで。

方法・しくみ

一言でいうと、"何らかの方法で、 CircleCI に対してビルドするように" できればよくて、きっと色んな方法があるんだろうけど、例えば circleci gem を使うと、↓のように書けばビルドをお願いできる。(CIRCLECI_TOKEN は、ビルド対象の CircleCI プロジェクトのトークン。Scope は all である必要がある。)

require 'circleci'

CircleCi.configure do |config|
  config.token = 'CIRCLECI_TOKEN'
end

CircleCi::Project.build_branch 'username', 'reponame', 'branch'

ぶっちゃけ、今回の目的に対してこの方法はもう、これ以上でも以下でもある必要がなくて、これで十分だったりする。あとはこれを "どこかで" "定期的に" 実行すればいいんだけど、それを heroku と scheduler アドオンで実現しているのがGitHub - masutaka/ci-build-trigger: A trigger of bundle update

github.com

ここでちょっと話を横道に逸らす。

この heroku app 、今回の目的である「単に定期的に CI を実行する」だけのものではなく、「CircleCI を使って定期的に bundle update を実行し、更新があればプルリクエストを作る」というもの。

masutaka.net

仕組み的なところをざっくり触れると、 CircleCi::Project.build_branch は実は下記のように環境変数の指定も可能で、

build_environment_variables = {"ENV_VAR1" => "VALUE1", "ENV_VAR2" => "VALUE2"}
CircleCi::Project.build_branch 'username', 'reponame', 'branch', build_environment_variables

この環境変数は CI 対象のプロジェクトの circle.yml で参照できちゃったりする。GitHub - masutaka/ci-build-trigger: A trigger of bundle updateはそれを利用して、"ある環境変数の値によって、circle.yml の中で処理を切り替える" ことで、CircleCI に bundle update をさせ、更新があればプルリクエストを作る(というシェルスクリプトを実行させる)、ということを行わせている。

test:
  post:
    - >
      if [ -n "${BUNDLE_UPDATE}" -a "${CIRCLE_BRANCH}" = 'master' ] ; then
        bundle update
      fi

本題

話を元に戻す。今回やりたい "単純な CI を、ただ定期的にリクエストするだけ" という目的に対し、上記 heroku app は幾分オーバースペックではあるのだが、heroku button まで設置して頂いているので、有り難くボタンを押させて頂くことにする。ぽちっとな。

heroku にログインした状態であれば、↓のような画面が表示される。

f:id:a-know:20150609212700p:plain

以下のように埋めていく。別に難しい項目はひとつもないんだけど。

  • App name : 上記 heroku app repository の内容を元に、自分の heroku app として新たに立ち上げることになるので、その app の名前を付ける。xxxx-daily-ci とかかな。
  • Region : リージョン。お好きなところを。
  • Add-on : scheduler アドオンが既に選択状態になっている。そのままでok。
  • Config Variables :
    • GitHub username : CI したいリポジトリを持ってる GitHub のユーザー名を。
    • GitHub REPO name : CI したいリポジトリの名前を。
    • BRANCH : 対象ブランチを。普通は master かな。
    • EXEC DAY : 実行する曜日を。何も指定しなかったら毎日動く。

入力できたら Deploy for Free

f:id:a-know:20150609212723p:plain

いぇあ!View ボタンを押しても何もでないので、そこは注意。

その後、README にも書いてあるとおり、 $ heroku addons:open scheduler --app <App Name> をする。と、↓のような画面がひらく。ので、 Add new job ボタンをおす。

f:id:a-know:20150609212754p:plain

これまた README に書いてあるとおりに $ bundle exec ruby ci-bundle-update.rb を scheduler に登録する。各種設定値は良きように。

f:id:a-know:20150609212820p:plain

あとは、指定した時間通りに CI が動き出すのを確認するだけ。タイムゾーンUTC なのでそこだけは頭の片隅に入れておく。

BUNDLE_UPDATE=true環境変数が設定された状態で CI が走るわけだけど、BUNDLE_UPDATE という環境変数さえ使ってなければ、問題なし。

関連

qiita.com



follow us in feedly