アプリケーションコードを超えて:CI/CDを設定、モバイル、フィーチャーフラグに拡張する
アプリケーションコード、データベースマイグレーション、インフラプロビジョニングにCI/CDパイプラインが構築され、デプロイはスムーズになり、ロールバックも高速化し、チームは安心して夜を過ごせるようになりました。しかし、まだ何かが足りないという感覚が残っているかもしれません。
問題は小さな形で現れます。チームメイトがステージング環境のデータベース接続文字列を変更する必要があるとします。修正自体は簡単で、設定値を更新するだけですが、設定がコードに埋め込まれているため、フルデプロイサイクルが必要になります。あるいは、モバイルチームが新しいバージョンをリリースしたものの、アプリストアのレビューに3日かかり、誰もその遅延を想定していなかったケース。または、ユーザーに段階的にロールアウトする予定の機能が、再デプロイなしでは制御する仕組みがないため、完全にオンか完全にオフのどちらかになっているケース。
これらは例外的なケースではありません。多くのCI/CD実装でひび割れが生じ始める領域です。幸いなことに、パイプラインを設定、モバイルアプリ、フィーチャーフラグに対応させる方法は、何に注目すべきかがわかれば簡単です。
設定を独立した配信パスとして扱う
多くのチームは、アプリケーションコードと一緒に環境変数や設定ファイルに設定を保存することから始めます。これはうまくいかなくなるまで機能します。ある環境の値を変更するだけで、他の環境に影響を与えないようにする必要が生じたとき、設定とコードではライフサイクルのニーズが異なることに気づきます。
設定の変更にビルドは不要です。フルテストスイートの実行も不要です。アプリケーションを再起動するようなデプロイも不要です。データベース接続文字列、APIキー、フィーチャートグル値はコードではありません。それをコードのように扱うと、不必要な摩擦が生じます。
解決策は、設定をコードから分離し、独自のパイプラインを与えることです。このパイプラインはアプリケーションコードのものよりもシンプルです。
- 設定値の変更がリポジトリにコミットされる
- 変更はコード変更と同じレビュープロセスを経る
- 承認されると、設定が対象環境に適用される
- アプリケーションは再起動せずに新しい値を取得する
重要な違いは、設定パイプラインがビルドとテストの段階をスキップすることです。コンパイルやユニットテストの対象はありません。重要なのは、設定が適切なサーバーに到達し、アプリケーションが動的にそれをリロードできることです。
このアプローチは監査も容易にします。すべての設定変更はバージョン管理で追跡され、ピアレビューを受け、パイプラインを通じて適用されます。サーバーにSSHでログインして値を変更し、誰にも気づかれないことを願う必要はもうありません。
モバイルパイプラインには異なる制約がある
モバイルアプリケーションは、デプロイしようとするまでは他のソフトウェアプロジェクトと同じように見えます。ビルドプロセスでは、デジタル署名が必要なインストーラファイルが生成されます。配信は独自のレビュープロセスを持つアプリストアを通じて行われます。そして、一度バージョンがユーザーの手に渡ると、アップデートを強制することはできません。
これらの制約により、パイプラインの設計方法が変わります。ビルドとユニットテストの段階はバックエンドアプリケーションと同じように機能します。しかし、デプロイ段階では2つの独立したパスが必要です。
最初のパスは内部配信用です。アプリストアにビルドを送信する前に、チームは実機でテストする必要があります。Firebase App Distribution(Android向け)やTestFlight(iOS向け)などのプラットフォームを使用すると、アプリストアのレビュープロセスを経ずに、QAチームやベータテスターにビルドを配布できます。パイプラインは、新しいバージョンがテスト可能になったら、自動的にこれらのプラットフォームにビルドをアップロードする必要があります。
2番目のパスはプロダクションリリース用です。ここでパイプラインは署名済みビルドをGoogle PlayストアまたはApple App Storeに提出します。パイプラインはレビューにかかる時間を制御できませんが、ステータスを追跡することはできます。レビューが承認されると、パイプラインはユーザーへの実際のリリースをトリガーできます。
モバイルパイプラインのリスクゲートには、モバイル固有のチェックを含める必要があります。証明書の有効期限、署名鍵の有効性、バージョン番号のインクリメントはすべて自動的に検証されるべきです。期限切れの証明書を持つビルドはアプリストアで拒否され、レビューを待った後にそれを知るのは苦痛です。
フィーチャーフラグで段階的ロールアウトを実現する
フィーチャーフラグは、新しいコードをデプロイせずに機能をオン/オフできる仕組みです。これは一般的な問題を解決します:機能は完成したが、すべてのユーザーに対して準備ができているか確信が持てない場合。もっとテストが必要かもしれません。まずはユーザーのごく一部にロールアウトしたいかもしれません。何か問題が発生した場合に迅速に無効化できるようにしたいかもしれません。
フィーチャーフラグがない場合、選択肢は限られます。確信が持てるまでデプロイを遅らせる(これによりデリバリーが遅くなる)か、最善を期待してデプロイする(リスクが高まる)かのどちらかです。フィーチャーフラグは第三の選択肢を提供します:機能を無効化した状態でデプロイし、その後段階的に有効化する。
フィーチャーフラグをパイプラインに追加するには、2つの変更が必要です。
まず、パイプラインはコードが両方の状態で正しく動作することを検証する必要があります。機能がフラグでラップされている場合、テストはフラグが有効な状態と無効な状態の両方で実行されるべきです。これにより、フィーチャーフラグのロジック自体にバグがある場合や、無効化状態が既存の機能を壊す場合を捕捉できます。
次に、パイプラインは不要になったフラグのクリーンアップを支援する必要があります。コードベースに永久に残るフィーチャーフラグは技術負債になります。複雑性を増し、コードを読みにくくし、バグのリスクを高めます。ベストプラクティスは、一定期間すべてのユーザーに完全ロールアウトされたフラグをチェックし、自動的に削除タスクを作成するパイプラインステージを追加することです。
パイプライン拡張のための実践的チェックリスト
これらの変更を実装する前に、以下のチェックリストを確認して注意が必要な領域を特定してください:
- アプリケーションを再デプロイせずに、特定の環境の設定値を変更できますか?
- すべての設定変更はバージョン管理で追跡され、適用前にレビューされていますか?
- モバイルパイプラインは内部テスターに自動的にビルドを配布していますか?
- モバイルパイプラインは証明書の有効期限と署名鍵の有効性を検証していますか?
- フィーチャーフラグは有効状態と無効状態の両方でテストされていますか?
- 不要になったフィーチャーフラグを削除するプロセスはありますか?
これらのいずれかに「いいえ」と答えた場合、明確な次のステップがあります。
まとめ
CI/CDは、アプリケーションコードがスムーズにデプロイできた時点で完了ではありません。ソフトウェアの動作に影響を与えるすべての変更(コード、設定、フィーチャートグルのいずれであっても)が、制御され、自動化され、監査可能なプロセスを通過した時点で完了です。設定パイプラインは環境固有の変更の摩擦を取り除きます。モバイルパイプラインはアプリストア配信の独自の制約を処理します。フィーチャーフラグはデリバリーを遅らせることなくリスクを制御する能力を提供します。
今日チームが最も苦労している領域から始めてください。ほとんどのチームにとって、それは設定管理です。それが機能したら、チームが何をリリースしているかに応じて、モバイルまたはフィーチャーフラグに移行します。目標は初日から完璧なパイプラインを構築することではありません。目標は、何も見落とされないようにすることです。