web-dev-qa-db-ja.com

複数の部分配信を伴う大規模プロジェクトのMonorepoとmulti repo

デリバリーパイプラインとリリースパイプラインをスムーズにするためのオプションを検討しています。ソースコードを構造化するための最良の方法についてアドバイスをいただければ幸いです。

これは、約30のマイクロサービスで構成されるかなり大きなプロジェクトです。ここでのマイクロサービスは非常に緩い用語ですが、問題としては十分に近いものです。現在、このすべてが1つのリポジトリに格納されています。

内部ワークフローは次のように構成されています。

すべてのコードがdevブランチにコミットされる1か月のスプリント。月末に、テストに移行する必要のあるすべてのタスクが"次のメジャーリリース"ブランチにマージされ、クリティカル/バグであるすべてのタスクが"アクティブデリバリー"ブランチにマージされてテストされ、お客様に選択的にロールアウトされます。

変更に伴うリスクを軽減するために変更をできるだけ少なくしたいため、すべてのお客様が最新かつ最高のものを必要としているわけではありません。

したがって、月末には次のようになります。
1つの最新の開発ブランチ
1つの部分的に最新のテスト/次の配信ブランチ
1つの製造ブランチ

そして、これはこのように顧客に展開されます:
お客様A
-インストールされた本番ブランチバージョン11
*本番ブランチ11.4からのオーバーライドされたマイクロサービス3
*本番ブランチ11.1からのオーバーライドされたマイクロサービス5
* ...

顧客B
-インストールされた本番ブランチバージョン11.6
*本番ブランチ11.14からのオーバーライドされたマイクロサービス7
*本番ブランチ11.7からのオーバーライドされたマイクロサービス15

顧客C
-インストールされた本番ブランチバージョン11.3

マルチレポセットアップに変更すると、明らかに非常識な配信パイプラインに対応できますか?サービスごとに1つのレポと、顧客ごとに1つのレポを検討しています。

コードリポジトリ:
-MicroService 1
-MicroService 2
-MicroService 3

顧客レポ:
-MicroService 1へのリンク-バージョン1.5
-MicroService 2へのリンク-バージョン2.5
-MicroService 3へのリンク-バージョン1.7
-顧客固有のデータファイル(現在、バージョン管理されていません...)

これによりワークフローが大幅に改善され、ブランチが1つしかないという洞察に戻ると思います。これにより、実際に顧客にリリースされるものをより適切に制御できるようになり、環境を実際に再現できるようになります。最も重要なのは、月1回のマージの必要がなくなることです。

私はこれについていくつかのフィードバックを大いに期待します。

編集:APIはサービス間でかなり安定していますが、共有ライブラリは少々複雑です。約25年前の製品なので、コアは安定していますが、技術部門が徐々に構築されているため、ある程度のクリーンアップが必要なことをイメージできます。

基本的に私が解決/改善しようとしている2つの問題があります

  1. マージの日は地獄です。本番ブランチはdevブランチよりも最大1年古い場合があり、devブランチのマージのサブセットのみがマージされます。現在のバージョンにはないはずの新機能がdevに追加された場合、これは本番環境に移行されません。これからのコードを使用するdevのすべての修正は、移動する必要がある場合に大きな問題を引き起こします。私の考えでは、複数の小さなリポジトリがあると、これが簡単になります。

  2. サーバーに顧客データを取得するためのバグがあるとします。バグはいくつかの共有ライブラリにあり、私はそれを修正し、CustDataServerと他のすべてのサーバーを構築します。これは、これによって影響を受けると考えられ、次に顧客/顧客のシステムに展開します。これは、誰かが次にバグ修正を行うときに、たまたま私の最後のバグ修正を使用した場合、基本的に意図せずに意図せずにそれを本番環境にリリースすることを意味します。ほとんどの場合、これで問題ありませんが、実際に運用環境で何が実行されているかを制御できないように感じます。 ServerAはSharedLibAとSharedLibBを使用してビルドされますが、ServerBは同じ共有ライブラリを使用してビルドされますが、他のバージョンです。マルチリポジトリアプローチは、少なくともこの場合、より多くの制御を与えるだろうという印象を受けています。

