Everything I wish I’d known when creating our mobile dev pipeline, Adam Breece

В своем втором докладе Адам рассказал о том, как в компании FlowPlay решены проблемы, связанные с необходимостью установки на тестовых мобильных устройствах (как iOS, так и Android) ночных сборок разрабатываемых приложений, а также с автоматизацией релиза приложения в мобильных сторах.

Видеоверсия доклада доступна на официальном сайте Haxe.

Тестовый проект и слайды презентации можно загрузить с гитхаба.

Первая задача, которую было необходимо решить, это построение процесса внутренних релизов приложения для команды тестирования. При этом должны были соблюдаться следующие требования:

  • автоматическая “ночная” сборка приложения;
  • возможность сборки приложения по необходимости, например, когда в “ночной” сборке присутствует ошибка, ведущая к падению приложения, а в репозитории уже внесено ее исправление;
  • возможность установки приложения непосредственно с мобильного устройства. Особенно это актуально для iOS-устройств, когда установка приложения возможна только с Mac’а;
  • наличие отладочных символов (debug symbols), позволяющих расшифровать логи ошибок в приложении.

Очевидно, что для решения этой задачи стоило бы воспользоваться продуктами, предоставляемыми компаниями Google (Google Play alpha и beta) и Apple (TestFlight).

Однако при их использовании возникли следующие проблемы:

  • могло пройти до 24 часов прежде чем тестовая сборка становилась доступна в TestFlight. К тому же в работе TestFlight несколько месяцев наблюдались перебои, и в Apple не могли решить эту проблему;
  • по неизвестным причинам Google Play отклонял бета-релизы в некоторых случаях, сообщая о неверных метаданных приложения, хотя сами метаданные при этом не менялись;
  • в данных продуктах нет средств для хранения архивов отладочных символов. К тому же Google Play выдает только дампы памяти приложения (то есть для расшифровки дампов нужно самостоятельно где-то хранить отладочные символы).

Поэтому лучшим решением было создание страницы, с которой можно установить приложение, просто перейдя по ссылке. Данная страница обновляется после каждой сборки приложения на сервере непрерывной интеграции (CI), при этом на данной странице по ссылкам доступны не только apk и ipa файлы, но и отладочные символы.

Установка приложения из apk-файла на Android не представляет никаких сложностей, но для того, чтобы установить приложение на iOS, минуя AppStore, необходимо дополнительно настроить распространение приложения путем Ad Hoc, чему была посвящена большая часть доклада Адама.

IPA - это архив, из которого приложение устанавливается на ваше iOS-устройство, в этом архиве хранятся различные метаданные.

Один из таких файлов с метаданными - mobileprovision-файл, с его помощью определяется как приложение может быть установлено (из AppStore, с машины разработчика, или путем Ad-hoc), а также на какие устройства приложение может быть установлено.

В случае AppStore приложение может быть установлено на любое устройство, но для Ad-hoc в mobileprovision-файле должен быть указан список идентификаторов устройств (UID), на которые приложение разрешено устанавливать.

На следующем слайде представлен пример содержимого mobileprovision-файла для тестового проекта PiratePig:

Как видно, в файле явно указано, что приложение может распространяться путем Ad-hoc, а также может быть установлено на 51 устройство с указанными идентификаторами.

Для просмотра содержимого provision-файлов Адам рекомендует пользоваться плагином Quick Look для MacOS.

Начиная с 8 версии, в инструментах OpenFL появилась поддержка сборки проекта для различных способов распространения приложения - в параметрах появился параметр -<deployment method>, при этом можно сразу собрать приложение для нескольких способов его распространения:

Однако для создания IPA-файла также необходим также Provisioning profile (файл профиля):

К счастью, в XCode 9 появилась возможность автоматической генерации и подписи профиля приложения из командной строки (до этого профиль можно было создать только с помощью GUI).

Для этого ваша учетная запись разработчика должна быть привязана в XCode, а также в настройках проекта необходимо указать, что вы хотите чтобы профиль приложения автоматически генерировался и обновлялся - в файле Project.xml необходимо добавить строчку:

<config:ios allow-provisioning-updates=”true” />

После этого приложение успешно соберется:

