Для этого нам понадобится
-
Действующий account Google Play Developer
-
Сервер Linux с предустановленным Docker, в моём случае это Ubuntu 16.04
-
Установленный Android SDK
-
Jenkins - в данном случае развернём его при помощи Docker
-
Gitea - Удобная служба для собственного Git-репозитория (это не обязательно можно использовать и GItHub) её мы подымем также на базе Docker контейнера
Настройка Google Play Account
Давайте предположим что вы уже действующий разработчик и осуществляли публикацию своих приложений в ручном режиме, что даёт основание полагать что вам известны основные моменты процесса и их озвучивать не стоит, коснёмся лишь того что нам понадобится для автоматического развёртывания
-
Авторизуйтесь в Google Cloud Platform, если еще не создан проект то создаём его
-
В разделе IAM и администрирование - Сервисные аккаунты жмём Создать сервисный аккаунт
-
После заполнения соответствующих полей он будет создан и появится в списке, жмём на три точки с права и выбираем создать ключ, выбираем JSON, сохраните его он нам понадобится для настройки Jenkins
-
Авторизуйтесь в Gooogle Play Developer Console
-
В разделе Пользователи и разрешения нажимаем пригласить пользователя сервисного аккаунта по сгенерированному email , выставляем ему роль Релиз менеджер (при необходимости можете настроить права этого пользователя более детально)
-
Я предполагаю что Сертификат для ключа подписи приложения, и Сертификат ключа загрузки у вас уже настроен и это не требует пояснений.
Установка Android SDK
# Install latest JDKsudo apt install default-jdksudo apt install android-sdk
Добавьте Android SDK в свой PATH,
откройте~/.bashrc
в редакторе и скопируйте следующие
строки
# Export the Android SDK path export ANDROID_HOME=$HOME/android-sdkexport PATH=$PATH:$ANDROID_HOME/tools/binexport PATH=$PATH:$ANDROID_HOME/platform-tools# Fixes sdkmanager error with java versions higher than java 8export JAVA_OPTS='-XX:+IgnoreUnrecognizedVMOptions --add-modules java.se.ee'
Для проверки запустите
source ~/.bashrc
Для того что бы просмотреть все доступные инструменты сборки выполните команду
sdkmanager --list
По аналогии с выполните установку интересующих вас версий инструментов для нужных платформ
sdkmanager "platform-tools" "platforms;android-28"
На этом установка Android SDK может считаться завершённой, и в дальнейшем нам понадобится лишь путь к установленным инструментам, в моём случае это выглядит как то так
Установка Gitea
Этот шаг является опциональным и совсем не обязательным если вы предпочитаете использовать git репозитарии такие как GitHub и им подобные и его можно пропустить, это малой степени повлияет на конечный результат. (На базе gitea в дальнейшем будет обсуждаться тема создания Telegram Bot`a для оповещения о публикациях)
Подробно по установке и настройке написано на оф сайте https://docs.gitea.io/en-us/install-with-docker/
По факту установка сводится к выполнению 2х действий
1) Перейдите на официальный репозитарий Gitea , на Docker HUB и скопируйте то что там написано в предварительно созданный файл
version: '2'services: web: image: gitea/gitea:1.12.4 volumes: - ./data:/data ports: - "3000:3000" - "22:22" depends_on: - db restart: always db: image: mariadb:10 restart: always environment: - MYSQL_ROOT_PASSWORD=changeme - MYSQL_DATABASE=gitea - MYSQL_USER=gitea - MYSQL_PASSWORD=changeme volumes: - ./db/:/var/lib/mysql
2) Сохраните и запустите команду docker-compose you_filename
3) Gitea установлена и доступна по URL http://you_IP:3000/
4) Создайте пользователя, репозитарий, сделайте PUSH исходного кода вашего проекта, и в моём случае для упрощения процесса публикации приложения все необходимые ключи для его подписи и деплоя я храню в месте с исходным кодом в системе контроля версий (да знаю это не совсем верно и вы вольны делать так как считаете нужным, к примеру создать отдельный volume для ключей и пробрасывать их jenkins для дальнейшего их использования gradle при подписании приложения, описание этого лишь раздует статью и потому не будет рассматриваться)
Предварительная настройка проекта
Для подписания нашего apk файла в автоматическом режиме на стороне сервера, нам нужен файл нашего keystore и правильно настроенный скрипт gradle , для этого добавим в него несколько секций
// Load keystoredef keystorePropertiesFile = rootProject.file("keystore.properties")def keystoreProperties = new Properties()keystoreProperties.load(new FileInputStream(keystorePropertiesFile))// GenerateNameVersiondef getVersionNameTimestamp() { return new Date().format('yy.MM.ddHHmm')}// GenerateVersionCodedef getVersionCodeTimestamp() { def date = new Date() def formattedDate = date.format('yyMMddHHmm') def code = formattedDate.toInteger() println sprintf("VersionCode: %d", code) return code}......android { signingConfigs { config { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) storePassword keystoreProperties['storePassword'] } }...... defaultConfig { versionCode getVersionCodeTimestamp() versionName "${getVersionNameTimestamp()}"
Содержимое файла keystore.properties
storePassword=you_password_keystorekeyPassword=you_password_keykeyAlias=you_key_namestoreFile=path_to_keystore_file
-
Я храню как файл с keystore.properties так и сам keystore в системе контроля версий, что не совсем правильно и не безопасно при публикации исходного кода в открытом виде к примеру на GitHub, по этому я не рекомендую использовать данный подход если у вас OpenSource проект , храните и подтягивайте их из отдельной папки.
-
Для публикации в Google Play требуется уникальная версия сборки, и я генерирую её скриптом Gradle на основании текущей даты и времени, и как вы понимаете это исключает использование каких либо вразумительных номеров версий и если вам это важно , то вам придётся придумать некий другой механизм автоматизации версионирования, я же остановился на этом варианте - потому как хотел что бы deploy происходил по нажатию одной лишь кнопки (PUSH)
Установка Jenkins
Его мы развернём используя Docker , я применяю уже настроенный образ с нужными мне инструментами из своего репозитария, вы же вольны использовать официальный, принципиально ни чего не измениться
docker run -it -d -v jenkins_home:/var/jenkins_home -v /usr/lib/android-sdk:/usr/lib/android-sdk -p 8080:8080 -p 50000:50000 --env JENKINS_OPTS="--prefix=/jenkins" --restart always leganas/ls_repository:jenkins
пробрасываем в качестве volumes в в наш контейнер папку с установленным Android SDK
Теперь он запущен и доступен по адресу http://you_IP:8080/jenkins/
После не хитрых манипуляций по заданию пароля Jenkins готов к работе, и теперь нам предстоит его настроить
1) Для начала нам нужно настроить окружение , заходим System Configuration - Глобальные настройки , и добавляем Environment variables (возможно ваши пути будут отличатся)
2) В разделе Настройки - Конфигурация глобальных инструментов проверяем настройки Git и Gradle (по факту обычно там всё уже настроено)
3) Заходим Настройки - Управление пользователями , выбираем пользователя и его настройки, ищем строку API Token , создаём новый и сохраняем его , он нам понадобится.
4) В разделе управления плагинами проверяем и если нужно устанавливаем плагины Git, Git client, Google OAuth Credentials plugin, Google Play Android Publisher
5) Заходим Настройки - Manage Credentials Configure credentials -Store - Jenkins - Global credentials (unrestricted)- и создаём там 2 ключа доступа |
-
для доступа к Git репозитарию
в моём случае т.к. я использую Gitea я создаю обычную пару login/password , для GitHub есть специальный плагин и инструмент для авторизации
-
для публикации приложения в Google Play Market
создаём ключ используя JSON файл который создали в первом разделе данной инструкции
6) Теперь создайте проект вашего приложения в Jenkins и настройте его
-
Управление исходным кодом - установите Git , укажите Repository URL и Credentials (которые создали на прошлом этапе)
-
Триггеры сборки - выставите Trigger builds remotely (e.g., from scripts), в поле ввода введите любой случайный текст (он нам понадобится для удалённой активизации процесса сборки) при помощи GIt huck
-
Добавьте шаг сборки Invoke Gradle script , и После сборочные операции - публикацию
Обратите внимание на поле Release traack , оно указывает то как будет опубликовано ваше приложение , в моём случае это "Внутреннее тестирование"
7) Запустите проект в ручную использую Web интерфейс Jenkins и посмотрите на результат в истории сборок - Вывод консоли Если вы всё сделали верно то ваше приложение должно быть подтянуто из Git репозитария до актуальной версии ветки /master , собрано , подписано и опубликовано на Google Play.
Автоматизация запуска сборки
Если мы всё сделали правильно и проект удачно был опубликован на Google Play , можно перейти к настройке его автоматического deploy по Git событию PUSH в /master ветку
1) Если вы используете Gitea как я то зайдите в репозитарий вашего проекта - Настройки - Git хуки, и в post-receive нажмите редактировать, и добавьте нечто этого рода
#!/bin/bashwhile read oldrev newrev refnamedo branch=$(git rev-parse --symbolic --abbrev-ref $refname) if [ "master" = "$branch" ]; then curl --user you_user_name:you_user_token http://you_url_jenkins/job/you_project/build?token=you_tocken_build fidone
-
you_user_name - Имя пользователя от лица которого jenkins будет производить сборку
-
you_user_token - Токен который был сгенерирован в настройках пользователя
-
you_url_jenkins и вообще весь путь до хука можно посмотреть на странице настройки проекта Jenkins и будет выглядеть он примерно так :
После проведения такого рода манипуляций сборка проекта Jenkins будет начинаться автоматически после PUSH события в master вашего репозитария.
PS. Если же вы используете для хранения вашего кода другую Git систему то этот же код вы можете поместить руками в .git\hooks\post-update
Заключение
В случае положительного фидбэка от статьи, в следующей части я расскажу как написать Telegram бота для оповещения ваших тестировщиков о наличии обновления приложения на Google Play.
Надеюсь эта информация была полезна и как то облегчит вам жизнь по настройки автоматической публикации.