Рубрики
Uncategorized

Автоматизированное развертывание нативных приложений React с использованием Fastlane — Часть 1 — Play Store

В этой статье мы узнаем, как развернуть нативные приложения React в магазин Android Play, используя…. Tagged с помощью CI CD, реагировать Native, Fastlane, Android.

В этой статье мы узнаем, как развернуть нативные приложения React в магазин Android Play, используя Фластлейн . Это первая часть серии об автоматическом развертывании нативных приложений React с использованием Fastlane.

Каждый, кто выпускал приложения вручную, знают, насколько утомительно и занимает много времени, основной идеей этой серии является то, что к концу этого будет иметь полное знание о том, как автоматизировать эти задачи, позволяя поставщику CI/CD управлять ими. Анкет Освобождение времени разработчиков и мощности обработки машины.

Первые две части будут сосредоточены на магазине Android Play, а затем мы увидим, как то же самое для App Store iOS.

Наша главная цель — использовать конкретные треки выпуска в Play Store, чтобы дать нам быструю и надежную среду для тестирования и выхода в нашу приложение, будь то на закрытой альфа -треке или на открытой бета -треке, прежде чем отправить релиз на производство и сделать его Доступно в игровом магазине.

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

  • Альфа -трек → Разработка филиала
  • Бета -трек → Постановление ветви
  • Производственный трек → Мастер филиал

Примечание: Хотя это руководство сосредоточено на приложениях React Native, могут быть предприняты те же шаги, чтобы добавить Fastlane в любое приложение для Android.

Требования

Чтобы следовать этому руководству, необходимо иметь следующее:

Рубиновые основы хороши, но не требуются.

Инициализация проекта

Первый шаг, который мы должны сделать, — это инициализация нашего нативного проекта React, у нативных документов React действительно отличный Настройка среды Раздел, так что следуйте инструкциям, используя React Native Cli QuickStart гид.

По сути, вам нужно будет установить зависимости и запустить React-Cnive init , в нашем случае мы собираемся назвать наш проект fastlane_react_native_deployment :

npx react-native init fastlane_react_native_deployment --version react-native@0.63.1

После создания проекта мы должны CD в созданную папку и инициализируйте локальный репозиторий GIT.

cd fastlane_react_native_deployment && git init

Давайте все сделаем:

git add --all && git commit -m "initial code"

Создание нашей учетной записи разработчика Play Store Developer

Затем мы собираемся зарегистрироваться на учетную запись разработчика в магазине Play Store, это требует единовременного платежа в размере 25 долларов США, если вы еще этого не сделали.

После того, как вы создали свою учетную запись, перейдите в Играть в магазин консоли приборной панели и нажмите Создать приложение :

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

Прямо сейчас вам не нужно заполнять детали вашего приложения в Список магазинов Раздел, но не стесняйтесь делать это, если хотите.

Другой шаг, который мы должны сделать в консоли Play Store, — это создать учетную запись службы с API Access к нашему приложению, чтобы вернуться к Все приложения Листинг, затем в боковой панели нажмите на НастройкиAPI Access , если вы никогда не настроили это в своей учетной записи Play Store, вы увидите экран, подобный следующему:

Нажмите на Создать новый проект И новый проект на консоли разработчика Google будет создан автоматически и связан с вашей учетной записью Play Store.

Экран будет обновлен с некоторой новой информацией:

В Учетные счета Раздел, нажмите на Создать учетную запись сервиса И появится модал, следуйте инструкциям там.

Вы можете дать учетной записи услуги любое значимое имя, которое вы хотите, для этого урока мы собираемся использовать Fastlane Анкет Важными шагами, которые нужно предпринять:

После завершения этих шагов вернитесь к странице консоли Play Store и нажмите Готово , страница будет перезагружаться, и появится недавно созданная учетная запись сервиса:

В учетной записи службы нажмите ПРЕДОСТАВЛЕНИЕ ДОСТУПА Новый модал, похоже, добавит его в качестве пользователя с доступом к вашей учетной записи Store Store, здесь вы можете выбрать между Менеджер релиза и Ведущий проекта роли.

