Jenkins android build apk

Continuous Integration для Android с использованием Jenkins + Gradle

Хочу поделится своими наработками по автоматической сборке Android приложения. В этой статье я приведу пример сборки для двух типов приложений, первый — простое приложение, содержащее в отдельной папке unit-тесты, второй — приложение использующее проект-библиотеку (android library project).

В конечном итоге мы получим отчет о выполненных тестах а так же подписанный apk файл, доступный для скачивания из артефактов сборки Jenkins.

Требования для настройки автоматических сборок

  1. Необходимые плагины Jenkins
    • Android Emulator Plugin
    • Git Plugin (если вы используете git)
    • Multiple SCMs Plugin (для возможности работать с несколькими репозиториями)
    • Xvnc Plugin (для возможности запуска эмулятора, если на сервере не установлен X server)
  2. Android SDK
    Загружаем отсюда. Раздел DOWNLOAD FOR OTHER PLATFORMS -> SDK Tools only
  3. Gradle
    Лучше скачать архив тут (gradle-**-bin.zip) и распаковать в /usr/local/lib
  4. Переменные окружения
    ANDROID_HOME=/usr/local/lib/android/sdk
    GRADLE_HOME=/usr/local/lib/gradle-1.8
    JAVA_HOME=/usr/lib/jvm/jdk1.7.0_03
    PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$JAVA_HOME/bin:$GRADLE_HOME/bin
  5. Библиотека для запуска эмулятора
    На случай если Jenkins работает на 64-битной ОС, необходимо добавить библиотеку ia32-libs, иначе эмулятор не запустится
    sudo apt-get install ia32-libs

Когда все требования выполненны, приступаем к настройке

В своей работе я использую Eclipse, поэтому проекты имеют, так сказать, старую структуру, не типичную для gradle проектов (такую как создает androidStudio). Дальнейшие примеры будут приведены исходя из того что проект выглядит таким образом:

Настройка

Для запуска тестов, достаточно указать секцию instrumentTest в android.sourceSets, в которой будут указаны пути к папкам в тестовом проекте. Когда я разбирался с Gradle видел не одну статью, в которой было написано что для запуска unit-тестов необходимо создать отдельную задачу, создать для нее отдельную запись в sourceSets и добавить в зависимости junit. В общем только зря потратил на это время, все гораздо проще.
Часть конфига, отвечающую за подписывание приложения, опишу немного ниже. После создания конфига приступим к настройке Jenkins.

Настройка Jenkins

Первым делом необходимо указать репозиторий с проектом. Затем необходимо выбрать пункт Run an Android emulator during build в котором необходимо выбрать один из двух вариантов — либо указать имя существующего эмулятора, либо указать параметры для запуска нового. При этом оставить галочку на пункте Show emulator window
Следующим делом необходимо добавить шаг сборки Invoke Gradle script и указать необходимые команды для Gradle. Для сборки и прогона тестов достаточно указать build и connectedCheck

Последним делом необходимо добавить действия выполняемые после сборки.
1. Publish JUnit test result report (публикуем отчеты о выполнении unit тестов). В строке для xml файла, с отчетом о выполненных тестах, необходимо прописать следующий путь:
**/build/instrumentTest-results/*/*.xml
Gradle создает 2 типа отчета — html и xml. HTML отчеты можно найти в папке build/reports/instrumentTests/connected/, но для Jenkins необходимо указать xml отчет.
2. Заархивировать артефакты (даем возможность скачать скомпилированное подписанное прилоежение прямо из артефактов). Путь к файлу для архивации:
**/build/apk/workspace-release.apk
Теперь вернемся к подписыванию приложения

Подпись приложения

Для подписи приложения необходимо иметь ключ созданный с помощью утилиты keytool, в котором будут хранится данные о разработчике приложения. Стандартная команда для создания:
keytool -genkey -v -alias appAlias -keyalg RSA -keysize 2048 -keystore release.keystore -validity 10000
Параметр alias необходимо исползьовать для каждого приложения свой, его потом необходимо будет указывать при подписывании приложения.

