web-dev-qa-db-ja.com

リリースに適した分岐戦略の選択

新しいプロジェクトの新しい開発チームから始めて、ソースリポジトリの分岐戦略を定義する必要があります(例:Microsoft Team Foundation Server 2010)。私たちは、するべきかどうかについて、粘り強い議論に遭遇しました...

[〜#〜] a [〜#〜]Releaseブランチを1つ用意し、そこから本番ビルドを行い、実際に何かがリリースされたときにLabelにします

OR

[〜#〜] b [〜#〜]。本番環境への新しいリリースごとに新しいReleaseブランチを作成します(Ex。バージョン1、2、3など...

オプション[〜#〜] a [〜#〜]は簡単なようですが、これが長期的に問題を引き起こすかどうかはわかりません。オプション[〜#〜] b [〜#〜]は、時間の経過とともに蓄積される1回限りの長命のブランチをたくさん作成するようです。

誰かが私たちが決めるのを助けることができるいずれかの方法で何か経験がありますか?具体的には、1つの選択肢のどこが問題かを聞きたいと思っています。 TFSやリリース管理の影響に関連する特定のエクスペリエンスを自由に提供してください。

11
JoeGeeky

オプションA.リリース用にメインラインとタグを使用するだけ

長所:

  • あなたはマージ地獄を避けます。
  • メインラインを維持することで、適切なリリース計画のようないくつかのベストプラクティスを奨励します。多くのWIPを導入せず、抽象化による分岐を使用してアウトオブバンドの長期作業を処理し、オープンクローズドシステムと構成可能な機能を使用して作業を管理します。進行中の可能性があります。またはしないかもしれません。リリースするため、または完全なロールバックを回避するために、現在または将来無効にする必要があります。

短所:

  • 進行中の作業への対処が問題となり、リリースの時期になると潜在的な表面攻撃の領域に追加されます。ただし、開発者が統制されている場合、新機能は構成可能でモジュール化されているため、簡単に無効化/有効化できます。または、WIPがなく、各リリースポイントですべての作業が完了するか、まだ開始されていません(スクラム)。
  • 大規模/帯域外の変更では、実装するために事前にもっと考える必要があります(たとえば、抽象化による分岐)。

個人的に私はこのアプローチを好みます。コードカバレッジとユニットテストは、ドアを開ける準備ができていないコードを特定する必要があり、現在の反復中にリリースされないコードで作業するべきではありません。抽象化やその他のメカニズムによる分岐は、長期的な変更や進行中の作業に対処するために使用できます。

これを行わないと、マージの問題、古いコード、リリースされない機能などに対処するようになります。

オプションB.リリースごとに分岐

長所:

  • 現在の反復が受け入れテストのラウンドを完了する間、次の反復の作業を開始できます。
  • 他のものは確かです。

短所:

  • たくさんの枝。
  • まだリリースポイントでブランチにタグを付ける必要があります。
  • WIPを処理し、WIPを作成しない場合は、以前のリリースブランチから次のリリースブランチにWIPをマージする必要があり、リリースブランチを無効化またはヤンクして、受け入れテストを再実行する必要があります。
  • ホットフィックスはより多くのブランチに適用する必要があります(ブランチ+ホットフィックス+新しいタグ+ホットフィックスをvnextブランチにマージし、ホットフィックスがどこにあるかに応じてvnextnextをマージする可能性があります)。

私はこのソリューションの大ファンではありません^ _ ^。

一般的には、メインラインに固執することをお勧めします。開発者がカットに失敗したときに簡単にヤンクできるWIPを作成できない、または次のリリースの早い段階でチェックされるWIPを作成できない場合は、コードの完了と分岐が必要なポイントでコードのタグ付けについて話し始めることができます。必要に応じて、開発者の単体テストで検出できなかった見落としがちな不具合やバグに対処する必要があります。

理想的には、それが例外プロセスであり、ルールではないことを望んでいると思います。

オプションC.クレイジーボーナスオプション

派手になりたい場合は、ユーザーストーリーごと/機能ごとの分岐モデルを検討することもできます。 (TFSまたは非DVCSでのひどいアイデアであると同時に、gitやMercurialなどのDVCSを使用している場合、信じられないほど簡単に実装できます)。

過去に、svnからMercurialに簡単に移植できないレガシーコードベースで作業していた以前の雇用主メンテナンスチームのために、以下を実装しました。リリースをより適切に調整するだけでなく、常にリリース可能なメインラインのビジネス要件を満たすために、多くの不要な作業が必要でした。 。 。

  1. 機能は、チームの開発ブランチの開発者によって開発されました。
  2. 機能をピアレビューする準備ができたら、開発者はそれをバンドルして、DevブランチからCRブランチへの単一のマージにまとめ、タイトルに機能ID /ユーザーストーリーを含めます。 *プリコミットフックによって強制*
  3. CRを通過した後、管理ツールを使用して機能をQAブランチにプロモートします。 (私は、さまざまな受け入れ段階に存在するユーザーストーリーをリストし、オペレーターがそれらの受け入れ段階の間にそれを昇格または降格できるようにする小さなターミナルアプリケーションを作成しました)
  4. QAは、自動化および手動のユーザビリティテストを実行します。機能が良ければ、リリースブランチ(メインライン)にプッシュされます。機能が拒否された場合、開発者がテスト中に持ち込まれた問題に対処し、パッチをCRブランチに追加するまで、QAブランチから降格/復帰します。
  5. コードがQAブランチから戻され、修正が適用された場合、ターミナルツールは必要な変更を再適用して、機能をCRブランチからQAブランチに戻し、QAがコードを再確認してプロモートするか、もう一度降格します。
  6. どの時点でも、リリースブランチは安定した解放可能な状態である必要があります。
  7. リリース後、新しいDev、QA、およびCRがメインラインからスピンされます。
15
Keith Brings

公開するリリースごとに別々のブランチがあります(年間約4)。特定のリリースをプルする必要がある場合に非常に便利です。

いくつかの古いリリースを維持する必要がある場合、ラベル付けがそうなるとは思いません。特定のリリースブランチでは、他のリリースを気にすることなく、各ブランチに個別に(または選択したブランチに)ホットフィックスを適用できます。

また、バグや機能がいつ導入されたかを探すときに、リリースの比較がはるかに簡単になります。

ブランチの数や、ブランチが変更されずに経過する時間について心配する必要はありません。あなたのバージョン管理システムはあなたに制御を与え、あなたのプロジェクトの開発の歴史を提供することです。歴史は変わらない傾向があります...そして、あなたのCVが対応できないことを心配しないでください。私たちは、開発ブランチでPERFORCEの9000以上のファイルを使用しています。私たちが取り組んでいるリリースでは最大50の開発ブランチを使用し、すでに述べたように、公開するリリースごとに1つのブランチを使用します。 PERFORCEは、これ以上呼吸をしていません。

簡単に言うと、開発者/メンテナ/バグフィクサー/問題ハンターとしての生活を楽にし、ブランチの数やファイルの数を気にしないでください。自尊心のあるCVはすべて対応します。

編集:

支社の数に関しては、混乱はまったくありません。リリースブランチの命名スキームと、開発(または作業)ブランチの1課題1ブランチポリシーは、それと関係があるかもしれません。

リリースブランチは、保持するリリースに応じて名前が付けられます。つまり、リリース2011 Service Pack 1のR2011SP1です。私たちの作業ブランチには、あまり知名度の低い名前があります:sub01、sub02、sub03など。「sub」は、すべての作業ブランチがサブブランチであることから来ています受け入れブランチの。受け入れブランチは、リリースの準備ができているすべての問題が収集されるブランチです。

1課題1の作業ブランチポリシーと、問題追跡システムが「ブランチ」フィールドでカスタマイズされているという事実を組み合わせることで、どのブランチでどの問題が開発されているかを常に把握できます。問題が承認ブランチに統合されると、このフィールドが更新されます。これは、どの問題がリリースの準備ができているかを常に知っていることを意味します(受け入れテストが行​​われた後)。同様に、リリースブランチが作成されたときにこのフィールドを更新します。これにより、問題がリリースされたリリースを常に追跡できます。

6
Marjan Venema

それはすべてコンテキストに関するものです。リリースする頻度とリリースの内容。

[〜#〜] b [〜#〜]メソッドを使用して、以前の作業で私が持っていたケーススタディの一部を以下に示します(これを目的別ブランチ)と呼びます )。

ストーリーを文脈に当てはめるには、

  • リリースは私たちのソフトウェアの新機能で構成されていました:新しいゲームモード、新しい機能、新しい設定オプション。
  • リリースサイクルはかなり長かった:クライアントは、通常1年間1つの機能セットを使用する大学でした。

特定のリリースで機能が完全な状態になるまで、主な開発はトランクで行われました。その時点で、projectname-january2012のようにブランチを作成し、そのブランチで品質テストとバグ修正を行います。公開リリースの準備ができたら、そのブランチのコードにタグを付けてリリースします。

ただし、リリースの開発はそのタグで終了しませんでした。必然的に、リリースにバグや小さな問題を見つけたクライアントがいました。したがって、その場合は、そのブランチに戻り、コードにパッチを適用して、january2012ブランチの新しいタグ付きバージョンを作成するだけです。リリースされ、修正がトランクにマージされます。

私たちのケースでは、一部のユーザーが機能の制限された古いリリースを使い続けることを好むため、または単に修正プログラムではなくまったく新しいバージョンをインフラストラクチャにデプロイするコストが原因で問題が発生したため、このアプローチは好都合でした。

だから、あなた自身に尋ねなければならない質問は:

  • どのくらいの頻度でリリースしますか?
  • 私のリリースは100%下位互換性がありますか?
  • クライアントはバグを修正するために完全にアップグレードしても大丈夫ですか?

頻繁にリリースする場合は、それぞれにブランチを用意する価値はありません。ただし、リリースサイクルが私の古いユースケースのようにかなり長く、その展開、下位互換性、および古いリリースに固執するクライアントがリスクになる可能性がある場合、オプション[〜#〜] b [〜#〜]確かにあなたは多くの苦痛を節約し、ブランチの乱雑さを扱う最小限のコストで物事をクライアントをサポートすることをずっと簡単にします。

2
Bushibytes

私はオプションAを好みます。安定した状態で、トランクおよびブランチリリースで開発してください。これにより、製品リリースに適用されるホットフィックスの統合作業が大幅に制限されます。

私は、オプションBを試みたチームが軌道に戻るのを支援するように契約しています。

考慮すべきいくつかのこと。

  • ホットフィックスをすべてのアクティブなコードブランチに移行します。これは、マージ、パッチ、および/または再開発によって行うことができます。修正が適切なすべてのリリースに適用され、トランクに適用されるように、これらを完全に管理する必要があります。
  • メインコードストリームから分離して機能を開発できるように、機能ブランチを検討してください。これらは実験的な変更を推奨します。機能が機能しない場合は、機能ブランチを放棄してください。
  • マージポイントにタグを付けて追跡します。
  • 必要に応じてリリースを分岐させます。これは通常、リリースがリリース候補ビルドの準備ができているときです。場合によっては、トランクに互換性のない変更を導入すると、強制的に早期分岐が発生する可能性があります。機能ブランチを考えてみましょう。
1
BillThor

過去にオプション(B)を効果的に実装するためにTFSを使用しました。

分岐/マージは、細かく分割する場合に最適なツールです。問題は、ブランチを作成すること(それはばかげて簡単です)にも、1週間分の作業をツリーに戻すことにも(通常は簡単にも)ありません...ソース管理の背後にあるCIシステムを自動的に機能させることです。君は。

システムがブランチのテストを自動的に構築および実行していない場合、ブランチ化は無意味だからです。

変更セットの相対パスを認識するようにTFSの既定のビルドワークフローをカスタマイズし、カスタマイズが新しいブランチを認識することができる規則を確立しました(開発ルートの下の単に新しいサブフォルダーではありません)。それはスムーズで、ブランチが簡単で、ブランチを強制終了するのも簡単で、コンパイルとテストのためにシステムから継続的なフィードバックを得ました。

多くの人々がこれらの戦略がTFSの下でどれほど不可能であるかを宣言しているのを見ていますが、それはXAMLベースのビルドエンジンの可能性に精通していないためだと思います。 TFSは単なるソース管理ではなく、ソリューション全体であり、そのまま使用する必要があります。

0
Craig Brunetti

私は何年もの間、あなたが説明した2つのスキームの間に何かを使用するシステムに取り組んできました。重要なのは、マルチレベルの番号付けスキームが使用されていることです。外部レベルは基本的にAPIバージョンであり、それはブランチで管理され(複数のブランチで何かを修正する必要がある場合は適切なクロスマージで)、内部レベルは行われた正確なリリースであり、タグで管理されます。

特に、顧客が持っている正確なバージョンがわかっている場合は、コードのビルド元のソースが正確にわかっているため、正確な複製を作成して、何が起こっているのかを正確に確認できます。これはサポートにとって非常に重要です!しかし、ブランチの外側のレベル、つまり現在リリースされているAPIバージョンは、時間の経過とともに進化します(開発の主要なトランクに新機能の大部分が追加されます)。また、APIの新しいメジャーリリースを行うときは、それをサポートするための新しいブランチを作成し(トランクは常にハードコア開発指向にすることができます)、現在の最も古いサポートがサポート終了になるかどうかを検討しますブランチ。

したがって、実際には[〜#〜] a [〜#〜][〜#〜] b [〜#〜]の両方が混在するものをお勧めします。どちらも良い面がありますが、どちらもそれ自体では完全ではありません。両方の長所を活用します。

0
Donal Fellows