BitriseでのdSYMのアップロードに試行錯誤した話（Bitcodeなし & SPMでFirebaseを利用している場合）

# 初めに

いま担当しているAppでは、CIにBitriseを利用しており諸々の運用プロセスを自動化しています。

- Bitrise
    - ユニットテスト実行・AppStoreへのアップロードetc..を自動化
- Firebase Crashlytics
  - FirebaseパッケージはSwift Package Managerで取得
- dSYMアップロードは[Fastlaneのdownload_dsyms](https://docs.fastlane.tools/actions/download_dsyms/)を利用してコマンドを一発叩くのみ

そんな環境下でdSYMアップロードが出来なくなったというトラブルの対処法について記しておきます。

# 経緯

### BitcodeをOFFにする

あくる日にAppStoreへのアップロードを実行したところ、下記のエラーメッセージとともにバイナリが無効と判定されアップロードが失敗しました。

![スクリーンショット 2022-12-02 17.53.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231066/e7e4fc00-2a62-06e6-9c3b-298c75864830.png)
`
ITMS-90562: Invalid Bundle - One or more dynamic libraries that are referenced by your app are not present in the dylib search path.
`

[AppleのForum](https://developer.apple.com/forums/thread/701949)で類似事象を参照するとConcurrencyを導入していて、なおかつBitcodeがONになっていると発生する模様。

早速BitcodeをOFFにし再度アップロードしたところ無事成功。
[Xcode 14 Release NotesのDeprecations](https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes)にあるようにBitcodeが非推奨となっているのでBitcodeは恒久的にOFFにすることにしました。

ちゃんちゃん。


### FastlaneでのdSYMの取得に失敗している

ところが後日、AppStoreでのAppリリースと同時にFirebase CrashlyticsへのdSYMのアップロードを行おうとしたところ失敗。

![スクリーンショット 2022-12-02 17.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231066/88fbb888-d899-34ac-4359-c708f0c80792.png)
`Couldn't find any dSYMs, please pass them using the dsym_path option`

どうやら[BitcodeをOFFにしたことでAppStoreからのdSYMダウンロードができなくなったこと](https://qiita.com/temoki/items/92999fcede0a7b89760f)が原因の模様。

ということでFastlaneでdSYMをダウンロードするフローはやめることとしました。

### Firebase dSYM UploadはSPMで取得したFirebaseには対応していない

Bitriseでは[Firebase dSYM Upload](https://github.com/andrewmarmion/bitrise-step-firebase-dsym-upload)というworkflowが[Workflow Recipes](https://github.com/bitrise-io/workflow-recipes)上に公開されています。
こちらへ切り替えることでBitcode=OFFの場合でのdSYMアップロードが実行できそうだったので、早速組み込む作業に取り掛かりました。

![スクリーンショット 2022-12-02 17.27.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231066/d268e7bf-f04a-64db-caf3-95fad3c00840.png)

ところが...
このworkflowではFirebaseのパッケージをCocoapodsのキャッシュディレクトリ経由で参照する仕様となっており、Swift Package ManagerでFirebaseのパッケージを取得している場合にはそのまま利用することができませんでした。
利用したい場合には、[こちら](https://fromkk.me/n/n860cefffadde)で紹介されているようにxcodebuildのオプションでキャッシュディレクトリを変更してあげる必要があります。

ですが、AppStoreへのアップロード時のみdSYMアップロードを実行できればよいので、影響は最小限にしておきたいという考えから既存の[Xcode Archive&Export](https://github.com/bitrise-steplib/steps-xcode-archive)などのフローには手を加えない方針とし、「一旦、手動にしとくか...」という方針になりました。

しかし、ひと手間掛けたところで美味しくなるようなものでも無いので、やっぱり自動化しておきたい...
ということで。

# シェルスクリプトでやってしまおう

やりたいこととしては、

- upload-symbolsを持ってくる
- xcarchiveファイルからdSYMを取ってくる
- upload-symbolsを実行する

ということなので、これをBashで書いてしまってscriptのworkflowで実行すれば良さそうと判断しました。

- upload-symbolsを持ってくる

[FirebaseのGitHubリポジトリ](https://github.com/firebase/firebase-ios-sdk.git)にupload-symbolsのバイナリもきちんといたので、`git clone`して持ってくることとします。

- xcarchiveファイルからdSYMを取ってくる

こちらは`$BITRISE_XCARCHIVE_ZIP_PATH` からpathを取得できるので指定は簡単です。

結果としては以下のような実装を行いました。

```bash
### xcarchiveのパス・ファイル名の定義
xcarchive_package=MyApp.xcarchive
xcarchive_file=${xcarchive_package}.zip
### プロジェクト内のGoogleService-Info.plistの在り処を把握しておく
google_info_path=$BITRISE_SOURCE_DIR/MyApp/Supporting\ Files/GoogleServices/MyApp/GoogleService-Info.plist
### Firebaseリポジトリでのupload-symbolsのパス
upload_symbols=./firebase-ios-sdk/Crashlytics/upload-symbols

### プロジェクトのディレクトリへ移動
cd $BITRISE_SOURCE_DIR/MyApp

### GitHubのFirebaseのリポジトリからclone
echo "download binary from GitHub"
git clone https://github.com/firebase/firebase-ios-sdk.git

### upload-symbolsのバイナリの実行権限を変更しておく
chmod 755 $upload_symbols

### xcarchiveのファイルをcurrentにコピーしておく
cp $BITRISE_XCARCHIVE_ZIP_PATH .

### xcarchiveのzipファイルを展開
echo "extract App xcarchive file"
unzip $xcarchive_file

### upload-symbolsの実行
$upload_symbols -gsp "$google_info_path" -p ios ./$xcarchive_package/dSYMs
```

このスクリプトで無事アップロードも自動化出来ました。

自身でメンテナンスすることを考えると極力Workflow Recipesで公開されているworkflowを使うのが良いと思うので、可能な限りWorkflow Recipesにあるworkflowを使ってあげたいところです。
ですがかゆいところに手の届かない、という状況の場合はscriptのworkflowを活用していきましょう。