В целях безопасности ключ не стоит держать под системой контроля версий, т.к. имея этот ключ можно подписать любое другое приложение, но системой оно будет распознаваться как одно и то же. Поэтому файл необходимо хранить непосредственно на сервере CI.
Исходя из этих соображений, я добавил в корень проекта файл gradle.properties, в котором указал всего пару настроек:
Значение releaseSigningPropertiesPath указывает на путь (относительно домашней директории,

/.androidSigning/) по которому расположен файл с параметрами для ключей (пароли и alias). Для проекта в этой папке должно хранится 4 файла:
release.keystore — ключ для релизной сборки приложения
releaseProperties — параметры для релизного ключа
debug.keystore — ключ для дебаг сборки приложения
debugProperties — параметры для дебаг ключа

Каждый из файлов *Properties должен иметь следующую структуру:

Пример:
Все эти параметры указываются при создании ключа.

Все остальные действия были указаны в файле build.gradle. Чем удобен Gradle, тем что внутри конфига можно так же выполнять обычный java код, что и позволило сделать подобный механизм подписи. Все, теперь смело можно запускать сборку и получать подписанное и протестированное приложение.
Теперь давайте рассмотрим второй пример сборки приложения, которое использует приложение-библиотеку.

Читайте также:  Навител федеральный округ для андроид

Сборка приложения использующего android-library

Основное отличие проекта-библиотеки это применяемый плагин: apply plugin: ‘android-library’

Второй конфиг уже внутри проекта

Теперь необходимо правильно указать репозитории в Jenkins.
В отличии от предыдущего примера, в этом случае в разделе «Управление исходным кодом» необходимо выбрать не какую то конкретную систему контроля версий а «Multiple SCMs». После чего будет возможность добавить свою систему и указать путь к репозиторию. Первым необходимо указать репозиторий с проектом, вторым — с библиотекой, при этом для репозитория с библиотекой следует указать дополнительную настройку «Check out to a sub-directory», содержащую имя папки в которой будет находится код. Имя этой папки должно соответствовать имени проекта, которое мы указали в зависимостях внутри файла build.gradle (в примере это MyLibrary)
compile project(‘:MyLibrary’)
Таким образом рабочая директория будет выглядеть как обычный проект, только с одной дополнительной папкой MyLibrary, в которой будет находится библиотека.

Все остальные настройки точно такие же как и для обычного проекта.

Источник

Jenkins для Android на чистой системе и без UI

На Хабре уже есть похожие статьи на тему сборки Android приложения с помощью Jenkins. Ключевыми особенностями/дополнениями текущей будет следующее:

  1. Мы установим Jenkins на удалённую Linux машину, где отсутствует UI.
  2. Мы будем собирать приложение из приватного репозитория.
  3. Мы решим проблему сборки приложения из ветки имя которой нам не известно.
  4. После сборки .apk файлов мы отправим их в Fabric и оповестим тестировщиков.
  5. После отправления в Fabric мы опубликуем приложение на Google Play.
  6. Защитим задачи по публикации приложения от запуска тестировщиками.

Установка jenkins

Итак, вы получили доступ на сервер. UI там отсутствует, но это совсем не проблема.
Для начала давайте установим сам jenkins сервер.

Более подробно о том, что делает установка этого пакета можно почитать в официальной документации.

После установки, в директории /var/lib/jenkins будет находиться сам Jenkins, репозитории проектов и другие необходимые для работы Jenkins файлы. Теперь вы уже можете зайти в Jenkins через браузер и начать конфигурирование своего CI сервера.

Однако перед этим необходимо установить всё необходимое для сборки Android приложения.

Установка Android SDK+JAVA

На официальном сайте внизу можно найти ссылки на тот дистрибутив, который нам нужен. Обычно его устанавливают вместе с Android Studio, однако в нашем случае, она нам не нужна, поэтому выбираем нужную ссылку и загружаем инструменты командной строки(Command Line Tools).

На момент написания статьи актуальная версия для Linux была: android-sdk_r24.4.1. Для установки выполняем команды:

Далее вам необходимо скачать используемые в вашем проекте Platform Tools, Build tools и текущее API, для которого вы собираете приложение. Для этого загляните в build.gradle файл вашего проекта (на уровень модуля приложения). Например, в моём проекте интересующая нас часть выглядит следующим образом:

