Сборка Android приложений на Travis CI

  • Tutorial
В данной статье я хотел бы показать, как можно бесплатно собирать Android проекты (Maven) с открытым исходным кодом на Travis CI.

Что у нас есть?


  • Android проект на github с открытым исходным кодом
  • Проект должен собираться Maven
  • Аккаунт на Travis CI

Что мы хотим получить?


Бесплатную сборку проекта по коммиту с отчётом о выполнении на почту. При этом мы хотим запускать интеграционные тесты на эмуляторе и использовать дополнительные компоненты SDK (addons, extras и т.д.)

Как нам этого добиться?


В качестве основы берём готовые скрипты на github: https://github.com/serso/android-common.
Основной скрипт, который использует Travis CI для сборки — .travis.yml:
language: java
jdk: oraclejdk7

before_install:
  - chmod +x $PWD/.travis_install_android.sh
  - $PWD/.travis_install_android.sh

  - export ANDROID_HOME=$PWD/android-sdk-linux
  - export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools

  - chmod +x $PWD/.travis_install_android_dependencies.sh
  - $PWD/.travis_install_android_dependencies.sh

  - chmod +x $PWD/.travis_start_emulator.sh
  - $PWD/.travis_start_emulator.sh

before_script:
  - chmod +x $PWD/.travis_wait_for_emulator.sh
  - $PWD/.travis_wait_for_emulator.sh

script: mvn install -Pwith-tests

В нём указывается базовый язык проекта — Java, далее версия jdk — я использую JDK 7 от Oracle.
Перед началом сборки нам необходимо установить Android SDK, а также его компоненты (API, extras, addons, etc.). За это отвечают bash скрипты .travis_install_android.sh и .travis_install_android_sdk.sh. Далее нам нужно загрузить некоторые артефакты Android в локальный репозиторий Maven — скрипт .travis_install_android_dependencies.sh, запустить эмулятор — .travis_start_emulator.sh и дождаться его запуска .travis_wait_for_emulator.sh.

Установка Android

#!/bin/sh

# Script installs Android SDK

sudo apt-get update -qq
if [ `uname -m` = x86_64 ]; then sudo apt-get install -qq libstdc++6:i386 lib32z1; fi
wget -O android-sdk.tgz http://dl.google.com/android/android-sdk_r22.0.4-linux.tgz
tar xzf android-sdk.tgz

export ANDROID_HOME=$PWD/android-sdk-linux
export PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools

sudo apt-get install expect
chmod +x $PWD/.travis_install_android_sdk.sh
$PWD/.travis_install_android_sdk.sh

Описание: обновляем список приложений, в случае 64 битной архитектуры — устанавливаем дополнительные пакеты (см. обсуждение здесь). Далее выкачиваем, разархивируем Android SDK и устанавливаем переменные окружения (т.к. переменные окружения в bash скрипте будут сброшены после его выполнения, нам придётся выставить их ещё раз в .travis.yml).

Установка компонентов Android SDK

#!/usr/bin/expect -f

# Script installs Android SDK components

spawn android update sdk --filter tools,platform-tools,build-tools-19.0.0,extra-android-support,android-17,sysimg-17,addon-google_apis-google-17,android-19,sysimg-19,addon-google_apis-google-19,addon-google_apis-google-19,extra-google-play_billing,extra-google-m2repository,extra-google-analytics_sdk_v2,extra-google-gcm,extra-google-google_play_services,extra-google-play_apk_expansion,extra-android-m2repository --no-ui --force --all
expect "Do you accept the license *:"
send -- "y\r"
expect "Do you accept the license *:"
send -- "y\r"
expect "Do you accept the license *:"
send -- "y\r"
expect "Do you accept the license *:"
send -- "y\r"
expect "Do you accept the license *:"
send -- "y\r"
expect "Do you accept the license *:"
send -- "y\r"
expect "Do you accept the license *:"
send -- "y\r"
interact

# WORKAROUND: for some reason we need to download following extras separately (otherwise we will get PkgVersion=2 instead of PkgVersion=2.0.0)
spawn android update sdk --filter extra-google-admob_ads_sdk,extra-google-play_licensing --no-ui --force --all
expect "Do you accept the license *:"
send -- "y\r"
interact


Описание: пытаемся установить нужные нам компоненты SDK. Здесь маленькая хитрость — android update sdk будет предлагать нам согласиться с лицензиями на некоторые компоненты, и т.к. возможности отвечать у нас не будет (скрипт выполняется удалённо), придётся отвечать автоматически с помощью команды spawn (которая была предусмотрительно установлена перед вызовом данного скрипта).
По какой-то, неведомой мне причине, android по разному выкачивает компоненты admob и play_licensing. Если их добавить в первый update, то вместо PkgVersion=2.0.0 будет PkgVersion=2, что нас не очень устраивает (т.к. эта переменная отвечает за версию артефакта в Maven repository).

Установка артефактов в репозиторий Maven

#!/bin/sh

# Scripts installs Android SDK artifacts in local Maven repository

git clone git://github.com/serso/maven-android-sdk-deployer.git
cd ./maven-android-sdk-deployer/
git checkout tags/api-19
mvn install -P4.2
cd ..

Описание: выкачиваем форк Maven Android SK Deployer по тегу api-19 и запускаем его сборку для версии Андроид 4.2 (на 4.4 я ещё не проверял). Почему мы выкачиваем форк вместо оригинала? В оригинале отсутствует тег, и поэтому любые изменения, внесённые в код проекта могут сломать нам сборку.

Запуск эмулятора

#!/bin/sh

# Scripts starts Android emulator with name 'Default'

echo no | android create avd --force -n Default -t android-17 --abi armeabi-v7a
emulator -avd Default -no-skin -no-audio -no-window &

Описание: создаём виртуальное устройство с именем Default и запускаем его в отдельном процессе.

Далее Travis запускает тестовый install проекта, по завершению которого вызывается фаза before_script, в которой мы дожидаемся запуска эмулятора.

Сборка

Финальный аккорд — запуск сборки. В моём случае это просто вызов mvn install с профилем with-tests, который запустит интеграционные тесты.
script: mvn install -Pwith-tests


Заключение


После того как проект успешно настроен, каждый коммит должен приводить к запуску сборки с последующим оповещением на почту. В качестве примера можно посмотреть проект Android Common Library с рабочими сборками в Travis CI.
Если у вас есть вопросы или предложения — добро пожаловать в комментарии. Спасибо за внимание.
Поделиться публикацией

Похожие публикации

AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 2

    0
    Простите, без "#!/bin/bash" в скриптах можно обойтись обычным "#!/bin/sh" или никак?
      0
      Ваша правда, скорее всего можно без проблем заменить. Завтра проверю, если всё будет хорошо — обновлю пост.

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое