Предисловие
Идея для статьи зародилась после того, как я потратил кучу времени на настройку Fastlane для своего проекта на React Native. Во время настройки, я так и не смог найти публикацию, которая давала бы простую инструкцию по интеграции Fastlane от А до Я. Эта статья должна стать не более чем простой инструкцией по базовой настройке Fastlane под обе платформы IOS и Android.
Замечание:
Инструкция предполагает, что ваше окружение уже готово к работе с React Native проектами и вы имеете установленные homebrew, ruby, xcode, android studio, созданное приложение в Apple Connect / TestFlight, Google Play и уже загруженна хотя бы одна сборка.
Содержание
настройка окружения и проекта
настройка IOS
настройка Android
Цель
Одним скриптом загружать новые билды в TestFlight и Google Play.
Настройка окружения и проекта
Перед началом установки зависимостей, необходимо создать пустой репозиторий. Он будет содержать все сертификаты и профили подготовки, необходимые для создания и подписи приложений.
Устанавливаем Fastlanesudo gem install fastlane
В корне проекте в Gemfile файл добавляем:
gem "fastlane"
Также в корне проекта создаем директорию fastlane, а внутри создаем файл Fastfile.
Следующим шагом, выполняем командуfastlane match init
Во время выполнения команды, нам необходимо будет выбрать storage mode git, а затем ввести ссылку на ранее созданный репозиторий для сертификатов. Итогом этой команды должен являться файла fastlane/Matchfile.
Замечание:
Если файл не был создан или произошла ошибка, попробуйте установить fastlane с помощью homebrew brew install fastlane
, затем повторить этот шаг.
На этом этапе мы обновим .gitignore файл, добавив:
# Fastlane
**/fastlane/report.xml
**/fastlane/Preview.html
**/fastlane/screenshots
**/fastlane/test_output
**/fastlane/.env.default
**/android/app/api.json
А также, добавим два новых скрипта в package.json:
"ios:beta": "fastlane ios beta",
"android:beta": "fastlane android beta"
Все! C общей настройкой закончили, теперь можно переходить к настройкам IOS и Android.
Настройка IOS
В fastlane/Fastfile добавляем код специально для платформы IOS, который подписывает, собирает и отправляет билд в TestFlight.
platform :ios do
private_lane :testflight_build do
gym(scheme: 'YOUR_SCHEME_NAME', workspace: './ios/YOUR_PROJECT_NAME.xcworkspace')
end
lane :beta do
sync_code_signing(type: "appstore")
testflight_build
upload_to_testflight(username: CredentialsManager::AppfileConfig.try_fetch_value(:apple_id), app_identifier: CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier))
end
end
Замечание:
В коде необходимо заменить называние схемы и проекта на ваши реальные, их можно легко найти в Xcode.
Создаем новый файл в директории fastlane/Appfile, выглядеть он должен так:
itc_team_id "000000000" # (iTunes Connect) team ID
apple_id "yourappleid@gmail.com"
app_identifier "com.mobile.app"
Замечание: На сколько я понял, itc_team_id необходим только если у вас есть несколько команд в одном акаунте на Apple Connect, если это не так попробуйте вовсе удалить itc_team_id из этого файла.
itc_team_id не так просто найти)) Но вот один из вариантов как это сделать:
авторизируемся на сайте https://appstoreconnect.apple.com/
затем переходим на https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/user/detail
Здесь вы получите JSON файл в котором, по полю "name" необходимо найти нужную вам команду (та в которой у вас создано ваше приложение), ее contentProviderId и нужно подставить в itc_team_id.
С остальными id в этом файле все понятно. Я думаю, не стоит объяснять как их достать.
Теперь необходимо произвести изменения в fastlane/Matchfile:
git_url("https://gitlab.com/team/mobile-app/mobile-app-certificates")
storage_mode("git")
type("development")
app_identifier(["com.mobile.app"])
username("yourappleid@gmail.com") # Apple id
team_id("AAA0AA000A")
team_id можно найти если на сайте https://appstoreconnect.apple.com/ перейти в настройки (редактирование) профиля, он будет подписан как ID команды
Создаем последний файл fastlane/.env.default:
FASTLANE_USER=yourappleid@gmail.com
FASTLANE_PASSWORD=yourappleIdPassword
FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD=application-specific-password
c FASTLANE_USER и FASTLANE_PASSWORD все понятно - это ваши креды от apple connect. А вот с FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD интереснее:
переходим на https://appleid.apple.com/account/manage
авторизируемся и переходим в раздел «Пароли приложений»
жмем на плюс и вводим id приложения из Apple Connect
нас могут попросить ввести пароль от учетной записи, затем там же в модальном появится пароль, скопируйте его. Это и будет FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD
Поздравляю! Базовая настройка fastlane для ios закончена. Можем проверить это, выполнив скриптyarn ios:beta
Замечание:
Скрипт может попросить придумать и ввести ключевую фразу для Match storage, а также ввести какие либо другие данные для различных подтверждений - сделайте это.
Настройка Android
Приступаем к настройке Fastlane под Android. Для начала добавляем код для платформы Android (код добавляем ниже уже написанного) в fastlane/Fastfile:
platform :android do
lane :beta do
keystore_password = ENV['KEYSTORE_PASSWORD']
key_password = ENV['KEY_PASSWORD']
key_alias = ENV['KEY_ALIAS']
releaseFilePath = File.join(Dir.pwd, "../android/app", "release.keystore")
gradle(task: 'clean', project_dir: 'android/')
gradle(
task: 'bundle',
project_dir: 'android/',
build_type: 'Release',
print_command: false,
properties: {
"android.injected.signing.store.file" => releaseFilePath,
"android.injected.signing.store.password" => keystore_password,
"android.injected.signing.key.alias" => key_alias,
"android.injected.signing.key.password" => key_password,
}
)
upload_to_play_store(
track: 'internal',
release_status: 'draft'
)
end
end
Этот код сначала выполняет grable clean
, а затем собирает и наконец отправляет билд в Google Play, как билд для внутреннего тестирования.
Добавим несколько переменных в fastlane/.env.default:
KEYSTORE_PASSWORD=your_keystore_password
KEY_ALIAS=your_alias
KEY_PASSWORD=your_key_password
KEY_PASSWORD, KEYSTORE_PASSWORD и KEY_ALIAS - вы указываете когда создаете свой release.keystore файл, он нужен для того чтобы вы могли подписывать и создавать release сборку.
Пишем еще пару строк кода в fastlane/Appfile
json_key_file "android/app/api.json"
package_name "com.my_mobile_app"
C package_name понятно, это android applicationId. А вот чтобы нам получить api.json, придется поднапрячься и выполнить следующую инструкцию:
Откройте консоль Google Play
Нажмите Account Details и обратите внимание на указанный там Developer Account ID
Нажмите Setup → API access
Нажмите кнопку Create new service account
Перейдите по ссылке Google Cloud Platform в диалоговом окне, которое откроет новую вкладку/окно
Нажмите кнопку CREATE SERVICE ACCOUNT в верхней части Google Cloud Platform Console
Убедитесь, что вы находитесь в правильном проекте Google Cloud Platform Console, найдя Developer Account ID из 2-го пункта, в светло-сером тексте, предшествующем .iam.gserviceaccount.com. Если нет, откройте средство выбора на верхней панели навигации и найдите тот, который содержит этот ID
Укажите Service account name и нажмите Create.
Нажмите Select a role, затем найдите и выберите Service Account User и продолжите.
Нажмите кнопку Done
Щелкните на кнопку троиточие напротив только что созданной учетной записи
Выберите Manage keys
Нажмите ADD KEY -> Create New Key
Убедитесь, что в качестве типа ключа выбран JSON, и нажмите CREATE.
Сохраните файл в проекте, в директории android/app под именем api.json.
Вернитесь на вкладку Google Play Console и нажмите DONE, чтобы закрыть диалоговое окно.
Нажмите Grant Access для недавно добавленной учетной записи в нижней части экрана (возможно, вам придется нажать Refresh service accounts, прежде чем она появится)
Выберите разрешения, которые вы хотели бы иметь для этой учетной записи. Мы рекомендуем Admin (все разрешения), но вы можете вручную установить все флажки и не включать некоторые разрешения Releases, такие как Release to production
Нажмите Invite user, чтобы закончить
На этом настройка под Android окончена! Теперь мы можем выполнить скриптyarn android:beta
Он соберет и отправит билд в Google Play, на внутреннее тестирование.
Итоги
Мы настроили Fastlane под две платформы IOS и Android в React Native проекте, и теперь можем загружать билды в TestFlight и Google Play с помощью одного скрипта!
По большому счету, такая настройка должна работать и на Flutter, потому что представляет из себя простую последовательную настройку под IOS и Android, только в одной директории.
Дальнейшими шагами будет являться настройка автоматического инкриминирования версии билда. Это делается нет так сложно, с помощью fastlane плагина versioning. Еще неплохо было бы, настроить ci/cd, например, в gitlab.
Замечание:
Это мой первый опыт в написании статей. Надеюсь вы нашли ее полезной и она сэкономит вам кучу времени!