私はこの混乱を片付ける方法についてのあらゆる種類のアイデアを受け入れています。

編集:私はこれまでのところすべての応答を感謝しています。ここでは、レポスタイルの選択は問題ではないことに同意します。

あなたの概要は、レイアウトリポジトリからのかなりの場所にあります。それを紹介するつもりでした。現在、クライアント固有のファイル(ほとんどの場合、dbおよびconfigファイル)はクライアントサーバーに格納されており、ソース管理の形式にはありません。

リリースサイクルに関しては、より頻繁にリリースすることが最善のアイデアであることに同意します。また、部分的なリリースは行わないでください。全部かゼロか。問題は、リリースサイクルが私の管理外にあるということです。私は多くのことに影響を与えることができますが、社内にあるものにのみ影響します。外部的には、変更を加えることは困難です。部分的で不十分なリリースの理由は、クライアントのリスクを軽減するためです。つまり、変更が少ないほど、新しいバグが発生する可能性は低くなります。このソフトウェアは非常に重要であり、バグにより1日あたり数百万ドルの損害が発生する可能性があります。

これを別の方法で試した場合、システムを、存在する制約を使用して作成されるものとして説明するとしたら、それを構造化するための理想的な方法は何でしょうか?

  • 論理的に複数のユニットに分割されているが、(密に)結合されている大きなコードベース
  • 毎年の新機能のリリース。
  • 機能は、ローカル変更とシステム全体の新機能の混合です
  • バグは、数時間以内に重大な場合、できるだけ早く修正する必要があります。
  • 完全なリリースを望まないお客様は、変更をできるだけ少なくしたいと考えています。実際、彼らはしばしば年次リリースを望まず、可能な限りそれを引き出す
  • 重要なソフトウェア、バグは高価です

問題点の数を制限するために内部ワークフローを構成する最良の方法は何でしょうか?

6
user1038502

1つまたは多くのリポジトリが問題の原因ではないようです。

それはあなたの分岐戦略です。

  • 可能であれば、gitflowなどの認識されている分岐戦略に切り替えます。

  • 本番の問題のバグ修正を書いている場合。本番環境から(修正プログラム)ブランチを作成します。開発ブランチや次のリリースブランチではありません。

  • 「次のリリース」ブランチが1年間マージされていない場合。それをマージしようとさえしないでください。それを新しい「本番」ブランチにしましょう。

  • チェリーピッキングマージを停止します。ブランチ全体をマージするか、まったくマージしない。さまざまなブランチがあなたが暗示するほど分岐している場合は、おそらく、ブランチごとに個別にそのバグ修正を作成する必要があります。

マイクロサービスの異なるバージョンを展開している顧客に関して。これは問題にならず、ソース管理に関連するべきではありません。

バージョン管理されたデプロイメントをソース管理とは別に保存します。バイナリにコンパイルしない場合でも、ソースコードと製品を区別する必要があります。

ソース管理からコードをチェックアウトして展開しないでください。ソフトウェア+構成と何らかのデプロイスクリプトを使用してZipファイルを作成します。 CDに投稿する必要があると想像してください。

ライブ環境では、ダウンタイムなしの展開などを可能にするために複数のバージョンが展開されていると思います。

各バージョンがテストされ、これと互換性のある他のどのバージョンも問題にならないと述べている限り。

3
Ewan

@DocBrownがコメントで指摘したように:

元の質問

複数の部分配信を伴う大規模プロジェクトのMonorepoとmulti repo

ここでは本当の質問ではないかもしれません。

もっと真ん中に、あなたは書きます

マルチレポセットアップに変更すると、明らかに非常識な配信パイプラインに対応できますか?

これは質問につながります:

非常識な配信パイプラインに対処する方法。

最初に、あなたの現在の状況をよりよく理解するためにいくつかの事実を集めようとします:

  • 製品の現在の状態を何らかの形で表す1つのソースリポジトリがあります。

  • コードが論理的にいくつかのユニットに分割され、それらが(密に)結合されている

  • 別の支店があります

    • 開発者
    • 製造
  • さまざまな顧客向けのいくつかの「レイアウト」(リポジトリ)
  • 1か月の長さのスプリント

