web-dev-qa-db-ja.com

継続的デリバリーシナリオでQAによって拒否された機能をロールバックする方法

組織の継続的デリバリーをますます検討しているので、リリースが本番環境にプッシュされる前に手動QAテストを効果的に組み込む方法を理解するのに苦労しています。

branch-per-feature Adam Dymitrukやgit-flowなどで説明されているような複数のアプローチを見つけました。これらはすべて、スプリントごとにセットアップを行うための多くの手動作業を含んでいるようですまたはロールバック操作を実行します。

例を挙げて問題を説明します。

ほとんどのCD文書は、「ハッピー」パスのフローを次のように概説しています。

develop -> CI build -> deploy to QA -> test on QA -> promote to Production

これは簡単に理解でき、問題がなければ問題なく機能します。しかし、本番環境へのデプロイが許可される前に手動テストを必要とする次のワークフローを想定しましょう:開発者1は機能Aで作業し、開発者2は機能Bで作業します。機能トグルを使用して含めることができる機能の。ちょっとした仕事。

開発者1は自分の作業を完了し、すべてをマスター(または同等のリリースブランチ)にマージし、QAにデプロイされるビルドをトリガーします。 QAがテストを開始します。 QAテスト中に、開発者2は作業を完了し、マスターにマージして、ビルドをトリガーします。 QAは機能Aを拒否します。したがって、開発者1からのリリースは続行できません。この時点で、プロセス全体が停止します。機能Aの準備ができていない限り、機能Aから拒否されたコードも含まれているため、機能Bはテストできません。

そして、これは簡単に自動化された方法で修正する方法を私が本当に理解していない部分です。複雑な手動操作なしで、機能Aを効果的にロールバックするにはどうすればよいですか?人々はこれをどのように行うのですか?確かにこれは誰もが直面している問題ですが、私がこれまで読んだ本や回路図はどれもこの問題を実際に扱っているようには見えません。

それをさらに一歩進めます。 GitHubフロー は、機能ブランチを本番環境にデプロイし、本番環境の問題が発生した場合はロールバックすることを提案しているようです。これは単一の開発者、単一のテスターのシナリオで機能する可能性がありますが、複数のテスターが同時に複数の機能に署名した場合はどうなりますか?

開発者1は彼の機能、マスターのブランチを開始し、作業を開始し、マスターにプッシュし、QA 1テストを行います。同時に、開発者2は同じプロセスを実行し、QA 2は彼の機能ビルドをテストします。回路図が与えられた場合、機能Aには機能Bが含まれず、機能Bには機能Aが含まれません。QA1がサインオフすると、機能Aが製品化されます。 QA 2が承認され、機能Bが製品化されます。しかし、機能Aは失われます。はい、それはマスターです。デプロイ後はマージされましたが、機能Cがデプロイされるまで本番環境に戻りません。

GitHubフローは、より大きなチームでどのように効果的に機能しますか?これに関する実用的な例はありますか?

6
Jensen

コード変更Aが拒否された場合、必ずしも「SCCSを使用してマージを元に戻すことによる機能Aのロールバック」の観点から考える必要はありません。 「QAで見つかった欠陥を修正するコードに新しい変更を追加する」という観点から考えてください。

問題によっては、これは次のことを意味します。

  • すぐにバグを修正しますが、Aのコードはマスターのままにします

  • aによって追加された機能を無効にする(機能のエントリポイントを無効にすることにより、「機能の切り替え」を使用することにより)、問題を修正できるまで、関連するコードをマスターに残す

  • aのコード変更をマスターから効果的に削除するコードへの変更の追加-しかし、これはBのようなその後の変更を妨げない方法で

3番目の箇条書きは、必ずしもではありませんが、多くの場合、開発者(およびいくつかの魔法の自動化によるQAチーム)がSCCSを使用し、Aのコード変更を元に戻すことを意味します。このロールバックがBとの衝突を示さない場合、問題ありません。衝突があり、手作業が含まれている可能性があります(AとBが次々に統合されたときの手作業と同等)。

そして、はい、正しい戦略の選択は手動の決定であり、ある程度の時間と手動の作業が含まれます。これは完全に「自動化された方法」ではありませんが、発生するたびに「複雑な手動介入」を必要としません。実際には、問題の修正またはロールバックの範囲は「些細な」から「複雑な」までです。ただし、継続的な配信を目的とする場合は、複雑なロールバックよりも些細なロールバックが頻繁に発生するように努力する必要があります。

このための最良のアプローチは、コードベースの同じ部分に触れる必要がほとんどなくなるような方法で、並行開発の機能を選択することです。さらに、できるだけ多くの自動テストが必要です。したがって、開発者は、コードが「マスター」に到達する前の機能開発中にこれらのテストを実行できます。これにより、QA中の頻繁な表示停止を防ぐことができます。

次に、これらの推奨事項をシナリオに適用します。

機能Aの準備ができていない限り、機能Aから拒否されたコードも含まれているため、機能Bはテストできません。

しかし、なぜですか? AとBが並行開発に適格であった場合、それらは互いにほとんど独立しているため、独立したテストに適格である必要があります。つまり、Aの問題が修正されていなくても、ほとんどの場合Bをテストできます。 QAがAからの深刻なバグを報告し、自動テストでは見逃されたとしましょう。自動テストが失敗しなかったという事実は、少なくともアプリケーションが完全に使用不可にならないことを意味するので、Bのテストから始めることができます。Aの問題が修正されない限り、マスターを本番環境に配信できないことを知っていますが、 Bのテスト中は、上記の3つの方法のいずれかでAを修正またはロールバックするのに十分な時間が必要です。

