アリババクラウド独自の実践とツールでブランチ管理の開発と課題を解決

ソフトウェア開発チームは、特にコラボレーションを促進するツールに大きく依存しています。ここでは、**Alibaba Cloud**の独自のプラクティスと開発ツールを探っていきます。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/how-do-we-manage-code-branches-at-alibaba_593834)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

アリババグループやアリババクラウドでは、社内で人気を集めているエキサイティングなエンジニアリングプラクティスがたくさんあります。これらのプラクティスの中には、アリババグループの大規模な環境では効果的ですが、外の世界では複製するのが難しいツールやワークフローを使用しているものもあります。一方で、あちこちで見かける標準的なプラクティスもあります。例えば、ブランチ管理の問題では、ツールと習慣の両方が重要な役割を果たしています。この記事で取り上げたツールや習慣の中には、アリババクラウド独自のものもありますが、世界中の組織が同じものを複製して利益を得ることができます。

アリババグループには多くの研究チームがあり、さまざまな部門が異なる公開フローを使用しています。分岐戦略はすべての部門で同じとは限りませんが、広い視野で見れば、かなり統一されています。これらの実践の中で、人気のあるプッシュ方式とそれに伴う分岐方式を総称して "AoneFlow "と呼んでいます。この一連の作業方法論の背後にある考え方はユニークで、アリババ以外ではあまり見られません。この記事では、これらのプラクティスに焦点を当て、ブランチ管理の問題について少しお話します。

#詳細な分岐
ブランチ管理といえば、一般的にはTrunkBasedとGitFlowの方法論に限定されます。

TrunkBased の方法論は、継続的インテグレーション (CI) の考え方の結果として生まれました。これにはマスターブランチといくつかのプッシュブランチが含まれており、それぞれのブランチはマスターブランチの特定のサブミッションバージョンから作成することができ、オンラインデプロイやホットフィックスのために使用されます。TrunkBasedメソッドでは、明示的な機能ブランチはありません。もちろん、実際にはGitの分散型の性質上、各個人がローカルブランチを持つことは可能であり、TrunkBasedでは短期的なフィーチャブランチを持つ可能性を排除していません。しかし、彼の手法を語るとき、ほとんどの人はこの点をあまり重視しないでしょう。

ここ数年で多くの事例が出てきていますが、TrunkBased はまだ開発者の心を掴むことができていません。その失敗は明らかで、複数のチームがマスターブランチで作業している場合、プッシュの時期になるとプロジェクト全体が簡単に破壊されてしまうことがあるのです（主に2つ以上のバージョンを同時に開発している場合）。これを補う一つの方法は、FeatureToggle を使用し、頻繁にマージを行い、十分なテストカバレッジを適用することです。しかし、これは開発チームの能力に高い要求を課すことになります。現在、ほとんどのチームは、複数の履歴バージョンを同時に維持する必要のないSaaSプロジェクトでは、主にTrunkBased方式を使用しています。特に、マイクロサービスに変化した小規模なサービスには便利です。

TrunkBasedメソッドには2つの形態があります。OneFlowメソッドはTrunkBasedと同じ哲学を多く採用していますが、操作のワークフローをより厳密に定義し、Hotfixブランチのようなものを追加しています。マルチプルトランク方式（通常は2つのトランク、セット開発用トランクと本番用トランク）は、セット本番用ブランチを採用したTrunkBasedの特別バージョンです。

GitFlow メソッドは他のいくつかのメソッドを組み合わせたもので、マスターブランチ、開発ブランチ、複数の機能ブランチ、多数の本番ブランチ、そして hotfix ブランチと、いくつかの面倒なルールを組み合わせたものです。この方法のための Git プラグインがありますが、しばらくの間メンテナンスされていません。このプラグインは各段階での作業を明確に定義しており、かつてはワークフローを重視する様々な企業に愛されていました。しかし、このメソッドを使うのは単純ではありません。ほとんどのマージの競合は、システムの最大の問題である統合テストには不向きです。

GithubFlow方式もありますが、その戦略はTrunkBasedと似ており、個人リポジトリとプルリクエスト操作を追加します。同じリポジトリに個人ブランチを追加する処理と同じで、分散チームに向いています。また、GithubFlowには複数環境でのデプロイをサポートする進化版があり、リポジトリやブランチを環境に接続するGitlabFlowも含まれています。それにもかかわらず、これらの方法はTrunkBasedのように荒っぽく重かったり、GitFlowのようにチューニングされていて面倒であったりします。では、他の選択肢はないのでしょうか？

#AoneFlowの紹介
AoneFlowはGitfFlowの代わりにアリババが開発したものです。AoneFlowには他のいくつかの分岐方法の影響が見られるでしょう。これは基本的にTrunkBasedのような継続的インテグレーションの容易さとGitFlowの管理の容易さを組み合わせたもので、GitFlowの面倒くささを回避しつつも、AoneFlowはGitfFlowの管理の容易さを実現しています。

