2FAが有効なアカウントで fastlane を使ってApp Store Connectへアプリをアップロードする方法

4 min read読了の目安(約3900字

2021年2月以降、App Store Connectを利用する全てのアカウントで2FAによる認証が必須になるようです。
これまでCI用に2FAを有効にしていないアカウントで対応していた方もいたかと思いますが、その方法が今後は取れなくなります。
2FAが有効なアカウントではSMS認証などで発行された6桁の番号をその都度入力する必要があるのですが、CIで使う場合は自動で動いているので当然入力ができません。

今回は fastlane を使っている場合の対処方法を紹介したいと思います。

fastlaneにおける対処方法

1. App Store Connect APIを使う

fastlaneではApp Store Connect APIに対応しており、
これを利用すれば簡単に解決します。CI用アカウントも不要になるため、2FAも不要になります。

2. fastlane spaceauth で FASTLANE_SESSION を発行して利用する

以下のコマンドを実行することで、FASTLANE_SESSION を発行することができます。
ここで発行されたセッション情報を FASTLANE_SESSION という環境変数に登録することで、
2FAの追加認証をパスすることが可能になります。

fastlane spaceauth -u <CIアカウントのApple ID>

但し、この FASTLANE_SESSION には期限があります。
1ヶ月でセッションの期限が切れてしまうので、その都度更新する必要がでてきます。
セッションが切れたかどうかをビルド開始前に検知できればいいのですが、
毎回そのようなことは面倒でやってられないかと思います。

例えばリポジトリへのタグPushで本番ビルドがGitHub Actionsで実行されるようになっている場合は、
ローカルで FASTLANE_SESSION を生成し、それをGitHub APIで secrets に書き込んでからタグPushを行うスクリプトを作っておけば、
CI実行前に最新の FASTLANE_SESSION へ更新することは可能となるため、期限のチェックをする必要もなくなります。

このように、FASTLANE_SESSION を使う方法は少々面倒ですが、fastlane の全ての機能を利用するにはこの方法しかないようです。
もし App Store Connect APIで利用できない fastlane の機能(download_dsymsなど)を利用するケースであればこの方法を選択する必要があります。

3. App用パスワードを使う

実はアプリをTestFlightへアップロードするだけであればApp Store Connect APIも FASTLANE_SESSION も利用する必要はありません。
CI用アカウントでApp用パスワードを生成しておき、それを環境変数 FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD に設定するだけで2FAの追加認証をパスできます。

私の利用ケースだと、アプリはTestFlightへアップロードして
そこで動作確認をしてから手動で審査提出をしており、アップロードだけできれば十分だったのでこちらの方法でも良さそうです。

どの方法をとるべきか

2の方法はセッションの期限を管理するのが面倒なので、download_dsymsを使わないのであれば、1か3の方法がおすすめです。
今回はこの1および3の方法を fastlane へ設定する方法を紹介します。

App Store Connect APIを使う場合の fastlane の設定方法

1. App Store Connect APIキーを発行する

App Store Connectへログインし、「ユーザーとアクセス」→「キー」→「App Store Connect API」からキーを発行できます。
但し、発行するには Admin 以上の権限が必要です。(App Manager以下の権限だと上記の「キー」のリンクが表示されません)
APIキーの権限(アクセス)については、アプリのリリースだけであればApp Managerがあれば十分なので、App Managerにしておきます。
このとき、 p8 ファイルが1度だけダウンロード可能なので、ダウンロードしたら即バックアップしておきましょう。
また、Issuer IDと発行したAPIキーのキーIDもコピーしておきます。

2. CI環境に キーID、Issuer ID、APIキーの環境変数を追加する

環境変数名は何でもよいですが、CI環境に キーID、Issuer ID、APIキー(p8ファイルの内容)を追加しておきます。
私のケースでは、

ASC_API_KEY_ID→ キーID
ASC_API_ISSUER_ID → Issuer ID
ASC_API_KEY_CONTENT → APIキーの内容

というようにしました。

3. fastlaneの設定を記述する

fastlaneでTestFlightへアップロードする際の設定を以下のように記述します。

api_key = app_store_connect_api_key(
  key_id: ENV['ASC_API_KEY_ID'],
  issuer_id: ENV['ASC_API_ISSUER_ID'],
  key_content: ENV['ASC_API_KEY_CONTENT'],
)
upload_to_testflight(
  api_key: api_key,
  skip_submission: true,
  skip_waiting_for_build_processing: true,
  ipa: "<アップロードするIPAファイルのファイルパス>",
)

upload_to_testflightをこの例では利用していますが、upload_to_appstoreでも同様の方法でAPIキーを指定します。
これでCI環境で2FAの追加認証をパスしてアップロードが可能になります。

App用パスワードを使う場合の fastlane の設定方法

1. CI用アカウントでApp用パスワードを発行する

以下のURLからCI用アカウントでログインし、「セキュリティ」→「App用パスワード」のところにある「パスワード生成」からパスワードを発行します。

https://appleid.apple.com

2. CI環境に環境変数 FASTLANE_USER と FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD を追加する

CI環境の環境変数に FASTLANE_USER と FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD を追加します。
FASTLANE_USERにはCI用App Store ConnectアカウントのApple ID(メールアドレス)を設定します。
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD には 1 で発行したApp用パスワードを設定しておきます。

3. fastlaneの設定を記述する

fastlaneでTestFlightへアップロードする際の設定を以下のように記述します。

upload_to_testflight(
  apple_id: "<アプリケーションのApple ID>",
  skip_submission: true,
  skip_waiting_for_build_processing: true,
  ipa: "<アップロードするIPAファイルのファイルパス>",
)

アプリケーションのApple IDというのは何かというと、
App Store Connectへログインし、「マイApp」から対象アプリを選択し、「App情報」→「一般情報」にあるApple ID (数値)のことになります。
当初このApple IDがCI用App Store ConnectアカウントのApple ID (メールアドレス)だと思っていましたが、そっちではなくアプリの方のApple ID (数値)になります。
fastlaneのリポジトリではこの apple_id にメールアドレスを設定している例もあったので issue を漁るまでわかりませんでした・・・ややこしい!

あとはCIで fastlane を実行すれば2FAの追加認証をパスしてアプリのアップロードが出来るようになります。

まとめ

2FAの追加認証をパスしてCIでApp Store Connectへアプリをアップロードする方法を紹介しました。
2021年2月から2FAが必須になるので、CI用アカウントを使っている方はお早めに対処することをおすすめします。