Всем привет, в этой статье я бы хотел поделиться опытом о том, как наша команда столкнулась со сложностями загрузки dSYM в Firebase Crashlytics, и как мы эти сложности решили. Важно сказать пару слов о нашем стеке: все зависимости установлены через Swift Package Manager, мы используем Xcode 14, а в качестве CI CD мы используем Xcode Cloud с первых дней его релиза.

Предыстория

Вся история началась с сообщения от CTO, в котором он спросил, почему ему, после последнего релиза в App Store, на почту приходит много писем такого рода:

Сообщения о потерянных файлах dSYM.
Сообщения о потерянных файлах dSYM.

Впрочем, помимо CTO такие письма получили все разработчики из разных команд, которые есть в нашем Firebase'e. Чтобы хоть как-то оперативно исправить ситуацию и перестать засорять коллегам почту, я решил отключить email уведомления об этой ошибке на время изучения проблемы. Тогда я узнал, что каждый участник Firebase'а должен самостоятельно отключить для себя эти уведомления.

Отключить уведомления о потерянных dSYM файлах
Отключить уведомления о потерянных dSYM файлах

Кажется, большое количество iOS разработчиков рано или поздно сталкивались с потерянными dSYM файлами, и, как правило, всё сводится к тому, чтобы перепроверить скрипт в Build phase или в CI и вручную догрузить недостающие dSYM файлы. Со скриптом всё было на первый взгляд нормально, поэтому я решил просто скачать из App Store Connect'a dSYM файлы вручную и загрузить их в Firebase Crashlytics, но тут возник нюанс - я не нашёл эти файлы для последних сборок.

Xcode 14 и Bitcode

Незадолго до релиза мы всем составом iOS команды обновились до Xcode 14, а также перевели версию IDE на такую же в нашем релизном workflow в Xcode Cloud. Очевидно, что копать нужно было куда-то туда, и я решил более внимательно изучить список того, что изменилось в последней версии Xcode. Вот что я обнаружил в release notes Xcode 14:

Deprecations

Starting with Xcode 14, bitcode is no longer required for watchOS and tvOS applications, and the App Store no longer accepts bitcode submissions from Xcode 14.

Xcode no longer builds bitcode by default and generates a warning message if a project explicitly enables bitcode: “Building with bitcode is deprecated. Please update your project and/or target settings to disable bitcode.” The capability to build with bitcode will be removed in a future Xcode release. IPAs that contain bitcode will have the bitcode stripped before being submitted to the App Store. Debug symbols can only be downloaded from App Store Connect / TestFlight for existing bitcode submissions and are no longer available for submissions made with Xcode 14. (86118779)

И да, действительно, я зашёл в App Store Connect и увидел, что в Build metadata для сборки, собранной на 13-ой версии, есть dSYM файлы, но для сборки, которая была собрана на последней, 14-ой версии - их нет.

Build metadata для сборок Xcode 13 и Xcode 14
Build metadata для сборок Xcode 13 и Xcode 14

Где и как скачать dSYM

Для того, чтобы скачать dSYM для сборки из Xcode Cloud, я перешёл в интересующую меня сборку в панели Xcode Cloud, и затем, в разделе Artifacts, я скачал iOS архив, который представляет из себя .xcarchive файл. dSYM файлы я обнаружил, когда открыл .xcarchive файл через Show Package Contents и перешёл в папку dSYM. Затем я успешно загрузил всё это в Firebase Crashlytics вручную, но осталась последняя, и самая интересная часть - это автоматизация процесса загрузки.

Скачать iOS архив интересующей сборки из артефактов Xcode Cloud
Скачать iOS архив интересующей сборки из артефактов Xcode Cloud

Автоматизация загрузки dSYM в Xcode Cloud

Для того, чтобы написать скрипт, который бы автоматизировал процесс загрузки dSYM в крашлитику, нужно было понять, как встроить эту логику в workflow нашего CI. Как известно, в Xcode Cloud существует 3 вида скриптов, каждый из которых будет выполнен в определённый момент времени. Подробно о custom builds scripts, и как их добавить в ваш workflow отлично описано в документации.

Виды скриптов в Xcode Cloud
Виды скриптов в Xcode Cloud

В нашем случае, интересует именно post-xcodebuild скрипт, который будет выполнен после успешной сборки. Далее, нам необходимо понимать, как мы можем получить доступ к upload-symbols скрипту от Firebase (документация), который и будет выгружать наши dSYM. В Xcode Cloud существует набор некоторых переменных, к которым мы можем обратиться в любом из скриптов – речь о Environment variables. Здесь я не буду разбирать каждую из переменных, они, впрочем, отлично описаны в самой документации. Для нашей задачи нам понадобиться всего лишь две:

  • CI_DERIVED_DATA_PATH - это именно тот каталог, углубившись в который можно найти upload-symbols скрипт. * Аналогичный каталог вы можете найти и у себя локально в /Library/Developer/Xcode/DerivedData/Your build;

  • CI_ARCHIVE_PATH - это путь к .xcarchive файлу, про который я рассказывал выше. Это то самое место, откуда мы будем забирать свежие dSYM файлы.

Наш скрипт должен делать всего лишь одно действие: запускать upload-symbols скрипт с правильными аргументами (валидный путь к .plist и dSYM). Вот, что у меня получилось:

#!/bin/sh
set -e
if [[ -n $CI_ARCHIVE_PATH ]];
then
    echo "Archive path is available. Let's run dSYMs uploading script"
    # Move up to parent directory
    cd ..
    # Debug
    echo "Derived data path: $CI_DERIVED_DATA_PATH"
    echo "Archive path: $CI_ARCHIVE_PATH"
    # Crashlytics dSYMs script
    $CI_DERIVED_DATA_PATH/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols -gsp /GoogleService-Info.plist -p ios $CI_ARCHIVE_PATH/dSYMs
else
    echo "Archive path isn't available. Unable to run dSYMs uploading script."
fi

Впрочем вот и всё, давайте запустим workflow с этим скриптом и посмотрим на логи. Скрипт выполнен успешно и dSYM файлы загружены в крашлитику.

Логи из Xcode cloud
Логи из Xcode cloud

Дополнительно

Если вы столкнулись с подобным warning'ом, то обратите внимание на информацию из документации Apple:

Important

Xcode Cloud uses zsh as its default Unix shell. As a best practice, always include a shebang in the first line of your custom build script; for example #!/bin/sh.

Обязательно измените тип вашего файла на исполняемый, это можно сделать с помощью команды:

chmod +x ci_post_xcodebuild.sh

На этом всё, наш скрипт готов. Благодарю за внимание и буду рад ответить на интересующие вопросы.

Комментарии (1)


  1. postNullone
    22.11.2022 13:27

    Отличная статья! Спасибо!