機能フラグプロセス

ユーザーアプリケーションの機能フラグ

この文書では、GitLab自体の開発で使われる機能フラグのみを扱います。 デプロイされたユーザーアプリケーションにおける機能フラグは、機能フラグ機能文書で見ることができます。

GitLab開発における機能フラグ

機能フラグを活用すべきかどうかを判断する際には、以下のハイライトを考慮する必要があります:

  • デフォルトでは、機能フラグはオフになっているはずです。
  • 機能フラグは、機能フラグ会計の必要性を減らすために、できるだけ短い期間コードベースに残るべきです。
  • 機能フラグをオペレーションする担当者は、機能フラグの背後にある機能のステータスを、責任ある利害関係者に明確に伝える責任があります。 機能フラグが必要であることが明らかになり次第、機能フラグの名前とデフォルトのオンかオフかをissueの説明に反映させる必要があります。
  • 機能フラグに隠された変更を行うマージリクエスト、または機能が安定したとみなされたために既存の機能フラグを削除するマージリクエストには、~”feature flag” ラベルを割り当てる必要があります。
  • 機能の開発が複数のマージリクエストにまたがる場合、以下のワークフローを使用できます:

    1. 最初のマージリクエストで、デフォルトでオフになる機能フラグを導入してください。
    2. 機能フラグがオンの場合にのみ、追加された新しいコードが到達できるように、1つまたは複数のマージリクエストでインクリメンタルな変更を送信します。 開発中は、ローカルのGDKで機能フラグを有効にしておくことができます。
    3. 機能をテストする準備ができたら、特定のプロジェクトの機能フラグを有効にし、実装にイシューがないことを確認します。
    4. 機能を発表する準備ができたら、機能フラグ自体のドキュメントと変更履歴エントリを含む、機能に関するドキュメントを追加するマージリクエストを作成してください。 同じマージリクエストで、新しい動作を有効にするために、機能フラグをデフォルトでオンにするか、完全に削除してください。

機能フラグは機能のリリースを少なくとも1ヶ月(=1リリース)遅らせるものだと思いがちですが、そうではありません。 機能フラグは特定の期間(例えば少なくとも1リリース)存続する必要はなく、その機能が安定していると判断されるまで存続すべきものです。 安定しているとは、GitLab.com上で機能停止などの問題を起こすことなく動作することを意味します。

機能フラグについては開発ガイドもお読みください。

機能フラグの使用時期

GitLab 11.4から、開発者は自明でない変更には機能フラグを使うようになりました。 そのような変更には以下が含まれます:

  • 新機能(新しいマージリクエストウィジェット、エピックなど)。
  • 複雑なクエリの書き換えなど、本番環境での追加テストが必要となる複雑なパフォーマンスの改善。
  • 新しいナビゲーションバーやサイドバーの削除など、ユーザーインターフェースへの侵襲的な変更。
  • サードパーティサービスからのプロジェクトインポートのサポートを追加しました。

すべての場合において、機能フラグが必要かどうかは、その変更に取り組んでいる人たちが最もよく判断できます。 たとえば、ボタンの色を変更する場合は機能フラグは必要ありませんが、ナビゲーションバーを変更する場合は間違いなく機能フラグが必要です。 機能フラグが必要かどうか不明な場合は、マージリクエストでそのことを尋ねれば、その変更をレビューしている人たちが答えをくれるでしょう。

UI要素に機能フラグを使用するとき、もしあれば、その基礎となる_バックエンドコードにも_機能フラグを使用するようにしてください。 こうすることで、その機能が有効になるまで、その機能を使用する方法が絶対にないようにします。

最終リリースに機能フラグの背後にある機能を含めること

最終リリースをビルドし、セルフマネージドユーザのために機能を提供するためには、機能フラグは少なくともデフォルトでオンになっているべきです。 機能が安定していると判断され、機能フラグを削除しても安全であると確信が持てるのであれば、機能フラグを完全に削除することを検討してください。 この決定を下す前に、少なくとも1日間は本番環境で機能フラグをグローバルに有効にしておくことを_強く_推奨します。 この期間中に予期せぬバグが発見されることがあります。