Однако установить его, перейдя по ссылке на странице, пока что не удастся. Проблема в том, что для этого дополнительно необходим файл manifest.plist, генерируемый XCode при сборке IPA-файла. В этом файле должна быть явно указана ссылка, по которой будет осуществляться установка приложения, а также некоторые другие параметры.

Эти данные можно указать в файле Project.xml:

И только после этого вам, наконец, удастся установить приложение на iOS-устройство:

Но при попытке перенести полученное решение на сервера непрерывной интеграции могут возникнуть проблемы, связанные с тем, что Apple предполагает, что все действия выполняются с помощью графического пользовательского интерфейса, а не из командной строки, в результате Xcode не может получить доступ к идентификационным данным, которые хранятся в Связке ключей (keychain). В результате выдается сообщение:

Для решения этой проблемы нужно выполнить следующие действия:

1. Перед сборкой проекта разблокировать keychain:

2. Для автоматической генерации профиля приложения (automatic provisioning) XCode также нужен доступ к данным учетной записи разработчика, который может быть получен только с помощью GUI. Но делается это один раз после получения нового сертификата, достаточно выбрать вариант “Always Allow” (“Всегда разрешать”) при подтверждении операции.

Далее Адам рассмотрел вопрос работы с отладочными символами, которые помогают расшифровать дампы приложения и найти источники возникающих ошибок.

Отладочные символы преобразовывают это сообщение:

В следующее, из которого можно найти строку, приведшую к падению приложения:

“Зашить” отладочные символы даже в релизную сборку приложения можно просто задав флаг HXCPP_DEBUG_LINK:

Но при сборке приложения для публикации в магазине отладочные символы необходимо удалить из приложения по двум причинам: наличие отладочных символов значительно увеличивает размер установочного пакета, а также упрощается реверс-инжиниринг приложения.

В случае Andoid это делается на этапе упаковки APK-файла, для этого требуется использовать подходящую версию Gradle (>=2.2.3). При этом вам необходимо самостоятельно сохранить где-нибудь so-файлы, которые можно использовать для расшифровки дампов.

XCode в этом отношении выигрывает, так как делает это автоматически. При этом отладочные файлы сохраняются в версии IPA для публикации в AppStore, таким образом обеспечивая возможность автоматической расшифровки дампов.

И последний вопрос, который Адам рассмотрел в своем докладе - автоматизация процесса публикации приложения в мобильных сторах.

Причины, по которым требовалось автоматизировать этот процесс, заключаются в следующем:

  • у компании есть 5 приложений (и их число будет расти), которые необходимо обновлять и в AppStore и в Google Play;
  • при этом данные приложения доступны в нескольких регионах на разных языках, что означает необходимость обновления описаний релизов для каждого приложения в обоих сторах для всех регионов.

Как видно, публикация обновления приложения может отнять у специалиста некоторое время. И кроме того, не все специалисты компании знакомы с процессом публикации приложений и обновлений к ним в сторах.

Поэтому публикация в сторе должна осуществляться с помощью серверов непрерывной интеграции (или если сервер недоступен, то с машины разработчика) по нажатию одной кнопки.

Но проблема в том, что ни Apple ни Google не предоставляют инструментов, позволяющих полностью автоматизировать процесс публикации в сторах:

  • altool от Apple позволяет только загружать IPA файл, но не может опубликовать его;
  • у Google есть API для работы с Google Play, но нет инструментов, которые его используют.

Но все же есть стороннее решение - Fastlane, которое помимо автоматизации публикации приложений в сторах, может использоваться и для других задач.

Для конфигурации Fastlane используются два типа файлов (пишутся на Ruby):

1. Fastfile - файлы для описания выполняемых задач. Например, следующий файл выполнит загрузку приложения и отправит его на рассмотрение:

2. Appfile содержат информацию о приложении (идентификатор приложения, Apple ID, идентификатор команды-разработчика и т.д.).

Интеграция между Faslane и Lime / OpenFL довольно проста и в случае FlowPlay решена путем создания шаблонов файлов Fastfile и Appfile, таким образом стало возможным их повторное использование и для других приложений.

Шаблон файла Fastfile:

Шаблон файла Appfile:

Действительные значения берутся из Project.xml и подставляются при сборке проекта.

Также в Project.xml указываются пути к этим файлам:

В результате достаточно выполнить одну команду и обновление приложения будет загружено в стор: