Привет! Я Даша, 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 :)
