ChatOps時のブランチ運用戦略(実装 / コードレビュー / 関係者確認 / 自動テスト / デプロイを円滑に行う)

#概要

以前、[「Slack / Hubot / GitHub / CircleCI によるChatOpsなデプロイ方法」](http://qiita.com/s-kiriki/items/26bdf537169891b22653)という投稿で、Slack / Hubot / GitHub / CircleCI などをつかってChatOpsな環境をつくる方法をまとめました。

今回は、それらのChatOpsな環境の中で、どのようなブランチを用意して、実装 / コードレビュー / 関係者確認 / 自動テスト / デプロイを効率よく行っていくかについて、まとめてみたいと思います。


#運用の概要図

![Untitled (9).png](https://qiita-image-store.s3.amazonaws.com/0/47881/3e51a012-2dbb-aa6b-2cef-963a52ed728d.png)


#ブランチの説明

|ブランチ | 役割 | 連携する環境(*\*1*) |
|:-----------|:------------|:------------|
|deployment/production | 商用にリリースされているもの。 | 商用環境 |
|master | 常に安定。いつリリースしても良い状態。| ステージング環境 |
|deployment/test-** | 関係者（開発者や企画や営業）が仕様・動作確認する。案件に応じて複数用意。 | 検証環境 |
|その他| 開発用ブランチ| 各自の開発環境 |

*\*1* CircleCIによって、GitHub上の該当ブランチに変更があった場合に、自動でデプロイされる環境になります。 

#Hubotの擬犬化
ここでは、Hubotを擬犬化して、ロボットではなくワンコとして扱っています。本投稿の挿入画像でも、Hubotではなくwankoとして表示されているので留意してください。

![Untitled (6).png](https://qiita-image-store.s3.amazonaws.com/0/47881/80ddafd4-dc3b-9cf9-200e-83ef078846d3.png)








#実装からリリースまでの流れ

##①masterからブランチを切って、実装

新規ブランチをmasterから切り、実装を行います。

##②仮コードレビュー[WIP]の実施（任意）

実装が終われば、検証環境へデプロイして関係者確認を行いますが、これの前にコードレビューを行います。ただしここでのコードレビューは必須ではありません。
この段階でのコードレビューが推奨されるのは以下の場合です。

* **修正が大規模なとき**
検証環境での確認が終わり、masterにマージする際にレビューが入ります。ここでレビューに引っかかると指摘点を修正し、再度関係者確認を行いますが、大規模な修正の場合、レビューで指摘が入る可能性が高く、またそうした際の手戻りのロスが大きくなってしまうため、関係者確認（検証環境へデプロイ）の前に予めコードレビューを行います。

* **実装に自信がないとき/後の本レビューで指摘されそうなとき**
このような場合も、手戻りのロスを防ぐため、関係者確認（検証環境へデプロイ）の前に予めコードレビューを行います。

コードレビューの依頼はGitHubのプルリクエストで行います。
プルリクエストのマージ先はmasterにします。

この際、プルリクエストのタイトルの先頭に【WIP】を付けます。WIPとは Work In Progress の略で、「まだ作業中だよ」「こんな感じでいいか見てほしいよ」「マージしないでね！」という意味があります。

また、WIPをタイトルに含むプルリクエストをマージできなくする[「Do Not Merge WIP for GitHub」](https://chrome.google.com/webstore/detail/do-not-merge-wip-for-gith/nimelepbpejjlbmoobocpfnjhihnpked)というChromeのエクステンションもあり、こちらを利用すると間違ってWIPのものをマージするのを防げます。


![zzz_スクリーンショット_2014-09-16_14_40_36.png](https://qiita-image-store.s3.amazonaws.com/0/47881/53d7c038-79be-cd2f-82a3-290506369ec2.png)


##③検証環境へのデプロイ

検証環境へのデプロイはデプロイしたい内容のブランチを検証環境のブランチにマージすることで行います。
検証環境のブランチ(development/test-**)はCircleCIによって変更が監視されており、変更があると自動でデプロイされるようになっています。

このマージはChatOpsで行います。Chat上で行うことで、チーム内でどの検証環境にどの案件がデプロイされたかが一目瞭然となります。
HubotにGitHubのAPIを叩いてマージを実行するよなコードを書いて、以下のようなコマンドをSlack上から実行しています。

```
hubot merge <repo>/<head> into <base>
```

![zzz_スクリーンショット_2014-09-16_15_12_16.png](https://qiita-image-store.s3.amazonaws.com/0/47881/cd3a367b-70af-4e73-58d1-3e8a31d9455d.png)


ちなみに以下のようなコマンドはエラーとなるようにHubotに実装してあります。

```
#masterやdeployment/productionへのマージは禁止。常にプルリクエスト経由で行われるべき。
hubot merge <repo>/<head> into master
hubot merge <repo>/<head> into deployment/production
```

![スクリーンショット 2014-09-16 15.13.13.png](https://qiita-image-store.s3.amazonaws.com/0/47881/64f7e544-def5-6e44-1096-d5197821897d.png)


##④コードレビューの実施 / masterへのプルリクエスト

検証環境での関係者確認でOKがでた場合は、いよいよリリースに向けてフローを進めていきます。
リリース（商用環境へのデプロイ）されるのは常にdeployment/productionブランチであり、そのdeployment/productionにマージされるのは常にmasterブランチであるため、まずはmasterブランチに対してマージを行います。

masterへのマージは常にGitHub上のプルリクエストを通して行います。
こうすることで、このmasterへのマージ前の段階で必ずコードレビューが入る仕組みとなっています。

##⑤リリース依頼 / 最終レビュー

リリースは、masterをdeployment/productionにマージすることで行われます。
deployment/productionへのマージもmasterと同じく必ずGitHubのプルリクエスト経由で行います。

ただし、このプルリクエスト（リリース依頼）は、ChatOpsで行います。

```
#deployment/productionへのプルリクエスト作成はChatOpsで行う
hubot deploy <repo>/master into deployment/production
```

![スクリーンショット 2014-09-16 15.26.35.png](https://qiita-image-store.s3.amazonaws.com/0/47881/d4fe66f0-43ca-a0de-4f47-7c61b282cb86.png)

リリース依頼(master=>deployment/productionのプルリクエスト)をChatOpsで行うことで、以下のようなメリットがある。

* チーム内で、デプロイ状況が一目瞭然
* 下図のようにリリース依頼がHubot（ここではwanko）による画一化されたフォーマットのプルリクでくるので、チェックしやすい。

![zzz_スクリーンショット_2014-09-16_15_29_05.png](https://qiita-image-store.s3.amazonaws.com/0/47881/be33aad9-02e5-64c9-3da8-98336b624f20.png)


#その他

##検証環境の掃除

検証環境に連携しているブランチには、さまざまなリリース前の変更がマージされます。
このため、新しいブランチを検証環境にデプロイする前には、一度検証環境のブランチをmasterブランチの状態に合わせておくのが好ましいです。
そこで、Hubotに任意のブランチのrefをmasterのrefに更新するスクリプトを実装（GitHubAPIを利用）して、ChatOpsでSlackから以下のようなコマンドを叩くことで実現しています。

```
hubot update ref <repo>/<head>
```

![スクリーンショット 2014-09-16 15.43.43.png](https://qiita-image-store.s3.amazonaws.com/0/47881/adab853e-5499-0639-8393-a38988c22c4d.png)