207 Tech Blog

テクノロジーで物流を変える 207 (ニーマルナナ) 株式会社のテックブログ

Expo Bare Workflow × EAS で実現する、デプロイ頻度改善の取り組み

この記事は React Native Advent Calendar 2021 の4日目の記事です。

はじめに

207株式会社では配送員の方向けのアプリであるTODOCUサポーターをReact Nativeで開発しています。 iOS/Android向けのアプリとして提供しており、 Expo Bare Workflow の状態で開発しています。
expo-updates も積極的に利用し、 先日プレビューが終わり正式版になったEAS についても、プレビュー段階から利用し、現在ではEAS BuildとEAS Submitも使っています。*1
Expoの提供するサービスを積極的に利用することで、高い頻度でユーザーへ機能を届けることができるようになっています。
この記事では、TODOCUサポーターチームで行っているデプロイフローを紹介し、皆さんの現場のReact Nativeアプリをよりよくするための参考になればいいなと思います。

OTAアップデートと解決したかった課題

TODOCUサポーターはReact Native x Expo Bare Workflow ( expo init から eject した状態)で開発しています。ejectしてない状態のことをExpo Managed Workflowと呼びます。*2
Expoの機能の1つに expo-updates というOTAアップデートの仕組みがあり、これを利用することでアプリストアの申請を介すことなくエンドユーザーへ最新の機能を届ける事ができます。

ExpoによるOTAアップデートを図示したもの
OTAアップデートの概念*3

簡易的な仕組み的としては、JavaScriptコードをExpoのサーバーに保存し、アプリはサーバーからJavaScriptのコードをダウンロードして反映することでアプリを動的に変更しています。

すべての機能を変更できるわけではなく、 Native Modules を利用する変更はJavaScriptだけでは完結しないため、OTAアップデートすることができません。 *4

Bare Workflowでアプリ内に Native Modules が無いのにOTAアップデートをユーザーに配信した場合、ネイティブの機能を呼び出そうとしても参照先が存在しないためクラッシュしてしまいます。 ここを防ぐためには、ネイティブ側の変更があった場合はリリースチャンネルを変更し、ストアにリリースする、というフローを入れる必要があります。*5

この複雑さもあり、リリースフローが固まっていなかったため、TODOCUサポーターの開発チームではデプロイ頻度が低いという問題がありました。

TODOCUサポーターのリリースフロー

基本的にはGitHub Flow を採用しつつ、ストアリリースが必要な機能に関しては release ブランチを作成するフローになっています。

リリースフロー
リリースフロー

main ブランチにコードをマージした時点で、CI/CIのパイプラインで .env ファイルに記載されたExpoのリリースチャンネルへOTAアップデートを配信するようにしています。

また、 release ブランチを作成した時点で .env ファイルのリリースチャンネルを変更して各ストアに申請をしています。

ポイントとしては、

  1. ストア申請〜承認&公開までの間でもリリースを止めないようにしたかった
    ストアへ公開が完了するまでは release ブランチを残すようにし、ビジネスの要件を取りこぼさないようにした
  2. "リリース大臣" のような、特定の人に依存しない仕組みにしたかった
    何かしらの機能に不具合があり、revertしたいときでもrevert PRを作って main ブランチにマージしたら誰でも対応できるようにした
  3. 今は何がリリースされているのか?というコミュニケーションを減らしたかった
    現在のフローになる前は git flow を利用しており、何をリリースしているのか?というコミュニケーションがよく発生していたので main ブランチの状態=エンドユーザーに提供されている状態にした

図にしてみるとシンプルですが、TODOCUサポーターチームにはQAチームがいるため、リリース前にQAを行い品質を担保するようにしていたり、リリース直前にプロダクトマネージャーへ連絡してユーザーへの周知などを引き継ぐ、などを行なっています。

今後実現したいこと

まだまだ道半ばで、今後実現したいことがたくさんあります。

  1. ios/ or android/ ディレクトリ以下の変更があった場合、Expoリリースチャンネルの変更を矯正する
    最近はストアリリースが必要な機能が減ってきており、基本的にOTAアップデートで運用しているために、ネイティブ側コードの変更が必要なことが少ないので目視で確認(PRの承認者の数は複数人になっています)になっており仕組みで解決できていないので、ここは優先して改善したいところ。
  2. ストアリリースの自動化
    ASOの観点から、定期的にストアに申請したいという要件があるため、GitHub Actionsでスケジュール実行する取り組みを現在行っています。
    ここはEAS Submitを利用するようにしていて、残りはバージョンコードを上げるコードを書くだけ、という状態です。

その他、EASの機能で利用していること

また、生産性を高めるために様々な取り組みをしています。雑多に書くと以下のような取り組みです。

  • GitHubでPRを作成したら、自動でEAS Buildが実行されてPRごとにプレビューできる環境の用意
    PRを開いたタイミングでPull Requestにリリースチャンネルを分離したビルドを作成し、PushごとにOTAアップデートを配信することでプレビューができるような環境を作成しています。ほぼ公式のexampleで実現可能です。TODOCUサポーターチームでは、このexample + ビルドしたURLをPRにコメントする処理を追加しています。
    github.com

  • 非エンジニアでも各環境ごとのビルドを作成する環境の用意
    GitHub Actionsの workflow_dispatch を利用して、非エンジニア(PdMなど)でも最新のコードで各環境のビルドを作成できるようにしています。

    GitHub上でビルドをトリガーする
    GitHub上でビルドをトリガーする

参考にしたドキュメント

  • OTAアップデート
    詳細な情報は公式によくまとまっているので、こちらも参照してもらうとより理解が深まるかもしれません。
    docs.expo.dev

おわりに

怖くないよ、Bare Workflow ということが伝われば幸いです。

207株式会社では、レガシーな物流業界の変革に挑む配達員向け効率化アプリ「TODOCUサポーター」を開発しています。 開発チームでは一緒に開発してくれるアプリエンジニア(React Native)やバックエンドエンジニアの仲間を大絶賛募集中です!

もし少しでもご興味がありましたら、以下のnotionをご覧ください!

www.notion.so

*1:EAS Buildについては簡易的ですが、記事も書いています EAS Build を使っている話

*2:詳細な違いは公式ドキュメントを参照してください

*3:アイコンはこちらを利用しています

*4:その他の制限事項は公式にまとまっています。

*5:1日目の記事にも記載されていますが、EXUpdatesRuntimeVersionを変更する方法もあります。TODOCUサポーターでは、リリースチャンネル(EXUpdatesReleaseChannel)を変更するフローにしています。1日目の記事もとても良くまとまっているのでおすすめです!