もちろん、Aの問題を取り除き、コードを「本番環境対応」にするための最も迅速な方法を決定する必要があります。そのため、Bのテストが完了すると、Aの問題に対する修正が既に(または少なくともすぐに)利用可能になり、QAは問題が(Aの機能の有無にかかわらず)なくなったことを承認できます。

タイムラインを見ると、各テストサイクルの後、「マスター」は2つの主要な状態を切り替えることができます。つまり、"既知の欠陥"があるか、"既知の欠陥はもうありません"。 「既知の欠陥なし」という状態に達したら、いつでも本番環境にデプロイできます。継続的な導入作業を行うには、機能のスライスを計画する必要があります"既知の欠陥はもうありません"にできるだけ頻繁に到達する状態。ここでの鍵は

  • 「A」や「B」のような個々の特徴スライスを上からできるだけ小さくします

  • 並行開発用の機能スライスをできるだけ独立して選択する

  • 本番環境への配信を妨げるバグが含まれている場合に備えて、機能スライスを非常に迅速かつスムーズに元に戻すか無効にするための計画

大規模なチーム(おそらく12人以上の開発者)では、マスターの継続的なチェックインが原因で「既知の欠陥がない」という状態に達することはめったにない場合は、追加の「プリプロダクション」(または「ステージング」)マスターブランチでQAによって承認された機能のみが統合されているブランチ。ただし、これは無料ではありません。「実稼働前」で統合を行う別の人が必要です。統合自体を確認するための「実稼働前」での別のQAステップでバグが導入されていないこと、および運用前環境。

8
Doc Brown

手動QAがプロセスの一部である場合、実際には自動リリースパイプラインの一部であってはなりません。 QA環境への自動ビルドとデプロイは引き続き実行できますが、別のパイプラインに配置する必要があります。次に、QAが何かを拒否した場合、ロールバックするものはありません。 「完了」した場合にのみ、リリースパイプラインにデータを送信し、「完了」の定義の一部はQAに合格する必要があります。

これはまた、何かがQAによって拒否されている場合、プロセスに根本的な欠陥があるというより広いポイントを持ち出します。自動化されたビルド、テスト、統合、および展開は、すべての主要な問題をキャッチする必要があります。 QAは実際には探索的テストを行うだけであり、そこから見つかったものはすべて、将来の製品反復のバックログ項目として追加できます。手動でのQAを行う前に、ショーストップのバグを何十もの異なる手順でキャッチしておく必要があります。

パイプラインに戻ると、QAパイプラインとリリースパイプラインがあるということは、コードに複数のブランチがあることを意味します。ただし、Gitでは、「ブランチ」はプルリクエストと同じくらい軽量です。 QAパイプラインは、プルリクエストを統合して、それぞれまたはその任意の組み合わせ(ロールアップ)のビルドとデプロイを開始できます。プルリクエストが手動QAに合格した場合にのみ、実際にそれをマージし、リリースパイプラインを通過させます。

それでも問題が解決しない場合は、ロールフォワードすることをお勧めします。つまり、リリースパイプラインの一部としてQAが必要な場合は、ロールバックしないという戦略にコミットする必要があります。何かが「拒否」された場合は、修正してマージし、パイプラインを通じて新しいリリースをプッシュする必要があります。これは少し危険ですが、適切な設定があれば、頻繁に行う必要はなく、修正は簡単なものでなければなりません。

3
Chris Pratt

これをソース管理の問題と考えないでください。運用と展開の問題と考えてください。不適切なデプロイによって引き起こされた問題を修正するためにコードをコミットする必要はありません。デプロイパイプラインを変更して、問題を修正するために以前のバージョンにロールバックする方法を教えてください。

Googleとfacebookがどのように展開するかを見ることができます。たとえば、Facebookは週に1回新機能を本番環境に出荷し、一般にかなり安定しています。

これをどのように達成するか を見ると、重要な要素は次のとおりです。

  • 出荷前に品質管理を行うためのコードレビューと単体テスト
  • エラーをより早くキャッ​​チするために、外部で起動する前に内部で起動する
  • 新しいバージョンがすべてのサーバー/ユーザーに一度に表示されないように段階的に展開
  • デプロイされたコードを変更せずに、本番環境で新機能または既存の機能の新バージョンをオンまたはオフにする機能フラグ。 Facebookは機能フラグをプロファイルにリンクしているため、ユーザーのプロファイルは、表示する機能セットを決定します。
  • 機能のフラグシステムを利用して、一部のユーザーにのみ新機能を表示するソフトローンチ。これにより、まだローカライズされていない配送機能のようなパターンを実際の使用で焼き上げることができます。
  • ダークラウンチ、シャドウプロダクション、コードの新しいバージョンと新しいバージョン、およびデータベーススキーマをプロダクションで並行して実行するための二重書き込み/読み取り手法。古いバージョンと新しいバージョンが一致するまで、ユーザーは古いバージョンの出力を確認してから、新しいバージョンに切り替えます。
3
Joeri Sebrechts