胃が痛いビッグバンリリースはもう嫌なので、デプロイを日常にする

この記事はGLOBIS Advent Calendar 2020の15日目の記事です。

# はじめに
エンジニアが行うタスクの中には、「胃が痛い」リリース作業があります。
多くの時間をかけて取り組んだ作業にも関わらず、本番でエラーが出たらお客さんやチームメンバーに迷惑をかけてしまう可能性があるためです。
自分が新卒の頃から考えると、「早く事業を成功させたい」という長期的なプレッシャーは相変わらずある一方で、作業単位での瞬間的なプレッシャーはかなり少なくなりました。

今は当たり前に1日10回以上デプロイしている会社も結構あると思うものの、デプロイが「日常」になっていないと、まとめられがちなので記事にすることにしました。

後半に デプロイ頻度を Git の情報から2ステップで見える化するスプレッドシートも用意したので、ぜひご活用ください！


# とある日のリリースPR
![Screen Shot 2020-12-13 at 9.57.49 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200628/7afae53b-9204-61a7-b906-97a1963acd24.png)

...(ﾟＡﾟ;)ｺﾞｸﾘ

去年の12月後半はコードフリーズしていたため、変更PRは次々と master branch にマージされていきました。
当時のbranchは以下です。
release = 本番環境に反映される
master = ステージング環境に反映される

branchの流れイメージ
![Screen Shot 2020-12-14 at 10.33.41 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200628/d52ed316-edeb-d478-7795-f51283516f90.png)


小さいPRは多かったものの、1本番デプロイに50PR以上含まれていることもありました。


# 週1デプロイの問題点

週1デプロイには以下の問題がありました。

- デプロイ後にエラーが起きた場合、どのPRが原因なのか分かりづらい
2. デプロイ担当者と開発者が異なるため、リリース時にPRを担当した開発者がいないことがある
3. 小さい修正でも、デプロイに間に合わないと1週間近く待つ場合がある
4. 担当制で回していてデプロイをたまにしかやらないので、デプロイ手順を忘れる


# 高頻度デプロイの重要性
高頻度デプロイが重要であることを言語化するために、本で出てきた説明を参考にしつつ言語化しました。

>“今の世の中、健全な技術チームであることを示す一番の兆候が「リリース頻度の高さ」だからです。チームの焦点を製品に絞らせている「できる上司」なら、仕事のはかどる環境作りのノウハウを心得ているはずです”
Excerpt From: Camille Fournier. “エンジニアのためのマネジメントキャリアパス.” Apple Books. 

しんどい作業をまとめることで、よりしんどくなるのは身に沁みていました。
>多くのチームは、ソフトウェアのデプロイやインテグレーションの頻度を下げることにより、バリューのかたまりをさらに大きくして、ストレスに対処しようとしている。そして、これが問題を悪化させている。フィードバックが減ると問題が悪化して、さらにかたまりが大きくなってしまう。遅れるものが増えると、かたまりがまた大きくなり、リスクが高まっていく。流れの原則では、改善のために小さなバリューを何度もデプロイすることを提唱している。  
Kent Beck,Cynthia Andres. エクストリームプログラミング (Japanese Edition) (Kindle Locations 801-806). Kindle Edition.   

More Effective Agile では少なくとも1日1回と言ってますね。
>増分的な作業プラクティスに重点を置く欠陥の挿入から検出までのギャップを最小限に抑えるという目標を支援するには、次の手段を講じる必要がある。■コードを頻繁に（少なくとも1日1回、できればさらに頻繁に）コミット／プッシュする。
Steve McConnell. More Effective Agile  ソフトウェアリーダーになるための28の道標 (Japanese Edition) (Kindle Locations 3534-3537). Kindle Edition. 

指標として具体的な数値を算出しているのが面白いと感じました。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">最近、エンジニアリング組織の健全さの指標に、<br>d/d/d というのを用いてる。<br><br>deploys / a day / a developer の略で<br>1日あたりのデプロイ回数を開発者数で割ったもの。<br><br>だいたい、0.1 以上なら健全と言える<br><br>これが悪化しているとき、最上流含めたエンジニアリングパイプラインのどこかに問題がある</p>&mdash; 広木 大地/ エンジニアリング組織論への招待 (@hiroki_daichi) <a href="https://twitter.com/hiroki_daichi/status/1100381137929625600?ref_src=twsrc%5Etfw">February 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

月ごとに deploys / a day / a developer を出してみたところ、0.01~0.04が多い状態でした。



# こんな感じで改善しました
自分としてはデプロイ分けたいと思っているものの、社内的には以下の状況だったので、
一つ一つ進めていきました。

