機能リリースに欠かせないGitHub FlowとChatOps
続いて登壇したGitHubの田中氏は、最初にここ1年半以内にアップデートしたプロダクトを披露した。無料のプライベートリポジトリ(アクセス制限3ユーザまで)Free Private Repositories、GitHub Actions、GitHub Packages、GitHub Sponsors、GitHub Desktop 2.0など、主立ったものだけで8つ。なぜこれだけ多くリリースできたのか。「大事になってくる要素が3つある」と田中氏。それがGitHub Flow、ChatOps、継続的デリバリ Continuous Deliveryである。
まずはGitHub Flowの解説から。GitHubでは機能開発する際、masterからフィーチャーブランチという機能開発用のブランチを切るという。その上でコードを変更してコミットして、プルリクエストを作成する。そこでコードレビューやCIプロセスを動かし、変更内容の品質を確認する。
CIプロセスでは自動テストやユニットテスト、機能テスト、結合テストなどを実行。そのほかにもアクセシビリティテストや性能ベンチマークなど、あらゆる観点で品質チェックなども実行する。そしてコードレビューやCIが成功しないと次のステップには進めないようになっているのだ。そしてすべてのチェックが終わると、デプロイをする。「デプロイと言っても、いきなりプロダクション環境にデプロイするわけではない」と田中氏は説明する。
GitHubはデプロイ環境を3種類用意している。1つはreview-lab。これはプロダクションと同じ構成のステージング環境である。CIのジョブ中で自動的にデプロイされ、https://<branch-name>.review-lab.github.com/というURLからアクセスできるようになる。
そこで結合テストを実施する。レビューラボの確認がOKになると、production/canaryというカナリヤ環境で実際のプロダクション環境の一部に、フィーチャーブランチの内容をデプロイする。カナリヤ環境の目的はユーザーのリクエストを実際にさばいてみて、エラーレートが上昇しないかやサーバーリソースを変な使い方をしていないかなど、リグレッションがないかどうかを確認するためだ。「これらは5~10分ぐらいで判別できる」と田中氏。
大丈夫だと判断できれば、productionにデプロイする。これで全ユーザーに公開されることになる。プロダクション環境でもカナリヤ同様、サーバーリソースのようなメトリクスを確認して、OKであればその時点でフィーチャーブランチをマスターにマージする。
これがGitHubでのデプロイの基本的なフローである。だが、これだけでは誰がどのように実行するのかがわからない。そこで活用するのがChatOpsだ。社内で使っているSlack上でコマンドを実行すると、裏でボットが処理してくれる仕組みだ。例えばデプロイ処理は、.deployというコマンドを使う。そしてどのブランチをどの環境にデプロイするのかを指定する。すると、その裏でHubotというボットが反応し、デプロイ処理を行う。
デプロイ後、知りたいのはプロダクション環境に異変が起こっていないかどうだが、それもHubotが教えてくれる。プロダクション環境のさまざまなメトリクスのダッシュボードや、エラー監視ツールのリンクを返してくれるからだ。「ここでひとつ大事なことがある」と田中氏。「GitHubではデプロイを実行するのは、プルリクエストをしていた本人。自分でデプロイするため、余計な承認フローなどはない。だからガンガンデプロイできる」という。
このようにGitHubではChatOpsのコマンドをたくさん作成しているため、ほぼすべてのオペレーションはChatOpsで行われているという。
「例えばサーバーリソースがおかしければ、Slack上でサーバーリソースの確認ができる。またデプロイ後に何か問題が発生したとき、今日のオンコール担当の確認などオペレーションに必要な操作は、すべてSlackコマンドで実装されており、Hubotで見ることができるようになっている。しかもSlackなので、直接、担当者にメンションして、経緯の説明やメトリクスを見せることなく、その場で一緒にトラブルシュートできる。問題が迅速に解消できるのが、ChatOpsのメリットだ」(田中氏)
リリーストレインでデプロイロックを解消
GitHubではこのような形でこれまでずっとプロダクトアップデートをしてきた。デプロイ数も2015年には週に400回を超える数を行っていたという。3つ目の要素、継続的デリバリ Continuous Deliveryも問題なく実現できているように思える。
だが、人が増えるに従い、大きな問題が出てきたという。GitHubはマイクロサービス化している部分もあるとはいえ、基本的には大きなモノリス。それに対して、先の体制でデプロイしていくと、デプロイが競合するようになったという。デプロイロックが起こっていたのである。
GitHubはフィーチャーブランチからプロダクションをデプロイし、その後、数分間はメトリックスがおかしくなっていないか確認する。その間に他の人がデプロイすると、きちんとした監視ができない。そのため、Hubotはプルリクエストをデプロイしてから、それがマージされるまでの間、他の人がデプロイできないようにロックをするのである。「デプロイロックの競合が起きて、デプロイロックが取られていないタイミングを待つ必要がでてきた」と田中氏は振り返る。
その改善策として作ったのがデプロイキューである。ロックがかかりデプロイできなかったときに、順番待ちできるようにする仕組みである。そして自分の番が回ってくるとHubotが通知をしてくれる。これでロック解消を待ち続けないといけないという問題は解消された。だが人が増えると、順番待ちの時間は長くなっていった。「2018年の初頭、キューの待ち時間が3時間19分。ひどいときは5~6時間待ちも起きていた」と田中氏は吐露する。そうなるとフィードバックサイクルのループも遅くなってしまう。
2018年の後半、この問題を解決する仕組みとして導入したのが「リリーストレイン」である。リリーストレインは、同じタイミングでデプロイするプルリクエストを複数まとめて、一気にデプロイする仕組みだ。
トレインにはたくさんのプルリクエストが乗るので、他の人のプルリクエストを乗車させることもできるようになっている。またフィーチャーブランチにはどのトレインにしたかという情報がHubotにより自動で記載される。そしてトレインに乗客がたまると、トレインのブランチごとにreview-labにデプロイする。問題がなければ複数プルリクエストをまとめてカナリヤ環境、さらにはプロダクションにデプロイして確認してから、トレインのブランチをマスターにマージする流れになる。「このような仕組みにより、シップされたトータルのプルリクエストの数は右肩上がりに増えている」と田中氏は満足そうに語る。
リリーストレインの仕組みは、元々GitHubの1つのチームが、自分たちのチーム向けにまとめて作った仕組みだという。実際試してみたところ効果がよかったので、社内ブログに記事を公開。さらに別のチームがHubotのコマンドに変更したり、草の根的に改善が加えられ、全社に広がっていったという。「これもGitHubらしさ。よい仕組みはすぐ広がっていく」と田中氏。
GitHubはDevOpsやリーン開発でよく語られる学習サイクルを高速に回すことを重要視しており、全員に根付いているという。「デプロイプロセスをどうするかに正解はない。きっと2、3年後には別の動きをしていると思う」と田中氏は語り、セッションを締めた。
お問い合わせ
日本マイクロソフト株式会社
-
【Microsoft Learn もくもく会】
- 全国のMicrosoft Learnユーザーのコミュニティです。
-
【JAZUG (Japan Azure User Group)】
- Azureを学び、楽しみ、活かす、日本のユーザーグループです。
-
【クラウドデベロッパーちゃんねる】
- クラウドを使って開発するITの開発者・デベロッパーの皆様へ様々な技術情報をお届けするYouTubeチャンネルです。
-
【Microsoft Learn】
- Microsoft Azureについて学習できる無料のオンライン トレーニング コンテンツ一覧です。
-
【開発者コミュニティ ニュースレター】
- マイクロソフトが配信しているニュースレターで、最新テクノロジ記事、技術ドキュメント、および開発者イベントなど、世界の情報を月イチで配信しています。