Ведущий проекта имеет доступ ко всем трекам, но Производство один, пока Менеджер релиза Роль имеет доступ ко всему. Мы собираемся использовать Менеджер релиза роль. Нажмите Добавить пользователя Чтобы закончить настройку учетной записи службы.

Создание нашего файла магазина ключей

ПРИМЕЧАНИЕ. Если вы следите за этим для уже опубликованного приложения, у вас, вероятно, уже есть файл магазина ключей, так что вы можете пропустить их создание.

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

https://developer.android.com/studio/publish/app-signing

Чтобы облегчить, мы будем использовать Android Studio. Откройте Android Studio, затем нажмите на Откройте существующий Android Studio Project и выберите ./android Папка в нашем нативном проекте React.

Тогда перейти к СборкаСоздать подписанный пакет/apk :

В следующем окне выберите Android App Bundle Чтобы использовать новый формат сборки, который меньше и быстрее для построения, чем apk , затем нажмите Следующий :

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

Поскольку у нас нет существующего магазина ключей, давайте нажмите на СОЗДАВАТЬ НОВОЕ... и появится новый диалог:

Ключевой путь магазина должно быть место внутри ./android/ Папка в нашем проекте, для этого урока мы собираемся использовать Android/KeyStore.jks Анкет Этот файл будет привержен репозиторию, сам файл заполнен AES, и ключи могут быть получены только в том случае, если у нас есть оба пароля.

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

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

Обязательно запомните пароли и псевдоним, который вы используете здесь, эта информация понадобится позже. Мы собираемся использовать App-1 как ключ Псевдоним Анкет

Поля на Сертификат Раздел — это информация, которая будет использоваться для создания файла магазина ключей, вы можете заполнить, затем с помощью собственной информации/компании.

Нажмите ОК После того, как вы заполните информацию, и она должна создать файл магазина ключей, предыдущий модал будет заполнен новой информацией. На данный момент вы можете закрыть этот диалог и саму Android Studio, так как мы закончили создание магазина ключей.

Использование нашего файла магазина ключей

Теперь нам нужно настроить наш проект, чтобы использовать ключ подписания при создании, во -первых, давайте создадим файл .properties для хранения наших учетных данных, создайте файл Android/KeyStore.properties со следующим содержимым:

storePassword=::store_password::
keyPassword=::key_password::
keyAlias=app-1
storeFile=keystore.jks

StorePassword это пароль, который вы использовали для магазина ключей.

Клаесенное слово это пароль, который вы использовали для самого ключа.

Keyalias это имя ключа, которое в нашем случае было App-1 Анкет

Storefile укажет на местоположение нашего файла Key Store, согласно предыдущим шагам, он называется Keystore.jks и находится внутри Android/ Папка, вместе с Keystore.properties файл.

Как мы уже говорили ранее, этот файл не должен быть привержен репозиторию, поскольку он содержит конфиденциальную информацию. Так что обязательно включите его в свой .gitignore файл.

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

