tl;dr
- TravisCIとCircleCIの根底にある違いの考え方を理解すると早い。
- そして、違いを考慮しているproductを使うと便利。
考え方
CircleCI
- pushされたbranchをビルドする。
TravisCI
- pushされたbranchをビルドする。
- pull requestのbranchを、仮にmasterにmergeしてみて、ビルドする。
仮にmasterにmergeしてみて??
TravisCIの二つ目のがわかりにくくて、混乱する。 やっていることは正しいんだけど、挙動が直感から外れるので、 TravisCIヘビーに使っているユーザーにもわりと意味不明挙動扱いされやすい(要出典)
- pull requestするとtravisのビルドがなぜか2個走る
- (GitHub statusが最新結果しか取れなかった頃は)一度passしたはずのテストが、 なぜかあとからやってきたfailにかき消される passしたはずのテストはどこへ
- .travis.yml でよく見る branches: only: - master ってなんだよ おれはmaster以外のテストもしたいぞ あれ、よくわからないが意図通りに動いてるぞ 何だこの設定
たとえばbranchを作った時のmasterと今のmasterが乖離していて、 pull requestのbranchのテストは全部通るけど、mergeしたらmasterが落ちる、 というのはよくあることだと思う。 そこを人間任せにするのか「ちゃんとmasterに追い付かせておいてね」、 仮にmergeしてみてtestするのか、は考え方による。 後者は便利に見えるが、なんで落ちたかよくわからない状況になることもありがち。
branchのpushでbuildされるとジャマ
となると単にbranchをpushしただけでbuildされるとジャマなので、
としたい。 これで、master branchへの変更、およびmasterに対してのpull requestに仮にmergeしてみて、が走る。 大きめのfeatureブランチを作っていて、 そのfeatureブランチに対するpull requestも仮にmergeしてみて、をしたい場合
とすればよい。
なにかこのブランチが作られた時には、hookで何かしたい、などの場合は
とする。正規表現が使える。
pull request時の挙動
TravisCI
pull request作成時にhookで起動する。 条件を満たしていれば。
pull request済みのbranchに追加のcommitでも起動する。
CircleCI
pull request作成時にはhookで起動しない。 branchのpushを検知する側だけなので。
だから、pull requestに対して何かをしたい、例えばlintしてコメントをつけるとか、の場合、 さっさとpull requestをつくらないと、コメントをpostする先のpull requestがない状態で、 処理が終わってしまう。 branchをpushしてしばらくしてからpull request作成、 そのpull requestに追加でcommitしてpush、 この後者のpushのタイミングで初めてコメントが付くことになる。 ちょっと注意。
git操作での挙動
TravisCI
仮にmergeしてみる TravisCI式がいいことづくめか? というとそうでもない。
git 操作でなにかするアプリの場合、
あまりこれを想定した挙動になっていないことが多い。
それからたとえば、GitHubのapiと連携してpull requestにreview commentをつけたいので、
上のtigで言うc47af08
を取りたい場合に、うってなる。
saddler-reporter-support-gitでは結構頑張って解決
している。
feature branchにmasterをmergeして追い付かせた時に正しく検出しなそう、とかある。
注) TravisCIに限れば、環境変数 TRAVIS_COMMIT
で該当コミットが取れる。
この「仮にmergeしてみる」は色々流派がありそうで、実際対TravisCIでは動いているけど、 他のパターンが有るときに全部解決してるかは自信ない。
pushされたbranchのビルド
Travisは必要最低限にチューンしてあるので、masterとかorigin/masterとかいない。 ちょっとだけ注意。
と手癖で打つとorigin/master
無いので落ちる。
余談
checkout -b したいときは
か単に
とする。
CircleCI
CircleCIはおそらく事故防止のためにgit関連のログをwebからは表示しないので、 推測だけど
してるだけだと思う。 オーソドックス。 そして多分cloneは初回だけで、cacheしつつあとはfetchとcheckoutっぽい。 sshで入るとこんな感じなので。
remote側も綺麗に全部見える(必要最低限ではなく富豪的)
余談
これたまに git fetch origin --prune
しないと膨れ上がりそう。
ログとかの都合上あったほうがいいのかもだから詳しくは調べてない。
まとめ
普通にやったらこうなる、を高速に解決しているのがCircleCI。 多分Jenkinsで自分でやったらこうなりそう、ただし低速。 ちゃんとやったらこうなる、を正しく解決しているのがTravisCI。 ただし、正しく理解しないと、適当に、じゃあこうかな? とやっても正解にたどり着けない。
drone.io, wercker, teamcity, codeship, あたりのメジャーどころは、 だいたいどっちかなんじゃないかな(未調査)、 カバーできてるんじゃないかな、カバーできてるといいなあ。 詳しい人に補足おねがいしたい!!
ローカルやCI上で動くはずのツールが、CIサービス上では動かないとき、 このへんの詰めが漏れてることが多いので e.g. pronto なぜか動かないときは、 ココらへんに気を配ってcontributeするとよいです。 なお、 checkstyle形式の結果をpull request review commentするsaddler などのpacksaddleプロダクトはその辺のCI間の差異を吸収して、使うときは考えなくていいように、作ってます。