CI/CD — это инструмент, позволяющий одной командой рассылать сборки вашего приложения тестировщикам, загружать их в App Store/Google Play, и не только. Ранее многие пользовались Fabric, но со временем были вынуждены мигрировать на Firebase App Distribution, предлагаемый Google. Хорошо это или плохо — время покажет. Мы же сегодня рассмотрим, как настроить эту технологию для рассылки сборок Flutter-приложения на macOS, используя Fastlane.
Когда мы только приступили к изучению данной технологии, то нашли эту статью. Она, бесспорно, полезная. Однако описывает только шаги для конфигурации Android-составляющей Flutter-приложения. Шаги для работы с iOS в ней опущены, а ведь там, как показала практика, есть, где споткнуться. Поэтому данная статья представляет собой перевод, расширенный и дополненный шагами, необходимыми для полноценной конфигурации рассылки как Android-, так и iOS-сборок Flutter-приложения. Итак, поехали.
Проверка подключения к Firebase
Предполагается, что к настоящему моменту ваш проект уже подключен к Firebase. Если вы еще этого не сделали, сейчас самое время. Воспользуйтесь сведениями из документации Firebase, описанными здесь. Обязательно перейдите на вкладку «App Distribution» и нажмите кнопку «Начать работу» — так вы подключите Firebase App Distribution к своему проекту. Позднее вам понадобится уникальный идентификатор вашего приложения в Firebase, который можно найти, перейдя по вкладкам: Настройки проекта → Общие настройки → Идентификатор приложения.
Учтите, что если у вас приложение для двух платформ: iOS и Android, то у каждой платформы будет свой идентификатор, и его нужно будет записать в соответствующей платформе Fastfile (конфигурационный файл для Fastlane). Но обо всем по порядку.
Подготовка командной строки macOS
Если вы не так давно обновились с Mojave (или другой, более старой версии macOS) до Catalina, то вы должны были заметить, что теперь macOS по умолчанию использует zsh вместо bash. В связи с этим вы должны переименовать свой $HOME/.bashrc в $HOME/.zshrc, а также выполнить команду:
chsh -s /bin/zsh
После выполнения этого шага в вашей командной строке вместо характерного для bash «‘$’» должен появиться «‘%’». Если этого не произошло (обычно такое случается, если у пользователя, под которым вы работаете, недостаточно прав), перейдите в Terminal → Preferences, выберите Command (complete path) и введите туда путь:
/bin/zsh
Следующий шаг — настройка Ruby. По умолчанию macOS поставляет свою версию Ruby, в которую вам нельзя ничего устанавливать. Предполагается, что она используется исключительно системой и полностью контролируется Apple. Поэтому вам нужно использовать другую версию Ruby, где никто не будет «бить по рукам» и у вас будет полная свобода в вопросах установки gems.
Для начала установим менеджер версий Ruby. Используем установку через Homebrew:
brew install rbenv ruby-build
Далее вам нужно дописать следующую строку в ваш $HOME/.bashrc или $HOME/.zshrc:
eval "$(rbenv init -)"
Не забудьте перезагрузить терминал или выполнить команду:
source $HOME/.bashrc
либо: source $HOME/.zshrc.
Теперь установите нужную вам версию Ruby. Список всех версий можно получить командой:
rbenv install -l
Установка нужной версии выполняется следующей командой (предположим, что вы решили установить версию 2.6.5):
rbenv install 2.6.5
После установки Ruby делаем ее глобально доступной для использования:
rbenv global 2.6.5
Убедимся, что все сделано правильно. Введите команду:
rbenv versions
Команда выдаст список всех версий Ruby, доступных на рабочей машине, и звездочкой выделит ту, которая в данный момент активна. Если все сделано правильно, то вывод должен выглядеть, например, так:
username-admin ~ % rbenv versions
system
* 2.6.5 (set by /Users/username/.rbenv/version)
Вот теперь можно перейти к Firebase.
Установка Fastlane и Firebase CLI
Установим Fastlane, если у вас его еще нет. Выполним команду:
sudo gem install fastlane -NV
Установим утилиты командной строки Firebase CLI:
curl -sL firebase.tools | bash
Введите команду:
firebase login
В появившемся окне браузера выполните авторизацию через тот Google-аккаунт, в котором создавали проект в Firebase.
Подключение Firebase App Distribution
Теперь рассмотрим процесс подключения Firebase App Distribution к вашим iOS- и Android-проектам. Перейдите в соответствующую подпапку (iOS/Android) в корне вашего Flutter-проекта и выполните команду:
fastlane init
Находясь в той же папке, выполните команду:
fastlane add_plugin firebase_app_distribution
Тем самым вы подключили плагин Firebase к вашему проекту. Обратите внимание — выполнять эти две команды нужно дважды: отдельно для iOS-проекта, отдельно для Android.
Возможно, с первого раза этот шаг выполнить не удастся. Если у вас в консоли появилось такое сообщение об ошибке:
An error occurred while installing json (2.3.0), and Bundler cannot
continue.
Make sure that `gem install json -v '2.3.0' --source 'https://rubygems.org/'`
succeeds before bundling.
То принудительно установите gem необходимой версии:
sudo gem install json -v '2.3.0' --source 'https://rubygems.org/'
А затем выполните неудавшуюся команду еще раз. После этого плагин должен благополучно подключиться к проекту.
Последний шаг — отредактировать наши Fastfile, которые находятся в подпапках проекта android/fastlane/ и ios/fastlane/. Вот как могут выглядеть файлы с простейшими lane для отправки сборок тестировщикам на Android:
default_platform(:android)
platform :android do
desc "Some Android test deployment"
lane :distribute_internal_android do
gradle(task: "clean assembleRelease")
firebase_app_distribution(
app: "ID вашего проекта в Firebase",
testers: "account1@gmail.com, account2@gmail.com",
release_notes: "New Android build",
firebase_cli_path: "/usr/local/bin/firebase",
apk_path: "../build/app/outputs/apk/release/app-release.apk" )
end
end
И iOS, соответственно:
default_platform(:ios)
platform :ios do
desc "Some iOS test deployment"
lane :distribute_internal_ios do
build_ios_app(
export_options: {
method: "ad-hoc",
provisioningProfiles: {
"com.your.app.bundle.id": "Your sertificate ADHOC"
},
signingStyle: "manual"
}
) # build_ios_app is a built-in fastlane action.
firebase_app_distribution(
app: "ID вашего проекта в Firebase",
testers: "account1@gmail.com, account2@gmail.com",
release_notes: "New iOS build",
firebase_cli_path: "/usr/local/bin/firebase"
)
end
end
Обратите внимание — в случае с iOS в данном примере приводится конфигурация для ручного управления сертификатами (manual). Убедитесь, что у вас установлены все необходимые certificates и provisioning profiles (Ad Hoc, App Store, Development).
Рассылка приложения
Перед тем, как делать итоговую сборку, убедитесь, что ваши проекты собраны в релизной конфигурации. Если вы перед отправкой приложения запускали его под дебагом, чтобы убедиться, что все в порядке, то сборка тестировщикам также отправится в отладочной конфигурации. А это значит, что тестировщики ее увидят и даже установят, но при запуске приложение будет крашиться. Чтобы этого не произошло, предварительно соберите приложение в релизном режиме командами:
flutter build apk
Или: flutter build ios
Впрочем, команду build необходимо выполнять в любом случае. Дело в том, что во время сборки Flutter собирает свои конфигурационные файлы и подтягивает их к платформенным проектам. В том числе, например, редактирует номер сборки/версии, взятый из pubspec.yaml. Без этих конфигурационных файлов вы просто не сможете собрать свои.apk-/.ipa-файлы.
Далее, в зависимости от того, в какой папке вы находитесь, выполните команду:
bundle exec fastlane distribute_internal_android
Или: bundle exec fastlane distribute_internal_ios
Готово! Ваши сборки уже собираются для отправки тестировщикам!
Иногда возникает странная ошибка — в консоли Firebase указано, что приглашения отправлены всем тестировщикам, однако некоторым на почту не приходит ничего. Делать сборку и отправлять ее повторно бесполезно. Чтобы это исправить, выберите нужных вам тестировщиков и нажмите «Resend invitation» / «Отправить приглашение еще раз».
После этого сборки начнут послушно прилетать на указанные email-адреса.