AoneFlowを理解するために例を挙げてみましょう。AoneFlowでは、masterブランチ、featureブランチ、productionブランチの3種類のブランチと、3つの基本ルールのみを使用しています。

####ルール1：作業を始める前にmasterからfeatureブランチを作成する
AoneFlowの機能ブランチはGitFlowのものをベースにしており、目立った変更はありません。チームが新しいタスク（例えば、新しい機能を追加したり、問題を修正したり）を開始するたびに、まず、最近本番環境にプッシュされたmasterからブランチを作成し、"feature/"で始まる名前を付けなければなりません。そして、このブランチのコードに変更を加えることができます。つまり、各作業項目 (それは一人の個人によって完成されたものであっても、複数の開発者が協力して完成させたものであっても構いません) には、対応する feature ブランチがあります。変更を直接マスターに提出することはできません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/62e5f535-6d66-bca0-2d72-1f754ded58fa.png)

####ルール2: 機能ブランチをマージして本番ブランチを生成
AoneFlowの本番ブランチはかなりインテリジェントで、システム全体の生命線となっています。Gitflowでは、まず完成した機能ブランチを共通マスター（開発ブランチとも呼ばれます）にマージしてから本番ブランチに引っ張ってきます。TrunkBasedも同様のアプローチで、必要な機能ブランチをすべてマスターに含める前に待ってから、マスター上の特定のポイントから本番ブランチを引っ張ってきます。一方、AoneFlow のアプローチは、まずマスターから新しいブランチを引っ張ってきて、現在のバージョンに含める必要のある機能ブランチを一つずつこのブランチにマージし、それによって本番用ブランチを形成します。本番用ブランチの名前は通常 "release/." で始まります。

このルールは非常にシンプルですが、実際に実行するには多くの詳細が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/c7789ca4-4b32-f8c5-3b9f-80c62fdc1c5e.png)

第一に、本番用ブランチの使用は非常に柔軟です。基本的なメソッドは、各プロダクションブランチを取り、特定の環境に関連付けることです。例えば、release/testブランチはデプロイとテスト環境に、release/prodは正式なオンライン環境に関連付けるなどです。その後、ブランチをパイプラインツールと組み合わせて、それぞれの環境でコードをスキャンし、自動化されたテストステージを通過させる必要があります。その後、生成されたデプロイメントパッケージを適切な環境に直接プッシュすることができます。

より高度な方法としては、本番ブランチに対応する環境を利用し、例えば、段階的リリースブランチと正式な本番ブランチを結びつけ、その中間に手動のステップを追加するという方法があります。最も先進的な方法は、反復計画に応じて機能ブランチを関連付け、反復の進化に応じてセットの本番ブランチを作成し、この本番ブランチのパイプラインに一連の環境を追加することです。これは古典的な継続的インテグレーションのパイプラインのように見えるかもしれません。別のオプションとして、すべての機能ブランチを組み合わせたプロダクションブランチを作成して、提案されたすべてのマージをテストするという方法もあります。これは基本的に TrunkBased と同じ効果をもたらします。もちろん、これらの派手で高度な方法は、私が夢見たものにすぎません。Alibaba Cloudの本番ブランチは通常、かなり定期的に開かれています。

さらに、生産ベースでの機能の組み合わせは、動的で調整が簡単です。アジャイル手法が一般的な現代の企業のセットアップでは、機能はすでに準備ができていて、オンラインになるのを待っていることがあります。しかし、マーケティング戦略やクライアントの要求が頻繁に変更されるため、チームはリリースを遅らせたり、完全に投げ出したりしなければなりません。

また、オンライン公開前に深刻な開発上の問題を抱えていて、チームがそれをスクラップしなければならないこともあります。伝統的に言えば、このような事態が発生した場合、私たちは手動でコードを調べ、チームが本番環境やマスターブランチにマージした機能に関係するものをすべて排除しなければなりません。これを経験したことのある人なら誰でも、この仕事の複雑でイライラする性質を知っているでしょう。

しかし、AoneFlow の方法論を使用すると、数分で本番用ブランチを再作成することができます。必要なのは、元の本番用ブランチを削除し、マスターから新しいブランチを取り出して同じ名前にすることだけです。あとは、最終的な機能をすべてマージするだけです。一連のアクションにより、プロセス全体がより自動化され、リポジトリをクリーンに保ち、捨てられたコードがないようにします。

