Привет! Я Даша, Android-разработчик в команде онлайн кинотеатра PREMIER. В прошлой статье я рассказывала, как мы настроили сборку проекта с помощью Gitlab CI. Дальше нужно отправить приложение в маркеты для внутреннего тестирования, а затем конечным пользователям.

Если не хочется скачивать билд и уходить в работу с консолями, чтобы загрузить приложение, то есть решение! 

Сегодня разберемся, как автоматически опубликовать приложение в Google Play, Huawei App Gallery и Firebase на примере нашего приложения онлайн-кинотеатра PREMIER. Также расскажу, как мы отправляем сборку в Nexus.

Подготовка

Для начала нам нужно добавить новый stage — deploy и поставить его после build:

stages:
  - build
  - deploy

Таким образом скрипты запустятся после того, как приложение будет собрано. 

Как я писала в прошлой статье, лучше выделить группы скриптов и разделить их на отдельные файлы. Для сборок создадим файл .gitlab-ci-deploy.yml и при создании каждой джобы мы добавим следующие строки:

stage: deploy 
when: on_success
 needs:
    - job: JOB_NAME
      artifacts: true

В when указываем условия запуска джобы. Для автоматического запуска нам нужно успешное выполнение предыдущей джобы сборки приложения, поэтому мы указываем on_success. Если мы хотим запускать вручную, то можем указать manual.

В поле needs.job мы указываем название джобы сборки и atrifacts:true, чтобы переиспользовать файлы, сгенерированные в ней.

Публикация в Google Play

Для публикации в Google play мы используем Gradle Play Publisher. Мы стараемся придерживаться единого стиля и поэтому везде для деплоя используем Gradle плагины.

Google_PublishAlpha:
  stage: deploy
  when: on_success
  variables:
    GOOGLE_PLAY_TRACK: "alpha"
  needs:
    - job: _Google_ReleaseBundle
      artifacts: true
  script:
    - ./gradlew -Pbuildnum="${CI_JOB_ID}" --console=plain :${APPLICATION}:publishGoogleReleaseBundle --track ${GOOGLE_PLAY_TRACK} --artifact-dir ${ARTIFACT_PATH}

Выделенные строки мы добавили при подготовке.

 variables:
    GOOGLE_PLAY_TRACK: "alpha"

Мы пока что публикуем только alpha версии, что указываем с помощью GOOGLE_PLAY_TRACK, но можно указывать и beta, internal, и production.

ARTIFACT_PATH — путь к сборке у нас выглядит таким образом: sources/app/build/outputs/bundle/googleRelease/;

APPLICATION — app или tv, так как у нас 2 модуля для разных платформ;

Публикация в Huawei App Gallery

Для публикации draft сборки в Huawei App Gallery используем Huawei App Gallery Publishing и App Gallery Connect.

Пайплайн публикации теперь выглядит так:

Huawei_PublishDraft:
  stage: deploy
  when: on_success
  needs:
    - job: _Huawei_ProdBundle
      artifacts: true
  script:
    - AAB_ARTIFACT_PATH=$(find $ARTIFACT_PATH -name "*.aab")
    - ./gradlew -Pbuildnum="$CI_JOB_ID" --console=plain :${APPLICATION}:publishHuaweiAppGalleryHuaweiRelease --buildFile=${AAB_ARTIFACT_PATH}

ARTIFACT_PATH — sources/app/build/outputs/bundle/huaweiRelease

APPLICATION — app или tv

В build.gradle мы прописываем конфигурацию для плагина:

apply plugin: 'ru.cian.huawei-publish-gradle-plugin'
…
huaweiPublish {
    instances {
        huaweiRelease {
            credentialsPath = "$PATH_HUAWEI_CRED"
            deployType = "draft"
            buildFormat = "aab"
        }
    }
}

PATH_HUAWEI_CRED ведет к json c client_id и client_secret.

Публикация в Nexus

Также для наших сборок мы используем Nexus — систему хранения артефактов. Скрипт отправки сборки для него выглядит таким образом:

_Google_PublishNexus:
  stage: build
  when: manual
  needs:
    - job: _Google_ReleaseApk
      artifacts: true
  script:
    - ARTIFACT_NEXUS_NAME=${CI_COMMIT_BRANCH#*/}
    - curl -v -u $NEXUS_LOGIN:$NEXUS_PASSWORD --upload-file $ARTIFACT_PATH $NEXUS_LINK

NEXUS_LINK — путь, где будет лежать наша сборка;

CI_COMMIT_BRANCH — предопределенное значение названия ветки, про другие переменные можно почитать тут;

NEXUS_LOGIN и NEXUS_PASSWORD нужны для авторизации в Nexus. 

Публикация в Firebase App Distribution

Публикацию через Firebase можно сделать с помощью App Distribution Gradle plugin:

Google_PublishFirebase:
  stage: deploy
  when: manual
  needs:
    - job: _Google_DebugBundle
      artifacts: true
  before_script:
    - export GRADLE_USER_HOME=$(pwd)/.gradle
  script:
    - ./gradlew --console=plain :app:appDistributionUploadGoogleDebug
      -Pci
      -Pbuildnum="$CI_JOB_ID"
      -PappDistribution-artifactType="AAB"
      -PappDistribution-groups="premier_qa"
      -PappDistribution-testers="$GITLAB_USER_EMAIL"
      -PappDistribution-releaseNotes="for $GITLAB_USER_NAME, job=$CI_JOB_URL, pipeline=$CI_PIPELINE_URL"
    artifacts:
    name: "$CI_JOB_STAGE-$CI_COMMIT_REF_NAME"
    paths:
      - "$PATH_HANDHELD_BUNDLE_PREPROD_DEBUG"
    expire_in: 1 week

CI_JOB_ID — идентификатор джобы;

GITLAB_USER_EMAIL — почты тестировщиков через запятую, кому будет доступна опубликованная версия приложения, например: "nikita@example.com, stas@example.com, gena@example.com";

GITLAB_USER_NAME — предопределенная переменная никнейма текущего пользователя гитлаб;

CI_JOB_URL — ссылка на джобы;

CI_PIPELINE_URL — ссылка на пайплайн.

Для РФ плохо подходит, т.к. есть запреты на скачивание apk напрямую из App Distribution, работает только с VPN. 

Итог

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

Gitlab CI содержит свое хранилище, но если вам этого будет недостаточно, то можно использовать Nexus и Firebase, но Firebase подходит не всем.

В следующей статье я расскажу вам про автоматическую публикацию приложений в RuStore :)

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


  1. turlir
    14.08.2023 15:24

    Из статьи следует что в Nexus вы отправляете только apk файл. Не думали так же поступать с маппингом R8?