エンジニアリングマネージャーとして組織的課題に立ち向かい、チームに継続的デリバリーを導入した

この記事は [Engineering Manager Advent Calendar 2021](https://qiita.com/advent-calendar/2021/em) の19日目として投稿します。

今回はエンジニアリングマネージャーとして組織的課題に立ち向かい、チームに継続的デリバリーを導入した話を書きます。継続的デリバリーに関する技術的な話は書きません。あくまで組織的課題をどう整理し、導入したのかという点にフォーカスします。

この記事の内容は私のチームの組織的課題にどう立ち向かったのかという話なので、多くの人や組織にとって有益ではないかも知れません。そもそもエンジニアリングマネージャーの仕事は各々の置かれた環境で発生している問題をオーダーメイドで解決することだと思っています。なので、私も他の会社の取り組みの記事を読んでも「これはこの会社にこういうことができる人材が揃っていたからできたんだな」とか「これはこの会社の事業形態がこうだったからできたんだな」とか考えがちです。また、一般化された話を読んでも「言いたいことはなんとなくわかるけどそれってどうやって実践するの？」と思うことがあります。ただ、そういう話の中にも自分たちの環境に取り込める要素や課題解決のヒントになる要素が含まれていることも事実なので、この話が少しでもどこかの誰かの役に立てば嬉しいです。

## 課題の発見
私のチームではアプリの機能リリースを１、２ヶ月に１回の単位で行っていましたが、リリース済みのバージョンからの差分が大きくなるため、リリース前の手動検証に多くの作業日数が費やされていました。また、作業期間が開発、検証、リリースのように区切られてしまう為、検証期間には開発者は発見された不具合修正に追われていました。
その結果、機能の実装自体に使える時間が少なくなり、開発のスピードを思った程出せずにいました。

私のチームの状況は以下のとおりです。

- React Native（expo）を使ってスマホアプリを開発している
- 自社アプリだが、他社からの依頼で機能追加を行うこともある
- 単体テストはある程度書いているが、結合テストやUIテストなどの自動テストは書けていない
- 手動検証を行うテスターがいる

そろそろこのリリースが重く開発スピードが出ない課題を解消しなければならないと考え、まずは普段のデリバリープロセスを洗い出し、どのプロセスにどれだけの作業時間、待ち時間がかかっているかを確認するために、チームで集まってバリューストリームマッピングをやってみることにしました。

バリューストリームマッピングについては主に以下のスライドを参考にしました。

https://www.slideshare.net/TechSummit2016/app013

結果として、やはりリリース前の検証に多くの時間が取られていたことと、デプロイやリリースノートの作成、承認のプロセスが重いことも明確になりました。

## 方針の整理
バリューストリームマッピングによって課題が洗い出せた後、どのようにしてそれを解決するのか方針を立てました。その方針は以下のとおりです。

リリースを軽くする → リリース頻度が増える → リリースごとの変更差分が小さくなる → リリースごとの手動検証作業を減らす → 開発の時間をより多く確保できる

要するに継続的デリバリーを導入してなんとかしよう、ということです。

まず、最初のステップである「リリースを軽くする」を実現するために以下を実施することにしました。

- デプロイを自動化する
- リリースノートの内容を必要最小限に絞り、作業負荷を減らす
- リリース承認が必要なケースを限定する

また、「リリースごとの手動検証作業を減らす」ために以下を決めました。

- 新機能開発時の機能単体検証はこれまでどおり行う
- リリースに伴う統合検証は引き続き手動で行うが、大幅に作業量を減らす
- リリースによって多少の不具合が生じることは許容し、すぐ修正リリースを行うことでよしとする
- 自動テストの拡充は今やらない

自動テストが整備されてない継続的デリバリーなんてあり得ないという意見があるかも知れませんが、作業負荷とリスクのバランスをコントロールできていれば良いので、今回はこれでよしとしました。
本当は繰り返し作業は早く自動化したいですが、まずは走り出さないといつまでも現状で停滞してしまうと恐れがあります。

## 実装

### デプロイの自動化

継続的デリバリーを行う上で、デプロイの自動化は避けて通れないと思いました。デプロイの作業が重くなってしまうと、いつでもリリースしようというモチベーションを持つことができません。

### 手動統合検証の作業量削減

「１回のリリースの差分が小さければ基本的に大きな問題は発生しない、発生したとしてもすぐに直せば良い」の精神で作業量を削減しました。具体的には作業時間を決めてそれで問題が見つからなければ良しとしました。我々のサービスは多少の問題が発生したとしても、それによってユーザーの人命や財産に影響を与える性質のものではないので、そこは開発スピードを優先して割り切ることにしました。もちろん問題は発生させたくないですが。

### リリースノートの内容の削減

もともと私のチームのリリースノートにはリリースする変更内容の他、リリースの目的やテストの結果など、割とリッチに情報を記載していました。過去にリリースで何か問題が起きるたびに、この情報は書いておこうという項目が増え、膨れ上がった結果です。これがすごく大変という程ではないけど地味に面倒という作業でした。そのため、リリースノートを書く意味から整理しました。誰のためのものなのか、何のためのものなのか。整理した結果、リリースノートにはリリースする変更内容だけ書けば良いという結論に落ち着きました。

### リリース承認が必要なケースの限定

私のチームではリリースの都度、リリース承認を行っていました。リリース承認は忙しい上司に依頼するので、チャットで依頼してから承認が完了までの待ち時間が数時間単位で発生し、非常にもったいない作業でした。毎日リリースしようと思ったらこのプロセスは運用に耐えないので、承認は基本的には必要なしとしました。ただし、外部の会社からの依頼で開発した機能を複数一度にリリースしなければならないケースについては、リリースの規模が大きくなるため、引き続きリリース承認を行うことにしました。

### デリバリーフローの整理

継続的デリバリーを行うにあたり、デリバリーフローの整理には非常に気を使いました。最も大事にしたのは「ある機能についての作業が、他の機能のデリバリーを阻害しないこと」です。そのためのブランチ運用、検証タイミングを整理しました。最初に書いたとおり、開発しているのは自社サービスですが、他社からの依頼での機能開発もあるため、ビジネス的な要件でこの機能とこの機能はこの日にまとめてリリースしてほしいということがあります。それも織り込みました。もちろんすべての機能をできたそばからすぐにリリースできてしまう方が開発者としてやりやすいのですが、それは開発者の都合なので可能は範囲でうまくやる必要があります。

## 結果

そんなこんなで、これまでの私のチームのが積み重ねてきた歴史によって作られてきた今となっては重たいプロセスを整理し、再構築して今できるベターな継続的デリバリーの体制を整えました。まだ導入して間もないので、しばらくしたら何か問題が起こるかも知れませんが、今のところリリースにかける時間がだいぶ短くなったという声が聞こえてきています。開発のアウトプットが増えてくれると嬉しいです。

## 今後のやること

とにかく今は手動検証の負荷が大きく、テストピラミッドが逆さになっている状況なので自動化して行きたいです。ただ、テスト自動化については費用対効果を気にして最も効果的な部分からやるべきだと思うので、きちんと戦略を練りたいです。

## まとめ

今回の活動の中で、改めて次のようなことを感じました。

- 目標を定めたら、今やるべきことと後回しでも良いことを切り分けてとりあえず動き出してみるのが大事
- 組織は歴史を重ねるごとにプロセスが重くなりがちなので、気になってきたら整理する必要がある
- 事業形態によるビジネス的な課題はすぐにどうこうできないこともあるので、エンジニアリング側でうまくやることが大事

来年も良いエンジニア組織を作るためにがんばります。