さらに、プロダクションブランチは疎結合されているので、複数のプロダクション環境で同時に機能テストを受けることができ、異なるデプロイメントでの機能統合の管理がより便利になります。本番環境のブランチは緩く結合されているだけで、それらが無関係であることを意味するわけではありません。テスト環境、統合環境、プリプロダクション環境、段階的リリース環境、正式なオンライン環境は通常、順番に実行されます。これにより、あるブランチがすべての機能が正常に動作することを確認した後に次の環境に渡される限り、機能は一種のファネルのような形でリリースされることが保証されます。Alibaba Cloudには、本番ブランチをまたいだマージ時の機能群を完全に自動化することができる統合プラットフォームがあります。ツールについては、次のセクションで詳しく説明します。

####ルール3: オンライン環境にプッシュした後、対応するブランチをマスターにマージし、マスターにラベルを追加すると同時に、そのプロダクションブランチに関連するフィーチャブランチを削除します。
本番ブランチのパイプラインがオンライン環境へのデプロイを完了すると、対応する機能がリリースされ、本番ブランチがマスターにマージされます。コードリポジトリに古い機能ブランチを蓄積しないようにするためには、すでにリリースした機能ブランチを一掃する必要があります。GitFlow のように、最新のマスターブランチは常に現在オンラインになっているブランチとは異なるものになります。もし以前のバージョンにロールバックしなければならない場合は、マスターブランチの正しいタグを見つけるだけでいいのです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1a124beb-cded-b7d6-2ec6-0a2c8d58db9c.png)

この3つの基本的なルールに加えて、いくつかの不文律もあります。例えば、サービスがオンラインになってからHotfixを適用する場合、通常の運用方法では、オンライン環境に対応した本番環境用のブランチ（本質的にはHotfixブランチ）を新たに作成することになります。同時に、このブランチのための一時的なパイプラインを作成して、リリース前に必要なチェックやテストの実装を自動化する必要があります。

これを行う簡単な方法は、現在のオンライン環境に対応する本番用ブランチから機能ブランチをすべてクリアし、そのブランチを直接修正した後、既存のパイプラインを使用して自動的にリリースすることです。

過去のバージョンのバグを修正しなければならない場合はどうすればいいのでしょうか？この場合は、マスターブランチ上で適切なタグの場所を見つけ、その場所からHotfixブランチを作成します。しかし、Alibaba Cloudの製品のほとんどはオンラインSaaSサービスなので、このような状況に陥ることはあまりありません。

上記で説明したシンプルなルールが、AoneFlowシステムの独自のコアを形成しています。AoneFlowのステップはシンプルに見えますが、単に何もないところから生まれてきたものではなく、数年にわたる経験の蓄積と洗練の産物なのです。次に、AoneFlowの技術的な閾値と、Alibaba Cloudが内部でどのように処理しているかについて少しお話しましょう。

#AoneFlowの最適化
多くの場合、技術の知識だけでは十分ではなく、練習と経験を積むことで新しい技術を習得することができます。Alibaba Cloudでは、当社のチームも同様に、完全なツールセットを使用して優れたコードを開発するために献身的に取り組んでいます。ここでお話しする習慣は、クリーンなコードを書き、ブランチを整理しておくことだけではなく、かなりの数の一般的な慣習も含まれています。

例を考えてみましょう。AoneFlow のプロセスでは、本番用のブランチを再作成するたびに、新しいデプロイメントパッケージを生成するためにコードを再マージしてコンパイルしなければなりません。しかし、コードの内容が異なるため、異なるサードパーティ製のソフトウェアパッケージに依存している場合、最終的な製品が以前とは異なる挙動をする可能性があります。そのため、Alibaba Cloudのコーディング規約では、オンライン本番ブランチのコードでは、スナップショットバージョン（オンラインで利用できないバージョン）の依存パッケージを使用できないことが明記されています。これにより、製品をビルドするたびに同じものであることが保証されています。このように細かいことがたくさんあるので、良い開発習慣を身につけることが製品の品質を確保するための鍵となります。

ツールがあれば、チーム内の連携もスムーズになります。指針を理解していなくても、ブランチの作成、マージ、更新の操作はすべてGitコマンドを使ってAoneFlowで完結させることができます。しかし、いくつかの操作（例えば、本番用ブランチにマージするための正しい機能ブランチを選択するなど）は、手作業によるエラーが発生しやすいものがあります。これらの面倒で複雑な操作を手動で（日常的に）管理することは、生産的な時間の使い方ではありません。

通常、Alibaba Cloudでは、AoneFlowを使用しているチームは、分岐のためにGitを使用する必要はなく、代わりに、Alibaba Cloudで使用するために特別に社内で開発されたAoneと呼ばれるプラットフォーム（以下、プラットフォームと呼ぶ）を使用しています。このプラットフォームは、製品要件の決定からユーザーストーリー、オンラインデプロイまで、チームの作業の80%を処理し、サービスコンポーネントとして組み込まれたいくつかの効率化ツールを搭載しています。その中でも、生産コンポーネントはAoneFlowのユーザーエクスペリエンスを大幅に向上させています。その中でも特にわかりやすいのが、以下に説明する機能を含む「Efficacy」です。