Это наглядно показывает, какие версии нам необходимо скачать. Для того, чтобы мы могли скачать необходимые нам компоненты, добавим в системные переменные следующие параметры:

Далее в большинстве гайдов предлагается просто скачать все компоненты с помощью команды:

Но так как нам жалко впустую тратить место на жёстком диске, мы будем скачивать только то, что нам нужно. Выполним команду, чтобы узнать, что именно нам нужно скачивать:

Результаты выглядят следующим образом:

Теперь мы можем установить только то, что нам нужно с помощью команды:

Теперь поставим JAVA с помощью команды:

Отлично! Мы поставили всё необходимое для сборки Jenkins и сборки приложения. Теперь переходим к настройке Jenkins.

Настройка доступа к приватному репозиторию

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

Итак, мы решили, что мы будем всё делать правильно и доступ к репозиторию получать по SSH. Для этого нам надо сгенерировать ssh ключ и положить его в директорию /var/lib/jenkins/.ssh.

Когда вы установили jenkins, был автоматически сгенерирован пользователь с именем jenkins на unix машине. Для того, чтобы jenkins мог использовать ключ, проще всего будет его сгенерировать из-под jenkins пользователя.

После этого будет сгенерировано 2 файла (со стандартными именами id_rsa, id_rsa.pub). Файл id_rsa необходимо положить в директорию /var/lib/jenkins/.ssh, после этого необходимо в настройках github репозитория добавить Deploy Key (содержимое файла id_rsa.pub).

Выглядит это следующим образом:

Далее надо добавить URL репозитория в список известных. Для этого попробуем обратиться к репозиторию и получить список веток репозитория.

И соглашаемся на добавление github в список известных хостов. Если у вас нету доступа к файлу id_rsa, значит вы создали его не из-под jenkins пользователя, и в этом случае вам надо дать доступ jenkins пользователю на работу с этим файлом:

После выполнения этих шагов мы сможем получить доступ к нашему приватному репозиторию для сборки Android приложения.

Читайте также:  Импорт контактов андроид гугл

Создание задачи для сборки приложения

Теперь перейдём в jenkins. По умолчанию он будет доступен на порту 8080. Перейдем в любом браузере на данный порт. После первого запуска залогиниться можно будет с помощью пароля, который находится в файле /var/lib/jenkins/secrets/initialAdminPassword. После этого вы попадаете в Jenkins панель. Для начала нам нужно настроить путь к ANDROID_HOME директории.

Manage Jenkins(Настроить Jenkins) → System Configuration(Конфигурирование Системы):

Также настроим пути к JDK, версию Gradle и Git. Для этого укажите директорию, где хранится JAVA, и добавьте необходимую для сборки версию gradle.

Manage Jenkins(Настроить Jenkins) → Global Tool Configuration:

Теперь мы можем создать первую задачу для сборки приложения. Выберем создание задачи со свободной конфигурацией. На вкладке с «Управлением исходным кодом» выбираем git. Далее указываем url git репозитория для доступа по ssh. Для первой задачи будем собирать из ветки мастера. Именно она по умолчанию и указана.

Далее добавим шаг сборки с помощью запуска gradle скрипта. Выбираем gradle версию, добавленную ранее. На всех важных полях находятся подсказки, зачем они нужны. Например, если у вас нестандартная структура проекта, то вам нужно указать место, где находит корневой build.gradle файл проекта и имя файла, если оно отличается от build.gradle.

Далее заархивируем .apk файлы, чтобы можно было их позже скачать тестировщикам или кому-нибудь другому. Для этого надо добавить послесборочную задачу и указать формат, какие файлы мы хотим сохранять. Первый раз при создании задачи я предполагал, что поиск нужного файла производится с помощью формата регулярного выражения, однако оказалось, что для поиска файлов Jenkins использует Ant path style. Стандартно предлагается сохранять все файлы с расширением .apk, однако большая часть из них нам не нужна, поэтому будем сохранять только те, которые заканчиваются на debug.apk, и release.apk.

Сборка подписанных apk с помощью build.gradle скрипта