- スプリントレビューでポジティブなFBもらわないとリリースしにくい雰囲気  
　→POレビューでOKであればリリース可能であることを繰り返し伝えた。
- デプロイを増やす必要性を感じていないメンバーもいる。  
　→なぜデプロイ回数を増やしたいかをnotionにまとめて共有、軽く話す。
- 影響範囲がわからないリリースだからこそ、ステージング環境で確認しようという雰囲気  
  →RSpecでカバーできる範囲を増やした。ステージング環境確認でも漏れるところがあったためRSpecに寄せていこうという話をした。
- デプロイには手間がかかるので、まとめてやったほうが良い  
　→release branchをなくして、master branchにmergeされたら自動デプロイされるようにした。
- conflictさせたくないのでマージしたいけど、本番に出てしまうと困る  
　→フィーチャートグルにより、本番には出さないけどマージはする。

フィーチャートグルとは
>フィーチャートグルを使う
すべてのコードが本番環境に入っているけど無効化されている状態で開発を進める
引用元：https://blog.sushi.money/entry/2018/09/04/113921


![Screen Shot 2020-12-14 at 10.37.02 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200628/f5128fae-ba07-ee47-5cf5-21ec4d01a85f.png)

問題をチーム内外の方と協力しながら解決した結果、deploys / a day / a developer の値がいい感じになってきました！


![Screen Shot 2020-12-14 at 12.41.56 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200628/5b8fd5a7-4474-34a8-f39d-5d80787ee245.png)

# deploys / a day / a developer を2分で計測できるスプレッドシートつくりました

完成イメージはこちら
※リリースを git tag で切っていないと使えません。
https://docs.google.com/spreadsheets/d/16JLCTrY2LDc_QtlU-ZIOClmib9_xZ8YxcF9chSg_RgE/edit?usp=sharing

## なぜ見える化、計測したか
「計測できるものは改善できる」と思っているからです。

## 仕組み
デプロイ日時のリストとコミット日時、コミット者を組み合わせて deploys / a day / a developer を算出しています。
git tag コマンドにてデプロイ日時を取得します。
ここでは tag = デプロイとみなしています。
※もし GitHubの releaseを使っている場合は `gh release list` などのコマンドに変更する必要があります。


## 使い方

### 1. テンプレートからシートを取得

以下にアクセスしてシートを作成します。
https://docs.google.com/spreadsheets/d/14-xaLhal-fcGA2ly-Wy_8NXxp_6xCNGZvDB2M1RvyYQ/copy

### 2. git tagを取得して貼り付け

![Kapture 2020-12-15 at 09.49.21.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200628/4dab76f0-03c3-cba5-a135-d10f3d6bc085.gif)


以下のコマンドを実行すると、クリップボードに git tagの出力を格納します。

```
technuma ~/works/next.js  % git tag --sort=creatordate --format "%(creatordate:short)" | pbcopy
```

↑の結果を、動画のように `HogeRepository_リリース数` の青いセルに貼り付けます。

### 3. git log からコミッタを抽出して貼り付け

![Kapture 2020-12-15 at 09.50.48.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200628/a87549dd-f5ac-6d11-c7ea-5cb2e9410029.gif)

`HogeRepository_人数` シートに移動して、コマンドの文字列をコピー

```
technuma ~/works/next.js  % git log --oneline --pretty=format:'%cd_%cn' --date=format:'%Y/%m' | grep -v GitHub | pbcopy
```

※↑のコマンドではGitHubというユーザーを除外しています。Botのユーザーがいたら `grep -v` で適宜除外をお願いします。

コマンドを実行すると、 コミッタと日付の羅列がクリップボードに格納されるので `HogeRepository_人数`の青いセルに貼り付けます。

### 4. 完成

以上でデプロイ頻度の推移、deploys / a day / a developerの推移を見ることができます！

# まとめ
今回の記事は Git Flow から GitHub Flow に変更したことで、デプロイを日常にすることができました。

様々な理由でデプロイが大きく、低頻度になってしまうこともあるかと思います。
1人で開発しているなら週1デプロイでも問題ないかもしれませんが、複数の人が関わってくるとどうしても低頻度で粒度が大きいデプロイはつらくなってきます。週1デプロイだったとしても、デプロイを分けてみることで不安を減らすことはできます。
この記事が皆さんのストレスフリーな開発に役立てたら嬉しいです。


# 参考リンク
https://www2.circleci.com/rs/485-ZMH-626/images/001_DevOpsCulture.pdf
https://circleci.com/landing-pages/assets/2017-VelocityReport-Updated-070219_JA.pdf
https://blog.sushi.money/entry/2018/09/04/113921
https://speakerdeck.com/twada/quality-and-speed-2020-autumn-edition?slide=59

# 参考書籍
エンジニアのためのマネジメントキャリアパス ―テックリードからCTOまでマネジメントスキル向上ガイド https://www.amazon.co.jp/dp/4873118484/
More Effective Agile ~“ソフトウェアリーダー"になるための28の道標 https://www.amazon.co.jp/dp/4822286584
エクストリームプログラミング https://www.amazon.co.jp/dp/4274217620