次の2つの大きな問題があります。

1)マージ日

2)何が本番環境に入るかをより詳細に制御


もちろん、現状を1つのサイズですべてに当てはめることは困難です。現状を比較的よく説明している場合でも、30000フィートのビューよりも複雑であるため、ここで説明しました。

ここで提供できるのは、いくつかの考え/アイデアです。

全体的な目標:すべてのお客様に1つの現在のコードベースを提供

I)リリースサイクルに取り組みます

実動バージョンと開発バージョンの間にどのような理由で大きなずれがあるのか​​、私にはわかりません。

より頻繁に製品をリリースする機会はありますか?リリースの頻度が高いほど、ドリフトは小さくなり、マージは容易になります。

II)アプリケーションの構成可能性に取り組みます

あなたが書いたものから、バージョン間の違いが何であるかは明らかではありません。アプリケーションをより構成可能にすることは、どういうわけか可能ですか?そのため、顧客は常に製品の最新バージョンを入手できますが、必要に応じて機能がダウングレードされる可能性があります。

もちろん、私が理解していることは、構成オプションが多ければ多いほど、対処しなければならない複雑さが増すということです。これはあなたの人生を楽にする必要はありませんが、私は一貫性があり、統一されたコードベースを扱いやすくすることの利点をあなたの状況での勝利と見ています。

III)お客様のすべてのサーバーで実行される1つのコードベースがある場合、本番環境にあるものとそうでないものを知っています。したがって、2番目の問題点は消えます。

だが:

正直なところ、これらのアイデアがどれほど実現可能であり、どれだけの労力を費やさなければならないのか、全体が努力に値するのかどうかはわかりません。

あなたは良い支払い顧客と事実を持っているので、あなたの製品は(基本的に)25年間走っています-そしておそらくおそらくもう何年も続くでしょう-あなたは小さなステップを踏むでレースに勝つために長期

開始点として、構成可能なオプションを使用して1つの現在のサービスの1つのバージョンをすべての顧客が実行するのにどれだけの労力が必要かをテストできます。また、構成の複雑さのコストはどのくらいか。


元の質問について:

Monorepoを使用してください。物事が見た目と同じくらい密に結合されている場合、それはより良いでしょう。


編集:

おそらく、あなたはWordの「リリース」をもう少し創造的に解釈する必要があります。 Releaseは、リポジトリ内の固定されたポイントであり、リリースブランチには、多くの構成のすべてのコンポーネントのワーキングセットがあります。

つまり、一部の顧客はリリースを(隔年)年に1回、他のユーザーはより頻繁にリリースしますが、リリースウィンドウ内の顧客は同じ実行コードを取得します。あなたの目標は次のとおりです。常に、現在のリリースのロールアウトを待機しています。

導入された欠陥の数も少ないと想定しているため、お客様は安定性に関心があり、小さな変更を好むことを理解しています。

しかし一方で、顧客は、製品が機能することを期待し、保証できる限り-例えばタイトなテストスイート-大規模な更新を行っても問題はありません。 N°1懸念事項は、(新しい)欠陥をできるだけ少なくし、すべての(リリースの時点まで)既知のバグを修正することです。

余談:私は過去2.5年間、あなたの条件ほど厳しくはありませんでしたが、同様の条件で作業しました。 6つの顧客、基礎となるアプリケーションの6つの異なるフレーバー。基礎となるアプリケーション自体は、独自のリポジトリにある7つ以上の個別のアプリケーションで構成されていましたが、後から考えて、プロジェクトに最初から参加している場合は、密結合のため、すべてのリポジトリに投票します。少なくとも毎月のリリースがありました。しかし、物事が積み重なって、すべてをリリースするのは難しすぎました。すべてのプロジェクトが事実上常に「最新」で実行されるように、「リリース」をロールアウトまたはアクティブ化することから独立させる戦略を提案しました。

この戦略が開発者に少し安心をもたらすことがわかりました。

1
Thomas Junk