ClickUpにおけるFlutter CI & CD
Engineering at ClickUp

ClickUpにおけるFlutter CI & CD

拡大を続けるモバイルチームと週次リリースを実現するには、信頼性の高いCIパイプラインが不可欠です。アプリをビルド・テストし、App StoreとGoogle Playストアにデプロイする能力が必要です。また、最新機能をテストするための内部プレビューバージョンも維持しています。

当社がClickUpFastlaneGitHub Actionsを活用して継続的インテグレーション(CI)と継続的デリバリー(CD)を自動化する手法をご紹介します。

バグの生涯 🐜

まずは、バグの管理と修正のプロセスを簡単に説明しましょう。

  1. バグ(または機能リクエスト)が報告されると、ClickUpにタスクが作成されます
  2. タスクは開発者に割り当てられ、ステージングブランチに対するプルリクエストで修正されます。
  3. CIは全テストを実行し、アプリをビルドし、ウェブプレビューをデプロイし、すべてをClickUpタスクにアップロードします。
  4. QAチームが修正内容を確認し、問題がなければタスクは完了としてマークされます。
  5. プルリクエストは自動的にステージング環境にマージされます
  6. ステージングブランチはビルドされ、社内TestFlight環境にデプロイされます。
  7. 毎週水曜日にリリースブランチが作成され、ビルドとテストが実行されます
  8. 毎週金曜日、GitHub上でリリースを作成すると、CIが自動的にApp StoreとPlay Storeへデプロイします。

ClickUpタスクにはバグに関するすべての情報が含まれます。進行中やコードレビューといったカスタムステータスを使用してバグを追跡します。CIワークフローが自動的にステータスを変更します。カスタムフィールドには、バグ報告者、担当者、リリース予定日などの追加情報が記録されます。

PRワークフロー 📜

上記で説明した最初の2つのステップは厳密にはCIに関連しませんが、3つ目のステップは興味深いものです…

開発ワークフローはすべてのプルリクエストに対して実行されます。AndroidおよびiOSアーティファクトのビルドを開始する前に、リンティングやフォーマットチェックを実施し、全てのテストを実行します。

ビルドが成功すると、CIはリンクされたタスクにメッセージを投稿します。QAエンジニアはプルリクエストに移動し、ビルド成果物をダウンロードするか、ウェブプレビューを利用できます。

CIはリンクされたタスクにメッセージを投稿します
ビルド成功後にリンクされたClickUpタスクに投稿される自動化されたCIメッセージ

ビルド成功後にリンクされたClickUpタスクに投稿される自動化されたCIメッセージ

CIランナーでのFlutter設定 🛠

CI環境でのFlutter設定には、広く知られたGitHubアクション「subosito/flutter-action」を利用しています。デフォルトで最新の安定版Flutterがインストールされます。新バージョンのFlutterリリース時にCIワークフローが壊れるのを防ぐため、バージョンを手動で指定する必要があります。

複数のワークフローがある場合、Flutterのバージョンはファイルに保存することをお勧めします。リポジトリのルートディレクトリにFLUTTER_VERSIONを使用しています。

別の簡単な解決策は、FlutterのバージョンをGitHubシークレットとして保存し、{{ secrets.FLUTER_VERSION }}を使用してアクセスすることです。

Webプレビュー 🕸

FlutterがWeb上で動作する特性により、プルリクエストの完全な機能を備えたWebプレビューを作成できます。device_previewパッケージを使用することで、デバイスのサイズや設定を調整可能です。

プレビュー機能は非常に有用であることが実証されており、QAチームだけでなく、デザイナーやプロダクトマネージャーも新機能の迅速な反復開発に活用しています。

Flutterでの完全機能を備えたWebプレビュー
via Flutter

via Flutter

ウェブプレビューの作成方法 🐶

開始するには、アプリがFlutter Webと互換性があることを確認してください。すべてのAPIがサポートされているわけではありません。

例えば、当社のアプリではプッシュ通知とWebソケットを無効化する必要がありました。

このサンプルワークフローでは、FlutterアプリのWebプレビューをビルドし、S3バケットにアップロードします。本番環境では`ENABLE_DEVICE_PREVIEW`環境変数を使用して`device_preview`を無効化しています。

Fixのbase hrefステップが必要な理由は、プレビューがバケットのルートディレクトリに配置されないためです。

そして、条件付きでdevice_previewを有効にするためのコードもいくつか。

環境変数は強力なツールであり、Flutterのツリーシェイキングアルゴリズムがリリースビルド向けにデバッグコードを削除することを可能にします。

Fastlane 💨

FastlaneはFlutterアプリのビルド、署名、デプロイを大幅に簡素化します。証明書、プロビジョニングプロフィール、その他の設定を管理します。パスワードやトークンはGitHubシークレットでセキュリティを確保して保管しています。

便利なFastlaneアクション:

iOS開発ビルドのサンプル 🍏

setup_ciを忘れないでください。これで奇妙なエラーから救われます👾。Flutterアプリ向けFastlaneの詳細はこちらです。

Android署名 🔒

Androidリリースビルドをセキュリティを確保して署名する最も簡単な方法は、トークンをGitHubシークレットとして保存し、環境変数とCIで生成された一時鍵を使用することです。

鍵となる jks ファイルを Base64 エンコードされたストリングとして GitHub Secrets に保存し、ワークフロー内でデコードします:

リリース&本番環境ワークフロー 🚀

リリース前のワークフローは、`release/v`で始まるブランチに対して実行されます。デバッグ用コードや内部コードをすべて除去し、リリースされるコードと同一のコードを確実にテストします。

さらに、リリース前のワークフローでは、着信webhookを使用してQAチームとマーケティングチームに新リリースを通知するため、複数のSlackチャンネルへ投稿します。

すべてのテストを徹底的に実施した後、GitHub上でリリースを作成し、本番ワークフローをトリガーします。これによりアプリがビルドされ、本番環境用証明書で署名された後、App Storeへ送信されます。

CIをもっと活用するコツ 🦾

GitHub Actionsのプッシュトリガーを使用する場合、同じブランチに短時間で複数のプッシュがあると問題が発生する可能性があります。複数のワークフローインスタンスが起動し、ビルド時間を消費したり、その他の問題を引き起こしたりします。

要約 🍩

CIの構築は楽しいプロセスです。簡単に始められ、進めながら進化させられます。当社のCIはClickUpのコアバリューの一つ「完璧に向けて前進する」を体現しています。QAチームとエンジニアリングチームのために、CIの改善を絶えず進めています。

ClickUp、GitHub Actions、Fastlaneの組み合わせは非常に強力で、1時間未満で柔軟かつ完全に自動化されたCI/CDパイプラインを構築できます。ぜひお試しください!

今後、多くの興味深いトピックを準備中です。ClickUpエンジニアリングブログをぜひチェックしてください!🦄