Для публикации приложения в Google Play .apk файл должен быть подписан специальным ключом. Если вы подписывали с помощью Android Studio, указывая путь к файлу, то надо научиться делать это из build.gradle скрипта. Далее мы рассмотрим самый простой пример и способы, как его можно улучшить. Достаточно положить ключ под версионный контроль, и после этого ссылаться на него из build скрипта. Вот пример, как это можно реализовать.

Недостатком решения является то, что ваш приватный ключ хранится под версионным контролем, как и пароль для сборки релизной версии приложения. Обратите внимание на то, что даже если вы в будущем уберёте ключ и поправите build.gradle скрипт, то существует вероятность, что кто-нибудь, покопавшись в истории коммитов, восстановит эту информацию, так что будьте внимательны. Более правильным решением было бы держать property файл, который не находится под версионным контролем и лежит, например, в

/home директории, в котором были бы написаны все необходимы параметры.

Например, в нашем проекте используется следующий подход. Файл с настройками и файл для подписи отсутствуют в версионном контроле. У разработчиков они подложены руками. Таким образом, мы решаем проблему того, что кто-то, кому этого делать не следуют, может подписать ваше приложение. Теперь надо решить проблему, чтобы подписывать приложение мог сам Jenkins. Для этого будем при подписи приложения проверять наличие файла в двух местах. Первое — это корневая директория проекта. Второе — определённое место на сервере, где ожидается, что этот файл должен храниться. Далее вы подкладываете этот файл на jenkins сервер и получаете возможность собирать подписанные версии приложения. Вот пример gradle скрипта, как это реализуется:

Публикация тестовых сборок в Fabric и оповещение тестировщиков

Fabric — замечательная система для сборка креш-репортов по вашему приложению. Если вы используете стандартную гугл аналитику для сборки крешей, то очень рекомендую посмотреть fabric или firebase. Для использования Fabric нам понадобится установить jenkins плагин.

Настроить jenkins(Manage Jenkins) → Управление плагинами (Manage Plugins) вкладка Доступные, вводим Fabric. Нас интересует Fabric Beta Publisher. После его установки вернёмся в описание задачи и добавим ещё один.

Необходимо указать Fabric_api_key, а также secret_key, и указать относительный путь к .apk файлу приложения, которое мы будем заливать для тестировщиков. Посмотреть эти значения можно в личном кабинете fabric. Settings → Organizations → → API_KEY, Build Secret.

Далее вы можете прислать нотификации для ваших тестировщиков. Можно указывать как email, так и группу тестировщиков. Каким образом управлять группами, вам будет виднее лучше всего самим. Например, мы предпочитаем использовать 2 группы: dev, production. Все тестовые сборки приложений нотифицируют dev группу тестировщиков, а сборки, которые будут заливаться в Google Play, нотифицируют production группу тестировщиков.

Далее, если наши сборки каким-то образом отличаются друг от друга, то нам необходимо указать эту информацию в Build Notes для тестировщиков. Делаем это через Environment Variable и скрипт, который будет заполнять данную информацию.

Читайте также:  Как сбросит андроид до заводских настроек самсунг

На нашем проекте придерживаются следующего подхода. Когда приходит время релиза, из master ветки создаётся ветка delivery_xx, где xx — это номер спринта. К сожалению, Jenkins по умолчанию не умеет собирать сборки из веток, где имя ветки может меняться. Нам придётся научить его этому самим.
Для этого нам понадобится установить ещё один плагин — EnvInject. После этого возвращаемся в вид задачи и устанавливаем новую опцию — Prepare an environment for the run. Благодаря этому плагину мы можем выполнить какой-либо groovy скрипт, и после этого сохранить в переменных среды все необходимые результаты.

В нашем случае, нам необходимо получить список веток у репозитория и найти ветку, имя которой начинается на delivery. Также, нам надо установить build notes для тестировщиков, чтобы они знали, из какой ветки производилась сборка приложения. Скрипт для этого будет выглядеть следующим образом:

Несомненно, тут вы можете дописать любую необходимую в вашем конкретном случае логику.
Далее подправим имя ветки с которой будет производится сборка.

И обновим блок публикации приложения в fabric, как показано на скрине выше.
Теперь мы умеем делать почти все пункты, описанных в начале статьи, и нам осталось только научиться публиковать итоговую сборку приложение в google play.

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

