Привет! Я Даша, 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_LINKNEXUS_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 :)
 
           
 
turlir
Из статьи следует что в Nexus вы отправляете только apk файл. Не думали так же поступать с маппингом R8?