羊をめぐるブログ

趣味の色々について書きます

Bitrise上でExpo OTA

はじめに

これは2021年振り返りカレンダーの4日目の記事です.

前回は,はじめてBitriseを用いてreact-nativeのCI/CD環境を構築する(新春SP)という内容でした.

serenard.hatenablog.com

Expoには Over The Air (OTA) update という,審査を通さなくてもアプリのアップデートを 配信できる機能があります. 細かいが致命的なバグなどを緊急に修正したい場合には,2,3日かかってしまう審査を 通さずにすぐ修正版を配信できるので便利です.

前回の記事ではOTAを実行するワークフローの構築については省略したので, 今回はそれについて書こうと思います.

OTAってなんぞってときには以下が,

docs.expo.dev

Expo OTAの仕様の詳細については以下がとても参考になりました.

zenn.dev

仕様

今回はreact-native (expo bare workflow) で開発しているiOSアプリのOTAを行います.

環境はstgとprdの2つあるとします.

OTAは緊急時に行うデプロイ手段のため,自動トリガーではなく,手動でトリガーすることとします.

実装

Expo projectの作成

Expo OTAを行うには,ExpoアカウントとExpoのプロジェクトが必要です.

https://expo.dev/へ行き,Create new projectからプロジェクトを作りましょう.

今回はserviceという名前で作ったとします.

Bitrise上でOTAワークフローの構築

先ほど作成したアカウントとプロジェクトを用いてOTAワークフローを作ります.

以下が全体像です.

f:id:sheep96:20220118233958p:plain

多くの部分は前回解説した部分と同じなので,異なる部分を解説していきます.

Expo publish

ここではOTAを行っています.内部では以下のスクリプトを実行しています.

  1. expo-cliをインストール
  2. 先ほど作成したexpoアカウントにログイン.パスワード,ユーザ名はsecretに保存したものを参照する.
  3. OTA配信を行う.release-channelを指定することにより,dev環境にだけ配信するようにする.

とてもシンポゥーです.

#!/usr/bin/env bash
# fail if any commands fails
set -e
# debug log
set -x

# expo publish
npm install -g expo-cli
expo login -u $EXPO_USERNAME -p $EXPO_PASSWORD
cd ui
cp .env.dev .env
expo publish --release-channel dev

prdについては,release-channelをprdにするだけです.

ワークフローの実行コマンド

こちらについては,前回解説したワークフロートリガー用のweb apiを叩くことで行います.

以下のようなものをdev, prd環境ごとに用意します.

#!/bin/bash

function deploy_ui_ota() {
  TAG_NAME=$2
  command="curl https://app.bitrise.io/app/hogehogehoge/build/start.json --data '{\"hook_info\":{\"type\":\"bitrise\",\"build_trigger_token\":\"hogehogehoge\"},\"build_params\":{\"branch\":\"production\",\"workflow_id\":\"deploy_ota\",\"tag\":\"${TAG_NAME}\"},\"triggered_by\":\"curl\"}'"
  eval $command
}

$1 $@

実行は以下のような感じです.

sh deploy.sh deploy_ui_ota v0.0.0

OTAで間違えてバグを配信した時

こちらが参考になります.

docs.expo.dev

手段としては以下が考えられそうです.

  • バグを修正して新規バージョンをリリース
  • バグが入ってない箇所までバージョンをロールバックし,OTAリリース(Expoは常に最新のOTAがないかを見に行くため.バージョンを落としても,リリースが後ならば取りに行く.)
    • https://qiita.com/kaba/items/b6e777d1c0b7ce1f78c6 の記事によるとExpoは1回の起動で1個しかOTA updateを確認しに行かないため,ユーザは1回はバグバージョンを見ることになる(バグをとってきた次の起動時に修正後を取りに行く).
  • expoのロールバックコマンドを利用する.
    1. expo publish:history --platform ios で過去のバージョンを取得.
    2. expo publish:set --release-channel prd --publish-id id で指定したバージョンに戻す.1個前ならばexpo publish:rollback --release-channel production --sdk-version 36.0.0も使える.

その他細かい知見など

  • OTAしたバージョンが1つしかない場合,ロールバックや他のビルドへの移動ができないため,再度OTAを行うか,Expoプロジェクトを削除するしかなさそう.
  • 自分は間違えて1度v999.0.0をOTA配信し,ユーザにアップデート通知が出ない状態にしてしまいましたが,バージョンを修正したものを再度OTAすることでことなきを得ました.
  • プロジェクトページからだとOTA履歴が見れないので,あったら嬉しい.
  • 一応BitriseにもExpo ejectというpublishを行うステップはあるが,release-channelを設定できない.

最後に

Expo OTAをBitrise上でワークフロー化する内容について書きました.とても便利で心強いOTAですが, 少し間違えると想定してないものを配信してしまったりするので,注意が必要です. ローカルで実行しようとするとExpoアカウントやrelease-channelの切り替えが必要になりますが, 今回のようにワークフロー化することで,手間やミスを減らせるんじゃないかと思います. 間違ってる部分は往々にしてありそうなので,ぜひお伝えいただけると嬉しいです.