Deploy (выкатывание) андроид приложения можно разделить на несколько стадий - публикация для внутренней команды тестирования, развертывание на альфа и бета тестировщиков и, наконец, релиз приложения в Google play маркет. Давайте разберемся, как сделать это удобным для всех и что классный руководитель команды разработки должен учесть при построении системы. Поехали...
Все сказанное ниже (и выше) применимо не только к сборке android, но и вообще любых мобильных приложений, да что там - вообще любых продуктов, которые в конечном итоге надо доставить до потребителя.
Для кого мы это делаем?
Для начала давайте выделим широкие группы людей, их цели и интересы.
Разработчики приложения
Собственно команда разработки, которая пишет код и хочет
- Чтобы их не дергали, когда нужно в очередной раз выкатить сборку для тестировщиков
- Быть уверенной в том, что тестировщики проверяют именно ту версию, которая пойдет в релиз
- Спокойно по очереди уйти в отпуск и не остановить весь проект, потому что "некому собрать приложение"
Команда тестирования - QA
Те, кто отвечает за качество конечного продукта и надеется, что
- Именно протестированная версия уйдет в релиз
- Если задача закрыта в таск трекере, то сборка с фиксом уже доступна для скачивания
- Получение очередной сборки не будет причинять боль и страдания, а будет проходить максимально легко и непринужденно
Внешние тестировщики, инвесторы и другие причастные
Наши бета тестеры, которые будут получать предрелизные сборки, и которые
- Не будут ставить приложения из полученного не пойми как APK
- Не всегда смогут справится с любым flow, отличным от "зайти в google play, установить приложение"
- Хотят получаться максимально стабильный билд с новым функционалом
Конечные пользователи приложения
Сюда могут входить не только люди, которые скачают и будут пользоваться финальной версии приложения, но и заказчик, друзья заказчика и т.д. и т.п.
Люди из этой группы
- Будут пользоваться финальным зарелиженным продуктом
- Могут "надавать по шапке" за очевидные баги
- Ждут стабильной, оттестированной версии продукта как только она будет готова
Что нужно знать?
Чтобы обеспечить постоянный контроль того, что делает команда разработки (а если этого не сделать, то чёрт его знает что в итоге может получиться), мы будем придерживаться принципов Continuous Integration (непрерывная интеграция) и Continious delivery (непрерывная доставка) которые предполагают, что как только очередной функционал готов с точки зрения команды разработки - он тут же будет доставлен дальше по цепочке.
Для примера мы будем использовать
- Beta from Fabric поможет доставить ваше приложение для внутренних тестировщиков, если вы хотите
- использоваться несколько разных сборок, но не создавать "приложение" в google play под каждую
- начать deploy вашего приложения, не заполняя перед этим всех данных для приложения в google play (иначе не выйдет использовать их каналы дистрибуции)
- Tiple-T плагин, который поможет автоматизировать доставку приложения в google play
Как это работает
Как только код попадает в стабильную ветку, например develop, master, rc (исходя из gitflow) сервер сборки упакует приложение и отправит определенным группам получателей.
Подключения вашего репозитория к CircleCI
Если проект у вас на Github, Bitbucket - то интеграция с CircleCI работает из коробки.
Возможный конфиг для CircleCI
version: 2
jobs:
develop_build:
working_directory: ~/code
docker:
- image: circleci/android:api-28-alpha
environment:
JVM_OPTS: -Xmx3200m
steps:
- checkout
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Pull Submodules
command: |
git submodule sync --recursive
git submodule update --recursive --init
- run:
name: Chmod permissions
command: chmod +x gradlew
- run:
name: Download Dependencies
command: ./gradlew androidDependencies
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Generate fabric config
command: ./gradlew fabricProp
- run:
name: Build dev release
command: ./gradlew assembleDevDebug -PversionCode=$CIRCLE_BUILD_NUM
- run:
name: Upload dev release to fabric
command: ./gradlew crashlyticsUploadDistributionDevDebug
rc_build:
working_directory: ~/code
docker:
- image: circleci/android:api-28-alpha
environment:
JVM_OPTS: -Xmx3200m
steps:
- checkout
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Pull Submodules
command: |
git submodule sync --recursive
git submodule update --recursive --init
- run:
name: Chmod permissions
command: chmod +x gradlew
- run:
name: Download Dependencies
command: ./gradlew androidDependencies
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Generate fabric config
command: ./gradlew fabricProp
- run:
name: Build RC
command: ./gradlew assembleRcRelease -PversionCode=$CIRCLE_BUILD_NUM
- run:
name: Upload RC to fabric
command: ./gradlew crashlyticsUploadDistributionRcRelease
master_build:
working_directory: ~/code
docker:
- image: circleci/android:api-28-alpha
environment:
JVM_OPTS: -Xmx3200m
steps:
- checkout
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Pull Submodules
command: |
git submodule sync --recursive
git submodule update --recursive --init
- run:
name: Chmod permissions
command: chmod +x gradlew
- run:
name: Download Dependencies
command: ./gradlew androidDependencies
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- store_artifacts:
path: app/build/reports
destination: reports
- store_test_results:
path: app/build/test-results
- run:
name: Upload Prod build to Google play
command: ./gradlew publishProdReleaseBundle -PversionCode=$CIRCLE_BUILD_NUM
workflows:
version: 2
build_app:
jobs:
- develop_build:
filters:
branches:
only: develop
- master_build:
filters:
branches:
only: master
- rc_build:
filters:
branches:
only: /rc\/.*/
Workflows содержит 3 конфигурации, которые запускаются в случаях, попадаемых под фильтры, а именно
- Если был залит код в ветку develop, то соберется devDebug версия и отправится в Fabric Beta
- Если был залит код в ветку rc/{что-угодно}, то соберется rcRelease версия и отправится в Fabric Beta
- Если был залит код в ветку master, то соберется releaseBundle версия и отправится в Google play в канал для внутреннего тестирования
Чтобы обфускация не усложняла жизнь разработчику, для внутреннего тестирования можно выкатывать версию без нее, но важно проверить приложение и с обфускацией, потому что она может сломать сборку!
В данном конкретном случае каждый flavor нацелен на разные контура на сервере и у каждого свой отдельный суффикс и иконка, что удобно при тестировании.
Метод fabricPror выставляет необходимые ключи для деплоя версии в fabric beta:
task('fabricProp') {
doLast {
def propertiesFile = file('fabric.properties')
def commentMessage = "This is autogenerated fabric property from system environment to prevent key to be committed to source control."
ant.propertyfile(file: "fabric.properties", comment: commentMessage) {
entry(key: "apiSecret", value: System.getenv('crashlyticsBountyApisecret'))
entry(key: "apiKey", value: System.getenv('crashlyticsBountyApikey'))
}
}
}
При этом crashlyticsBountyApisecret и crashlyticsBountyApikey это переменные, заданные на сервере CircleCI, т.е. необязательно ведь всей команде знать конфиденциальные данные, верно?
Там же, кстати, хранятся и ключи для сертификатов подписи приложения.
Доставка приложения в Fabric Beta
Плагин от Firebase позволяет выбрать на какую группу пользователей раскатить новую версию, а переданный $CIRCLE_BUILD_NUM каждый раз увеличит версию приложения, позволяя корректно обновить предыдущую установленную версию.
def getBuildNumber = { ->
def DEFAULT_CODE = 1
def code = project.hasProperty('versionCode') ? versionCode.toInteger() : DEFAULT_CODE
println "BuildNumber is set to $code"
return code
}
....
versionCode getBuildNumber()
....
Доставка приложения в Google play
Как только приложение протестировано на внутренней сборки, можно отправить версию в канал дистрибуции для внутреннего тестирования в Google play, с чем нам и поможет плагин Triple-T, настройку которого можно найти у него же на странице на github.
Вместо заключения
Ценно не только то, на сколько хорошо вы пишите код, но и то, как вы умеете коммуницировать со своей командой и делать жизнь каждого проще и приятнее. А если продукт, над которым ваша команда работает планирует развиваться, то упрощение процесса разработки и деплоя сэкономит уйму сил, времени и нервов, потому что это то, что будет происходит каждый ваш рабочий день и то, что точно стоит автоматизировать.
Успех - это сумма маленьких достижений, повторяющихся изо дня в день
Оригинал статьи размещен здесь: https://dimlix.com/deploy-android-app-with-ease/