Для нас уже подготовили плагин для публикации приложений в Google Play с помощью Jenkins. Ставим его: Google Play Android Publisher Plugin. Далее нам необходимо создать специальный сервисный аккаунт, который будет заниматься публикацией приложений в Google Play. Для этого необходимо выполнить следующие шаги:

  1. Заходим в консоль разработчика под владельцем аккаунта.
  2. Настройки → Доступ к API.
  3. Нажимаем «Создать проект».
  4. Нажимаем «Создать аккаунт приложений».
  5. Переходим по ссылке.
  6. В выпадающем списке нажимаем «Edit» и меняем имя аккаунта на необходимое, например «Jenkins».
  7. В выпадающем списке выбираем «Сreate key» и выбираем тип ключа «JSON».
  8. Нажимаем создать ключ.
  9. Автоматически будет загружен файл, который позже будет использоваться для аутентификации в консоли разработчика плагина для публикации приложения.

То же самое в картинках:

Далее необходимо выдать соответствующие доступы в консоли разработчика для созданного сервисного аккаунта и публикации приложений. Для этого выполняем следующие шаги:

  1. Возвращаемся в консоль разработчика
  2. Для созданного аккаунта приложений нажимаем «Открыть доступ»
  3. Для созданного аккаунта приложений нажимаем «Открыть доступ»
  4. Необходимо убедиться, что есть разрешения для Изменения информации о приложении и управлении Production, Alpha и Beta версиями приложения
  5. Нажимаем добавить

То же самое в картинках:

Теперь мы можем выйти из консоли разработчика и перейти к настройке Jenkins для публикации приложения.

  1. Переходим в Jenkins
  2. Выбираем пункт меню «Credentials»
  3. Выбираем общие доступы и нажимаем «Add Credentials»
  4. Выбираем тип доступа: «Google Service Account from private key»
  5. Вводим имя доступа(позже будет использоваться в настройке задачи), например android-publish
  6. Выбираем тип «JSON key»
  7. Загружаем файл, который мы ранее скачали «JSON key»
  8. Нажимаем ОК, чтобы создать доступ

Тоже самое в картинках:

Далее переходим в вид задачи и добавляем Шаг после сборки — Upload Android APK to Google Play.
Необходимо указать credentials для этого шага, которые мы добавили ранее. А также путь к apk файлу и информацию, какой процент пользователей необходимо перевести на данную версию. Вероятно, изначально это будет 100%. Также необходимо указать, какую версию .apk файла вы заливаете. Вы можете публиковать alpha, beta, production версии через jenkins. После этого, можно спокойно запускать задачу, а самому идти пить чай, пока jenkins сделает за вас всю рутинную работу по сборке, подписыванию приложения и публикации.

Защита критических задач

Теперь мы умеем создавать задачи, можем давать доступы тестировщикам, и они сами будут собирать себе сборки приложений, когда им это будет нужно. Естественно, мы не хотим, чтобы наши QA случайно опубликовали приложение. Предлагаю поступить следующим образом.
Нам будет необходимо вынести публикацию приложения в отдельную задачу и забрать доступы у QA по запуску этой задачи.

  1. Переходим в Настройки Jenkins → Сonfigure Global Security
  2. Блок «Авторизация» → выбираем пункт «Project-based Matrix Authorization Strategy»
  3. Сразу добавляем своё имя пользователя и выставляем для себя все пункты как доступные. Если не сделать этот пункт, вы запретите доступ для самого себя из jenkins (если всё-таки так случилось, смотрите решение тут).
  4. Далее добавляете имя пользователя QA, и устанавливаете ему разрешения, которые считаете нужными. Для нас принципиально не давать ему запускать задачи. Блок «Задача», пункт «Build»
  5. После этого переходим к задаче, доступ для которой хотим дать QA, и даём ему соответствующие доступы.

Теперь наши QA не смогут случайно опубликовать приложение в Google Play.

Пожалуй, на этом всё. Мы могли бы и дальше улучшать автоматическую сборку и публикацию приложений, однако это выходит за рамки данного tutorial.

Источник

Оцените статью