デフォルトで無効になっている機能を有効にするプロセスでは、マージリクエストが最初にレビューされてから変更が GitLab.com にデプロイされるまで、5~6 日かかることがあります。 しかし、予期せぬ問題を考慮し、このアクティビティには 10~14 日を見込んでおくことが推奨されます。

機能フラグは、その状態(有効/無効)に応じて文書化されなければならず、状態が変わったら、それに応じて文書を更新しなければなりません

注意:このようなアクションを行うと、機能フラグへの変更がマージされた直後に GitLab.com でその機能が使えるようになることを考慮してください。

デフォルト状態の変更や機能フラグの削除は、最終的な自己管理リリースに含めるために、_少なくとも_3-4営業日前の22日までに行う必要があります。

これに加えて、機能フラグの背後にある機能が必要です:

  • GitLab.comの全環境で十分な期間実行すること。 この期間は機能フラグの背後にある機能によって異なりますが、一般的な経験則として、十分なフィードバックを集めるには2~4営業日で十分です。
  • その機能は、上記の期間中にGitLab.comプラン内のすべてのユーザーに公開されるべきです。 より少ない割合のユーザーやグループのみにその機能を公開すると、機能の安定性を判断するのに十分な量の情報が公開されない可能性があります。

まれにですが、機能フラグが使われている場合でも、リリースマネージャが安定版ブランチの変更を却下したり差し戻したりすることがあります。 これは、変更に問題があると判断された場合や侵襲的すぎる場合、GitLab.com での変更の挙動を適切に測定する時間がない場合などに必要になることがあります。

機能フラグのコスト

上記を読むと、この手続きは多くの作業を追加することになると考えたくなるかもしれません。 幸いなことに、これはそうではなく、その理由を示します。 この例では、作業コストを0から無限大までの数値で指定します。 数値が大きいほど、作業コストは高くなります。 コストは時間には換算さ_れず_、ある変更と別の変更の複雑さを相対的に測定する方法にすぎません。

もし機能フラグを使わず、意図したとおりに機能すれば、総コストは10になります。 しかし、これは最良のシナリオです。 最良のシナリオのために最適化すると、必ず問題が生じます。一方、最悪のシナリオのために最適化することは、ほとんどの場合、より良い結果をもたらします。

これを説明するために、私たちの機能が障害を引き起こし、すぐに解決する方法がないとします。 つまり、障害を解決するためには、以下の手順を踏む必要があります:

  1. リリースの差し戻し。
  2. 変更内容に応じて、必要なクリーンアップを行います。
  3. コミットを revert して、”master” ブランチが安定していることを確認します。 これは、問題の解決に数日から数週間かかるような場合に特に必要です。
  4. リバートコミットを適切な安定版ブランチにピックし、問題が解決するまで将来のリリースを妨げないようにします。

歴史が示すように、これらのステップは時間がかかり、複雑で、多くの開発者を巻き込むことが多く、そして何よりも最悪なのは、問題が解決されるまで、私たちのユーザーがGitLab.comを使って嫌な思いをすることです。

つまり、私たちが最適化すべき最悪のシナリオでは、総コストは20になります。

もし機能フラグを使っていたら、状況は大きく変わっていたでしょう。 リリースをリバートする必要はありませんし、機能フラグはデフォルトで無効になっているので Git コミットをリバートして選ぶ必要もありません。 実際、私たちがしなければならないのは機能を無効にして、最悪の場合はクリーンアップを行うことだけです。 この場合のコストを 2 としましょう。この場合、最善の場合のコストは 11: 機能のビルドに 10、機能フラグの追加に 1 です。 最悪の場合のコストは 13 となります:

  • 10で機能を構築します。
  • 1 で機能フラグを追加します。
  • 2 を無効にしてクリーンアップします。

最良のシナリオでは、機能フラグを使わない場合と比べて、必要な作業はほんの少ししか増えないことがわかります。 一方、変更を戻すプロセスは大幅に、そして確実に安くなりました。

言い換えれば、機能フラグは開発プロセスを遅らせることはありません。 むしろ、インシデントの管理が_非常に_簡単になるため、プロセスがスピードアップします。 継続的なデプロイが簡単になれば、GitLab.com で変更を利用できるようになるまで何週間も待つ必要がなくなるため、機能の反復にかかる時間はさらに短縮されます。