###ワークフロー全体の自動化
社内ツールなので、プラットフォーム全体が驚くほどまとまっています。すべてのプロジェクトオペレーションを一箇所で実行することができます。これには、プロジェクト要件の決定、タスクへの分割、それに応じたオンライン機能ブランチの作成、本番ブランチの統合、テンプレートに沿ったテスト環境の自動作成、本番後の運用・保守までが含まれます。

このプロセスはすでにタスク管理の範囲をはるかに超えて進化しています。しかし、プラットフォームが機能ブランチとプロジェクト要件を一緒にリンクし、機能ブランチの名前がそれに応じて命名されることを保証するのは、まさにこの理由からです。さらに、各環境バージョンのソースの信頼性を確保するために、プロダクションブランチとデプロイの動作を結びつけます。これにより、重要なエンドツーエンドのデリバリーフローが構築されます。

###プロダクションブランチパイプラインの自動化
ワークフローを自動化する方法として、CI/CD パイプラインは多くのデリバリ・チームの間で一般的に使用されています。AoneFlow のライフサイクルにはいくつかのコードブランチがあり、誰かがこれらのブランチのいずれかを作成したり更新したりすると、一連の動作が常に従わなければなりません。パイプラインは、これらの日常的な開発プロセスによって生成されたブランチを、それらが表すディープレイヤーの設計図と接続することができます（例えば、コードを提出し、テストのためにそれを統合します）。特に、AoneFlow の各プロダクションブランチは特定のデプロイ環境にリンクされているので、タイムリーにコードをチェックしてデプロイする必要があります。

理想的な状態では、それぞれのブランチにマッチしたパイプラインを提供する必要があります。AoneFlowの本番ブランチは設定されているので、継続的なインテグレーションはGitFlowの方法よりも簡単です。理論的には、AoneFlowではどのようなパイプラインツールでも利用できます。しかし、Alibaba Cloudの統合プラットフォームでは、パイプラインがコードをレビューしたり、セキュリティのために検査したり、オンラインでデプロイしたりする方法を提供しています。また、Alibaba Cloudチーム内でのAoneFlowの有用性を高めることができます。

###ブランチ接続管理
フィーチャー・ブランチとプロダクション・ブランチの間の接続関係を維持することは、AoneFlow特有の問題です。本番ブランチの分類を決定するフィーチャーブランチを決定することは、本番ブランチが変更する必要があるフィーチャーブランチのグループを知る上で非常に重要であることを覚えておいてください。例えば、特定のプロダクションブランチからフィーチャーを削除する必要がある場合、通常、削除する必要のあるフィーチャー以外のフィーチャーをすべてマージして、そのブランチを元のフィーチャーを置き換えるために使用します。このような情報をすべて記録することは小さな問題ではありませんので、この情報を表示し、プラットフォームを通じて操作を支援することができれば非常に便利です。

低レベルの本番環境(例えば統合テスト環境)に機能群を置く場合、検証が完了したら、その内容をより高レベルの環境(本番前の環境など)に対応するブランチに移行したいと考えています。そうすることで、オンライン版がすでに量産前の検証を通過していることを確認することができます。本番前のバージョンはすでに統合検証を経ており、それに応じてプッシュされ、すべての本番ブランチをチェーンに結びつけます。同様に、この操作は通常のGitコマンドでも実現できますが、グラフィカルなツールを使えば、より直感的に作業を進めることができます。

さらに、プラットフォーム上の各ブランチのコードを統合して表示することが可能で、ブランチに対応したデプロイ環境やマシン情報、操作の記録なども表示されます。これらの「付加価値の高い」支援機能により、AoneFlowはより回復力を高め、アリババクラウドチームの複雑なプロジェクトをサポートする上で重要な役割を果たしています。

#結論
コード分岐のためのワンサイズフィットのアプローチはありません。しかし、重要なのは、プロジェクトのスコープに合わせたリリース率です。アリババクラウドの協調開発プラットフォームであるAoneFlowは、ブランチ管理手法の完全なセットを生成しました。Alibaba Cloudの旗の下にあるすべての製品を確実に納品するために、柔軟性があり、効果が高く、シンプルなワークフローを採用しています。どのブランチ管理方法を使うべきか迷っていて、Gitflowの並行開発機能から離れられない、あるいはTrunkBasedの継続的な統合機能を手放したくない、という場合には、AoneFlowは検討する価値があるかもしれません。

同様の記事を読んで、アリババクラウドの製品やソリューションについてもっと詳しく知りたい方は、[www.alibabacloud.com/blog](https://www.alibabacloud.com/blog?spm=a2c65.11461447.0.0.1f491e10zpmjdn) をご覧ください。

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*