Давайте сделаем это, открыт Android/App/Build.Gradle и добавьте следующий выделенный код выше Android { блокировать:

def enableHermes = project.ext.react.get("enableHermes", false);

def areUploadKeystoreEnvsSet = System.getenv("MYRNAPP_RELEASE_STORE_FILE") != null &&
                                System.getenv("MYRNAPP_RELEASE_STORE_PASSWORD") != null &&
                                System.getenv("MYRNAPP_RELEASE_KEY_ALIAS") != null &&
                                System.getenv("MYAPPP_RELEASE_KEY_PASSWORD") != null

def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystorePropertiesFileExists = keystorePropertiesFile.exists()
def keystoreProperties = new Properties()
if (!(keystorePropertiesFileExists || areUploadKeystoreEnvsSet)) {
    throw new InvalidUserDataException('''\
You must have a keystore.properties file in the /android/ folder or set the environments variables:
  MYRNAPP_RELEASE_STORE_FILE
  MYRNAPP_RELEASE_STORE_PASSWORD
  MYRNAPP_RELEASE_KEY_ALIAS
  MYRNAPP_RELEASE_KEY_PASSWORD
''')
}

keystorePropertiesFileExists && keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

android {

Это загрузит наш файл свойств внутри KeyStoreProperties переменная. Если Android/KeyStore.properties Файл не существует, и переменные среды не установлены, ошибка будет выбрана.

Возможно, вы отметили, что переменные среды имеют общий префикс, Myrnapp_release_ Вы можете изменить это на все, что имело бы больше смысла для вашего проекта. Идея иметь префикс состоит в том, чтобы избежать столкновений, когда вы устанавливаете эти переменные среды для нескольких приложений в настройках вашего поставщика CI/CD.

Внутри того же файла, Android/App/Build.Gradle , ищите Подписывающие Конфигс блокировать. Это должно быть около строки 165 и выглядеть так:

    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
    }

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

Добавьте следующее внутри Подписывающие Конфигс Блок, прямо под отладка блокировать:

        release {
            if (areUploadKeystoreEnvsSet) {
                storeFile rootProject.file(String.valueOf(System.getenv("MYRNAPP_RELEASE_STORE_FILE")))
                storePassword String.valueOf(System.getenv("MYRNAPP_RELEASE_STORE_PASSWORD"))
                keyAlias String.valueOf(System.getenv("MYRNAPP_RELEASE_KEY_ALIAS"))
                keyPassword String.valueOf(System.getenv("MYRNAPP_RELEASE_KEY_PASSWORD"))
            } else {
                storeFile rootProject.file(keystoreProperties['storeFile'])
                storePassword keystoreProperties['storePassword']
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
            }
        }

Это будет проверять, были ли установлены переменные среды, если они были, он попытается загрузить настройки, используя их значения, если они не были (пункт ELSE), он загрузит значения из файла свойств.

С созданным конфигурацией релиза, мы должны его использовать. В том же файле поиск типа сборки выпуска он должен быть прямо ниже Подписьконфиг Блок, внутри BuildTypes блокировать. Похоже:

        // ...
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            signingConfig signingConfigs.debug
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
        // ...

Нам нужно изменить Подписьконфиг Поле в Выпуск Блок для использования Подписывающая среда. Релиз вместо отладки:

            // ...
            signingConfig signingConfigs.release
            // ...

Следующим шагом является генерация нашего AAB ( Android App Bundle ). Это так же просто, как запустить следующие команды:

cd android
./gradlew bundleRelease

После выполнения команды встроенный приложение-release.aab Файл будет доступен в Android/App/Release/App-release.aab Анкет

Этот файл не должен быть привержен репозиторию, поэтому добавьте следующее в .gitignore :

android/app/*/*.aab

Давайте сделаем все, что мы сделали до сих пор:

git add --all && git commit -m "android release signing"

Загрузка нашего первого пакета приложений для игры в магазин

Теперь пришло время создать альфа -закрытый трек в консоли Play Store. Вернитесь в список приложений Play Store Console и нажмите на App Relays в боковой панели.

Прокрутите вниз до Закрытый трек и нажмите Управление на Альфа Трек, на следующем экране нажмите Создать выпуск Анкет

Нажмите Продолжить Чтобы Google управлял и защитила ключ подписания приложения. Затем в следующем разделе нам нужно будет загрузить приложение-release.aab Файл, который мы только что построили.

После того, как загрузка будет выполнена обработка, убедитесь, что Имя выпуска это правильно, добавьте запись изменений, если это необходимо, и нажмите Сохранить Анкет

Вы, вероятно, увидите предупреждение, которое не позволит вам начать развертывание релиза альфа, связанное с тем, что на альфа-треке нет внутренних тестеров. Вы можете воспользоваться этой возможностью, чтобы включить тестеров, вернуться к App Relays Страница и нажмите на Управление В альфа -треке.

Откройте Управление тестерами Раздел и включите любые электронные письма, которые вам нужны. После завершения этого нажмите Редактировать релиз Анкет

Все должно быть заполнено теми же данными, чем раньше, нажмите Обзор и Начать развертывание в Альфа Кнопка должна быть доступна, нажмите на нее, чтобы закончить первый релиз альфа.

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

Мы наконец -то закончили с консоли Play Store.

Инициализация Fastlane

Теперь мы собираемся настроить Fastlane , инструмент, который мы будем использовать, чтобы сделать для нас тяжелую работу при развертывании в Play Store.

Первый шаг — инициализировать рубин Бундлер В нашей папке Android и добавить Fastlane в качестве зависимости:

cd ./android
bundle init
bundle install --path vendor/bundle
bundle add fastlane

Примечание. Если по какой -то причине последняя команда приводит к ошибке, это, вероятно, потому, что у вас нет инструментов разработки, установленных в вашей ОС. Для macos Это означает запуск xcode-select-install Анкет В Windows установщик Ruby позаботится об установке необходимых пакетов. И на большинстве вариантов NIX необходимо установить -dev Вариант пакета Ruby.

Добавить Android/Vendor и Android/.bundle к вашему .gitignore , поскольку мы не хотим совершать эту папку в репозиторий.

Затем беги:

bundle exec fastlane init

Вам будет предложено некоторую информацию, связанную с вашим приложением. Первая информация — это имя пакета, это идентификатор приложения, который вы используете. Для Android это означает значение поля Android.defaultConfig.applicationId в Android/App/Build.Gradle файл.

Вторая информация — это путь к учетной записи службы JSON, который мы сохранили ранее.

Наконец, третий вопрос задаст нам, если мы хотим загрузить существующие метаданные из игрового магазина и настройки метаданных, мы ответим y здесь.

После этого шага будет новая папка под названием Фластлейн Внутри Android Папка, откройте эту папку, и вы найдете файлы Fastlane. Самый важный здесь — это Fastfile , который содержит наши полосы движения: некоторые общие задачи, которые мы можем выполнить от CLI.

Android -версия

Одним из основных аспектов использования автоматизированного процесса развертывания для мобильных приложений является автоматическое увеличение их номеров сборки для каждой последующей сборки. На самом деле это требование загружать новые пакеты в магазин Play Store: вы не можете загрузить новую версию, которая имеет такой же или меньший номер сборки, чем последний загруженный. Если мы попытаемся сделать это, будет выброшена ошибка:

[!] Ошибка Google API: ApKnotificationMessageKeyupgradeVersionConflict: APK определяет код версии, который уже использовался. — APK указывает код версии, который уже использовался.

В настоящее время Fastlane не предоставляет действие по увеличению версии Android, как для iOS, к счастью, есть и другие способы сделать это, и один из них использует плагин Fastlane. Один был специально написан для этого урока: Android_version_Manager

Давайте добавим этот плагин в наш проект, перейдите в Android/Fastlane Папка внутри нативного проекта React:

cd android/fastlane

А затем беги:

bundle exec fastlane add_plugin android_version_manager

Fastlane спросит Должен ли Fastlane изменить Gemfile на Path '/Android/Gemfile' для вас?

Ответь Да.

Теперь мы можем использовать плагин для обработки версий для нас. Open Android/Fastlane/FastFile В вашем любимом текстовом редакторе.

# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:android)

platform :android do
  desc "Runs all the tests"
  lane :test do
    gradle(task: "test")
  end

  desc "Submit a new Beta Build to Crashlytics Beta"
  lane :beta do
    gradle(task: "clean assembleRelease")
    crashlytics

    # sh "your_script.sh"
    # You can also use other beta testing services here
  end

  desc "Deploy a new version to the Google Play"
  lane :deploy do
    gradle(task: "clean assembleRelease")
    upload_to_play_store
  end
end

Fastfile По сути, рубиновый файл, с некоторым дополнительным DSL смешанным. Он содержит несколько полос, которые являются шагами, которые мы можем выполнить, чтобы помочь нам автоматизировать несколько задач.

На данный момент не обращайте внимания на существующие полосы, просто обратите внимание, что в корне у нас есть блок платформы под названием : Android с индивидуальными полосами внутри.

Мы собираемся создать две новые дорожки внутри этого блока.

Номер сборки

Первая полоса, которую мы создадим, называется ибн . Эта полоса будет нести ответственность за я разоблачить b сборка количество.

Android Номер строителя Мы имеем в виду здесь широко известен как Внутренняя версия номер , и это значение версия кода Поле в файле Android/App/Build.Gradle Анкет

Вот как наш ibn Лейн выглядит как:

desc "Increment build number and push to repository - Build number in this case is the android version code"
lane :ibn do |options|
  should_commit = options.fetch(:should_commit, true)
  commit_message = options.fetch(:commit_message, "android: bump build number (version code) [skip ci]")
  should_push = options.fetch(:should_push, true)

  ensure_git_status_clean if should_commit

  params = {
    :app_project_dir => 'app'
  }
  if options[:build_number]
    params[:version_code] = options[:build_number].to_i
  end

  android_increment_version_code(params)
  new_version_code = Actions.lane_context[Actions::SharedValues::ANDROID_VERSION_CODE]
  UI.important("Incremented android version code to #{new_version_code}")

  if should_commit
    path = "android/app/build.gradle"
    git_add(path: path)
    git_commit(path: path, message: commit_message)
    # Push the new commit and tag back to your git remote
    push_to_git_remote if should_push
  end
end

Вот обзор того, что мы только что сделали.

Во -первых, у нас есть Лейн: Имя do | Параметры | ... конец Блок, который создает саму полосу движения. Мы можем иметь некоторое описание полосы движения, используя desc Позвоните над определением полосы движения.

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

Например, следующий код:

  # ...
  should_commit = options.fetch(:should_commit, true)
  # ...

Собирается хранить в переменной с именем должен_коммит Значение, передаваемое на CLI для должен_коммит Вариант, если не было пройденное значение, мы собираемся предположить истинный в качестве значения по умолчанию (второй аргумент, переданный извлечь ).

Далее, мы следим за тем, чтобы, когда мы запустим нашу полосу, в нашем репозитории GIT не внесены никаких некоммерческих изменений:

  ensure_git_status_clean if should_commit

Этот шаг необходим в случае, если мы собираемся автоматически совершить удар номера сборки в нашем репозитории ( sup_commit это true ), так как мы не хотим совершать не связанные файлы.

Сразу после этого мы создаем другую локальную переменную под названием Params , который инициализируется в хэш с одним ключом, : app_project_dir :

  params = {
    :app_project_dir => 'app'
  }

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

  if options[:build_number]
    params[:version_code] = options[:build_number].to_i
  end

Если мы передали вариант build_number При вызове нашей полосы из командной строки их значение будет добавлено в качестве нового элемента в нашем Params Хэш, с ключом : version_code Анкет Единственное отличие в том, что мы сначала отбрасываем его в целое число, позвонив to_i Анкет

Теперь мы можем назвать действие из Android_version_Manager Плагин, передавая параметры хэш как единственный аргумент. Это действие, как следует из их названия, отвечает за увеличение кода версии в Android/App/Build.Gradle файл.

  android_increment_version_code(params)

Исходный код для этого действия можно найти на GitHub: ./lib/fastlane/plugin/android_version_manager/actions/android_increment_version_code_action.rb

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

  new_version_code = Actions.lane_context[Actions::SharedValues::ANDROID_VERSION_CODE]
  UI.important("Incremented android version code to #{new_version_code}")

Actions.lane_context это специальный хэш, используемый Fastlane, который содержит значения, разделяемые из действий, которые выполнялись ранее, в нашем случае мы получаем значение для ключа Действия:: sharedValues:: android_version_code Анкет

Это поле, которое Android_increment_version_code Действие использует для хранения нового кода версии. Откуда мы это знаем?

Глядя на документацию действия:

bundle exec fastlane action android_increment_version_code

Который напечатает что -то вроде этого:

Ключи, которые мы можем использовать, доступны на android_increment_version_code Выходные переменные Таблица.

На одном и том же выводе также показано описание действия и каждого варианта, которое он принимает.

Помните, что параметры Хэш, мы передаем, имеет : app_project_dir Ключ и также может содержать другой ключ : version_code ? Как мы можем видеть выше, это варианты, принятые действием.

Наконец, в конце нашей полосы движения у нас есть:

  if should_commit
    path = "android/app/build.gradle"
    git_add(path: path)
    git_commit(path: path, message: commit_message)
    # Push the new commit and tag back to your git remote
    push_to_git_remote if should_push
  end

Если должен_коммит это Верно , что это будет по умолчанию (помните о опциях Android/App/Build.Gradle Файл в наш репозиторий, и если должен_Пуш Также верно, мы сразу после этого мы собираемся продвинуть эти изменения в репозиторий удаленного GIT.

Сообщение о коммите будет значением Commit_message переменная, которая происходит от Commit_message Аргумент командной строки мы передаем нашу полосу.

Теперь давайте назовем нашу полосу, сначала убедитесь, что вы находитесь в каталоге Android Native Project:

cd android

Затем беги:

bundle exec fastlane android ibn should_commit:false

Обратите внимание, как аргументы передаются на переулок с использованием [ключ]: [значение] формат.

Вывод должен выглядеть похоже на это:

Из вывода команды выше мы видим, что код версии (номер сборки) был увеличен из 1 к 2 Анкет Что означает, что наша полоса работала. 🎉

Номер версии

Вторая полоса, которая нам нужно, называется ivn Анкет Эта полоса будет нести ответственность за увеличение версия n мгновенный

Android Номер версии Мы имеем в виду здесь широко известен как Название версии , и это значение Версия имен Поле в файле Android/App/Build.Gradle . Это значение, видимое для пользователей при загрузке приложения.

Мы собираемся использовать Semver, подобное версии, Major.minor.Patch Анкет

Вот как наш ivn Лейн выглядит как:

desc "Increment version number and push to repository - Version number in this case is the android version name"
lane :ivn do |options|
  should_commit = options.fetch(:should_commit, true)
  commit_message = options.fetch(:commit_message, "android: bump version number (version name) [skip ci]")
  should_push = options.fetch(:should_push, true)

  # Ensure that your git status is not dirty
  ensure_git_status_clean if should_commit

  increment_type = options.fetch(:increment_type, "patch")
  new_version_params = options[:version]

  params = {
    app_project_dir: 'app',
    increment_type: increment_type,
  }

  unless new_version_params.nil?()
    params[:version_name] = new_version_params
  end

  android_increment_version_name(params)
  new_version_name = Actions.lane_context[Actions::SharedValues::ANDROID_VERSION_NAME]
  UI.important("Incremented android version name to #{new_version_name}")

  if should_commit
    path = "android/app/build.gradle"
    git_add(path: path)
    git_commit(path: path, message: commit_message)
    # Push the new commit and tag back to your git remote
    push_to_git_remote if should_push
  end
end

Эта полоса следует той же идее, что и предыдущая. Но он принимает еще несколько вариантов. Самыми важными являются IGRMENT_TYPE и Версия Анкет

Мы можем пройти любой из них. Версия позволяет нам напрямую указать новый номер версии, а IGRMENT_TYPE дает нам возможность просто сказать тип приращения, который может быть одним из: пластырь , несовершеннолетний и майор Анкет

  increment_type = options.fetch(:increment_type, "patch")
  new_version_params = options[:version]

Если мы ничего не проведем, по умолчанию будет патч Приращение текущей версии.

После того, как мы обрабатываем параметры полосы движения, мы называем Android_increment_version_name действие, предоставленное Android_version_Manager плагин, который мы использовали.

  android_increment_version_name(params)
  new_version_name = Actions.lane_context[Actions::SharedValues::ANDROID_VERSION_NAME]
  UI.important("Incremented android version name to #{new_version_name}")

Исходный код для этого действия также можно найти на GitHub: ./lib/fastlane/plugin/android_version_manager/actions/android_increment_version_name_action.rb

И тогда та же самая обработка GIT, которую мы сделали на предыдущей полосе, также делается здесь.

  if should_commit
    path = "android/app/build.gradle"
    git_add(path: path)
    git_commit(path: path, message: commit_message)
    # Push the new commit and tag back to your git remote
    push_to_git_remote if should_push
  end

Теперь давайте назовем нашу полосу, опять же, убедитесь, что вы находитесь в каталоге Android Native Project:

cd android

Затем беги:

bundle exec fastlane android ivn should_commit:false

Вывод должен выглядеть похоже на это:

Версия была правильно выбита с 1 к 1.0.1 Анкет 🎉

Отправка версии Alpha в магазин Play с помощью Fastlane

Теперь, когда у нас есть полосы, отвечающие за увеличение номера сборки и версий, пришло время создать нашу полосу, ответственную за загрузку новой альфа -версии в Play Store.

Вот наш альфа переулок:

desc "Build and push a new alpha build to the Play Store"
lane :alpha do
  build_params = {
    build_task: "bundle",
  }
  build(build_params)

  supply_params = {
    track: "alpha",
    # defaults to completed
    release_status: "draft",
  }
  supply(supply_params)
end

Код для этой полосы движения намного проще, чем те, которые мы написали до сих пор.

Прямо с самого начала мы переходим на другую полосу, называемую сборка и передавая некоторые варианты.

Мы можем назвать другие полосы движения напрямую, они просто функции.

сборка Лейн отвечает за создание нашего файла AAB:

desc "Build a version of the app"
lane :build do |options|
  build_task = options.fetch(:build_task, "assemble")
  build_type = options.fetch(:build_type, "Release")

  gradle_params = {
    task: build_task,
    build_type: build_type,
  }
  gradle(gradle_params)
end

Он принимает два варианта:

  • build_task : который может быть либо собрать или пучок
  • build_type : вариант, который мы строим

А затем передает их Градл действие.

После сборка Заканчивается Лейн, контекст исполнения восходит к нашему альфа переулок:

  supply_params = {
    track: "alpha",
    # defaults to completed
    release_status: "draft",
  }
  supply(supply_params)

Затем мы называем поставка Действие Переходя два варианта:

  • трек со значением альфа
  • release_status со значением проект Это необходимо, поскольку мы не выпускаем непосредственно в магазин Play — Но для одного из наших закрытых треков.

Давайте запустим нашу полосу и посмотрим, что произойдет:

bundle exec fastlane android alpha

Из приведенного выше вывода мы видим, что Fastlane вызывает в нашем сборка Лейн и после этого восходит к альфа Лейн, который затем называет поставка действие.

После того, как FastLane загружает новый релиз альфа, он должен вывести что -то похожее на это:

Примечание. Если вы получаете такую ошибку, как это:

Ошибка Google API: Badrequest: только выпуска со статусом может быть создано в черновом приложении. — Только выпуски со статусом могут быть созданы в проекте приложения.

Это означает, что вы не выпустили первоначальную альфа -версию непосредственно в консоли Play Store, как упомянуто в предыдущих шагах.

Если вы пойдете в консоль Play Store App Relays экран, вы должны увидеть, что последняя версия — та, которую мы загрузили:

Потрясающий! Время работать над нашим бета и Производство дорожки.

Создание дорожек для бета и производственных треков

бета и Производство дорожки еще проще. Как мы всегда собираемся выпустить первым, чтобы альфа Единственное, что нам нужно сделать, это продвигать с одного трека на другой.

Альфа → Бета → Производство

desc "promote the current alpha build to the beta track"
lane :beta do
  version_codes = google_play_track_version_codes(track: "alpha")

  version_code = version_codes.first

  supply_params = {
    track: "alpha",
    track_promote_to: "beta",
    version_code: version_code,
  }
  supply(supply_params)
end

desc "promote the current beta build to the production track"
lane :production do
  version_codes = google_play_track_version_codes(track: "beta")

  version_code = version_codes.first

  supply_params = {
    track: "beta",
    track_promote_to: "production",
    version_code: version_code,
  }
  supply(supply_params)
end

Мы используем действие Google_Play_track_version_codes Чтобы получить активные коды версий текущего трека, с которого мы продвигаем.

Затем мы используем первый код версии, найденный в качестве коэффициента, который будет продвигаться на следующий трек. Это необходимо для использования одной и той же изменчивости из указанного кода версии.

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

  desc "Submit a new Beta Build to Crashlytics Beta"
  lane :beta do
    gradle(task: "clean assembleRelease")
    crashlytics

    # sh "your_script.sh"
    # You can also use other beta testing services here
  end

На самом деле, мы можем удалить все полосы, которые мы не используем. Финал Fastfile Похоже:

default_platform(:android)

platform :android do
  desc "Build a version of the app"
  lane :build do |options|
    build_task = options.fetch(:build_task, "assemble")
    build_type = options.fetch(:build_type, "Release")

    gradle_params = {
      task: build_task,
      build_type: build_type,
    }
    gradle(gradle_params)
  end

  desc "Build and push a new alpha build to the Play Store"
  lane :alpha do
    build_params = {
      build_task: "bundle",
    }
    build(build_params)

    supply_params = {
      track: "alpha",
    }
    supply(supply_params)
  end

  desc "promote the current alpha build to the beta track"
  lane :beta do
    version_codes = google_play_track_version_codes(track: "alpha")

    version_code = version_codes.first

    supply_params = {
      track: "alpha",
      track_promote_to: "beta",
      version_code: version_code,
    }
    supply(supply_params)
  end

  desc "promote the current beta build to the production track"
  lane :production do
    version_codes = google_play_track_version_codes(track: "beta")

    version_code = version_codes.first

    supply_params = {
      track: "beta",
      track_promote_to: "production",
      version_code: version_code,
    }
    supply(supply_params)
  end

  desc "Increment build number and push to repository - Build number in this case is the android version code"
  lane :ibn do |options|
    should_commit = options.fetch(:should_commit, true)
    commit_message = options.fetch(:commit_message, "android: bump build number (version code) [skip ci]")
    should_push = options.fetch(:should_push, true)

    ensure_git_status_clean if should_commit

    params = {
      :app_project_dir => 'app'
    }
    if options[:build_number]
      params[:version_code] = options[:build_number].to_i
    end

    android_increment_version_code(params)
    new_version_code = Actions.lane_context[Actions::SharedValues::ANDROID_VERSION_CODE]
    UI.important("Incremented android version code to #{new_version_code}")

    if should_commit
      path = "android/app/build.gradle"
      git_add(path: path)
      git_commit(path: path, message: commit_message)
      # Push the new commit and tag back to your git remote
      push_to_git_remote if should_push
    end
  end

  desc "Increment version number and push to repository - Version number in this case is the android version name"
  lane :ivn do |options|
    should_commit = options.fetch(:should_commit, true)
    commit_message = options.fetch(:commit_message, "android: bump version number (version name) [skip ci]")
    should_push = options.fetch(:should_push, true)

    # Ensure that your git status is not dirty
    ensure_git_status_clean if should_commit

    increment_type = options.fetch(:increment_type, "patch")
    new_version_params = options[:version]

    params = {
      app_project_dir: 'app',
      increment_type: increment_type,
    }

    unless new_version_params.nil?()
      params[:version_name] = new_version_params
    end

    android_increment_version_name(params)
    new_version_name = Actions.lane_context[Actions::SharedValues::ANDROID_VERSION_NAME]
    UI.important("Incremented android version name to #{new_version_name}")

    if should_commit
      path = "android/app/build.gradle"
      git_add(path: path)
      git_commit(path: path, message: commit_message)
      # Push the new commit and tag back to your git remote
      push_to_git_remote if should_push
    end
  end
end

Теперь мы можем управлять нашими полосами:

bundle exec fastlane android beta

Сделайте все, что мы сделали до сих пор в репозитории GIT:

git add --all && git commit -m "add fastlane and lanes to publish the app to play store"

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

git push -u origin master

Улучшения

Есть несколько моментов, которые можно улучшить здесь.

Продвигаемые сборки против разных сборков для каждого трека

Мы продвигаем с одного трека к следующему, но это не сработает для всех. Пример: каждый трек должен потреблять различный API, а API установлен через .env файлы

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

Развертывание

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

Смотрите более подробную информацию об этом на Документация для поставка действие Анкет

Внутренний трек против альфа -трек

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

Основным преимуществом этого является то, что внутренние выпуски тестов обрабатываются быстрее, чем другие, недостаток в том, что он ограничен только 100 тестерами.

Вывод

Вот и все! Теперь мы можем загрузить наше приложение в Play Store, выполнив одну команду с помощью Fastlane.

В следующей части мы увидим, как использовать несколько поставщиков CI для автоматического дела при каждом изменении, которое подталкивается к Разработать , Постановка и Мастер ветви.

Оригинал: «https://dev.to/jonathancardoso/automated-deployment-of-react-native-apps-using-fastlane-part-1-play-store-3n0g»