Bitriseを使用したiOSアプリ申請処理のリトライ方法について Now in REALITY Tech #112

今週の「Now in REALITY Tech」は、Bitriseを使用したiOSアプリ申請処理のリトライ方法についてiOSチームからお送りします。

背景

REALITY iOSアプリのリリースサイクルは現状1週間毎にアップデートを行っており、毎週金曜に申請作業を行い、翌週の月曜日にリリースするフローとなっております。
アプリの申請処理はBitrise + fastlaneによって自動化されており、リリースブランチにcommitがpushされるとBitriseのアプリ申請処理用のワークフローが実行されるようになっています。

Bitriseで行うアプリ申請処理のステップは下記となっています。

  1. アプリのクリーンビルド

  2. fastlane gym + pilotを使用してApp Store Connectにビルドをアップロード

  3. fastlane deliverを使用してアプリの申請処理

Bitriseでのアプリ申請処理の課題

このフローにおいて上記3のfastlane deliverでの申請処理が不安定で、下記のようなApp Store Connectへのスクリーンショットアップロードエラーなどによりアプリの申請処理ができない問題がありました。

App Store Connectへのスクリーンショットアップロードエラー

この問題の対処として、fastlane deliverでアップロード処理のタイムアウトとリトライ処理を行うパッチ(修正PR)が追加され、バージョン v2.220.0 にアップデートすることでこのエラーで後続の処理が進まなくなることは少なくなりました。
補足:deliverのパラメータに screenshot_processing_timeout を指定することでタイムアウト時間を指定可能です。タイムアウト時間のデフォルトは3600秒なので調整することをおすすめします。

しかしながら、上記スクリーンショットのアップロードでエラーだけでなく、App Store Connectに新しいバージョンを作成しても即時反映されずエラーになるなど、様々な要因によりdeliverの処理が不安定となっていたため、申請処理を再実行することで解消するケースが多い状況でした。

問題の解決方法

上記問題の対処として、アプリ申請処理でエラーとなった場合に自動でリトライする仕組みを導入しました。
今まではリリース申請担当者が監視し、エラーになった場合に手動でリビルドする必要がありましたが、この仕組みによりリリース担当者の負担を削減することができます。

自動リトライの仕組みについて具体的に紹介していきます。

Bitriseでのアプリ申請処理の自動リトライ方法

変更後のbitrise.yml

初めに自動リトライの仕組みを追加後のbitrise.yml(Bitrise設定ファイル)を下記に示します。
(※一部処理を省略しています)

  submit_review:
    before_run:
    - # 申請前処理
    envs:
    - RETRY_COUNT: ${RETRY_COUNT}
    steps:
    - script@1:
        title: make submit-review
        inputs:
        - content: # 申請処理
    # ①前ステップエラー時にリトライ回数をインクリメント
    - script@1:
        is_always_run: true
        run_if: .IsBuildFailed
        title: increment RETRY_COUNT
        inputs:
        - content: |-
            #!/bin/bash
            echo "Current RETRY_COUNT: $RETRY_COUNT"
            new_retry_count=$(($RETRY_COUNT + 1))
            envman add --key RETRY_COUNT --value "$new_retry_count"
    # ②前ステップエラー時のリトライ処理
    - build-router-start@0:
        is_always_run: true
        # 3回リトライする
        run_if: '{{ .IsBuildFailed | and (not (getenv "RETRY_COUNT" | eq "3")) }}'
        inputs:
        - workflows: submit_review #ワークフローの指定
        - environment_key_list: |-
            RETRY_COUNT
            HOGE(その他環境変数)
        - access_token: "{$Bitriseのアクセストークン}"

①前ステップエラー時にリトライ回数をインクリメント

このscriptステップは、無限リトライになることを防ぐためにリトライ回数をインクリメントし、次のステップのリトライ処理を実行するかどうかの条件に使用します。
リトライ回数は環境変数で保持しておきます。

このステップと次のステップで使用している、is_always_run: true および run_if: .IsBuildFailed が重要で、この設定があることでエラー時にのみステップを実行することができます。
詳細はBitriseドキュメントの下記ページをご参照下さい。
ビルドが失敗した場合にのみステップを実行する

②前ステップエラー時のリトライ処理

このbuild-router-startステップは、同じアプリ内で指定されたワークフローを現在のビルドとは別で新しいビルドとして開始することができます。このステップを実行する条件は上記で示したエラー時にのみ実行する条件に加え、環境変数にセットしたリトライ回数が3であるかどうかを確認し無限リトライを防止しています。

inputsに開始するワークフローの指定、ビルドに渡す環境変数のセット、アクセストークンを設定するだけでビルドを開始することができます。

申請ステップエラー時

わずかなスクリプトと設定で簡易に自動リトライの仕組みを作ることができました!

まとめ

毎週実施する重要度の高いリリース作業をできるだけ機械的に実行できるようにすることで、リリース担当者の負担を減らすことができました。
しかし、申請用ビルドがタイムアウトでAbortした場合は、今回導入した自動リトライ処理は実行されないため、リリース作業の完全自動化を目指して効率的な開発環境の構築を進めていきたいと思います。