Здравстуй дорогой читатель. Если тебе незнакомы понятия Continuous integration (CI), Continuous delivery (CD) или же у тебя нет представления как и зачем их нужно использовать, то прошу под кат, где тебя ждет небольшое описание как настроить данные сервисы в своем Android проекте, а также какие бонусы будут получены в итоге.
Введение
Дорогой читатель, если ты думаешь, что в данной статье будет много кода — то ты ошибаешься. Кода как раз у нас будет самый минимум, но он позволит показать некоторые возможности CI. Основная часть статьи — как настроить связки сервисов. Надеюсь для разработчиков Junior/Middle данная статья будет весьма интересной и полезной.
Предыстория
Все началось со стартапа. У нас было достаточно хорошее финансирование и планы на ближайшие два года. Над android проектом работало два человека. Методология была у нас похожа на agile с использованием gitflow. Спустя два месяца разработки код был частично покрыт тестами, и вроде процесс для нашего небольшого проекта был отлаженный, но что то не давало покоя.
У меня есть предположение, что если вы не работаете в крупной компании, а трудитесь в стартапе (которых бесчисленное множество), то вы даже не задумываетесь о выгоде использования CI CD сервисов. Однако именно они помогут вам сэкономить время.
Я — разработчик, поэтому буду описывать происходящее от данной позиции.
Думаю ситуация, в которой к вам подходит кот (под данным словом я понимаю абсолютно любую позицию не-разработчиков в вашей команде, которые просят продукт для QA) и просит установить последнюю сборку на его телефон. По началу это не воспринимается как серьезная трудная задача. Однако, это создает следующие проблемы:
- Пожалуй самое главное — вы отрываетесь от текущей задачи
- Вы ищете последний скомпилированный apk
- Ваш последний скомпилированный apk является вашей dev сборкой, и показывать ее ну никак нельзя
- Вы подключаете мобильный телефон кота через кабель и устанавливаете сборку
- А что если в нашей текущей ветке есть не закомиченные изменения? (commit -a stash в помощь, но все равно это время)
- Вы тратите время на возврат к задаче которую вы выполняли
Это лишь вершина айсберга. А что если у вас много разных котов? Вы начинаете тратить все больше и больше времени для выполнения задач второстепенного характера.
Давайте же попробуем разобраться на небольшом примере, как сэкономить свое и чужое время.
Забегая немного вперед скажу, что сейчас, если разработка проекта у меня занимает больше одного месяца я все равно настраиваю Ci+Cd, что в дальнейшем приводит к вовлеченности заказчика и вы сразу же получаете фидбэк на разработку.
Цели
Мне было интересно построить данную статью на примере очереди из действий, которую нам необходимо проделать для получения результата. Причем каждую цель — выделить в отдельный коммит. Думаю так будет интереснее и проще понять, что происходит.
Пока мне видится три основные этапа ToDo:
- Создать проект
- Настроить CI
- Настроить CD
Преждевременная оптимизация — корень всех зол. (Premature optimization is the root of all evil. D. Knuth)
Создать проект
Думаю этот этап будет самым простым. Создаем новый репозиторий на VCS (Github/Bitbucket). Я лично выбираю GitHub — просто дело привычки. Все дальнейшие изменения вы можете отслеживать по коммитам.
Далее, делаем первый коммит
Даже если сейчас мы начнем делать разработку новой фитчи, и к нам подойдет кот и попросит последнюю сборку, то мы будет вынуждены откатиться до master head. В целом мы подошли к проблеме.
Настроить Ci
Чтобы что-то кому то отправить, надо это что-то где-то собрать. И желательно с минимальной отвлеченностью нас от основной задачи разработки.
В качестве Ci сервиса я предпочитаю CircleCI. Существуют также и альтернативы и никто не запрещает вам использовать более одного Ci сервиса в вашем проекте.
Наша цель — двигаться небольшими шагами, поэтому поставим себе цель просто запустить сборку репозитория на Ci
Начнем пошагово:
1. Авторизуемся на CiCircle через GitHub
2. В боковой плашке находим Project и переходим к нашему новому проекту (если вы нажмете на Build project то сборка завершится неудачей из за не настроенного проекта)
3. Заходим в настройки репозитория на GitHub в категорию Integrations & services и нажимаем Add Service
4. Забегая вперед, в настройках проекта на CiCircle рекомендую включить мониторинг Pull request(PR), это позволит вашим коллегам не мерджить в мастер нерабочий код. (Возможно это еще одна моя заморочка, но я считаю, что master ветка должна всегда собираться)
5. Пожалуй самая важная часть по настройке Ci — настройка в вашем проекте
Нам необходимо внести изменения в build.gradle, добавить cicircle.gradle (по сути шаблон) и некоторый circleci.yml (который несет в себе основную настройку по CI). Я сторонник проводить любые изменения master ветки только через PR, поэтому создаем branch с преднастройками Ci и делаем PR.
Если все было сделано правильно, то под PR мы увидим что-то похожее
А если зайдем в Ci то увидим как собирается наш проект
Спустя какое то время (обычно сборка занимает не более 5 минут мы увидим скорее всего положительный результат)
А значит можно продолжать, и смело нажимаем Merge! (И на Ci запустится сборка master ветки)
Какие плюсы для себя мы получаем?
- Сборка происходит независимо от нас в облаке
- Теперь каждый раз когда мы делаем PR то мы точно знаем, соберется ли у нас сборка. Это исключает возможность подкинуть себе проблем с нерабочими сборками из мастера
- Есть возможность прогонять тесты
Отлично, работаем дальше!
Раз сборка происходит в облаке, логично предположить, что остаются какие то артифакты в виде apk.
Мне кажется, что хорошая цель на данную итерацию — получать apk, который можно было бы выложить в маркет. Таким образом мы получаем при каждой сборке master ветки (не PR) уже готовый продукт.
1. Чтобы сбирать release.apk — нам необходимо сгенерировать ключ подписи. Это делается единожды через Android Studio.
2. Далее вносятся изменения в build.gradle
signingConfigs {
release {
def signFile = project.rootProject.file('./release.keystore')
if (signFile.exists()) {
storeFile signFile
storePassword "qweqwe"
keyAlias "habrcicdcat"
keyPassword "qweqwe"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
Файл release.keystore лежит в папке с проектом.
3. Создаем bash скрипт кторый будет отвечать за перенос собранного файла в директорию артефактов
#/bin/bash
GRADLE="./gradlew"
$GRADLE assembleRelease
RELEASEFILE="${CIRCLE_ARTIFACTS}/habrcicdcat-release-${CIRCLE_BUILD_NUM}-${CIRCLE_SHA1}.apk"
cp ./app/build/outputs/apk/app-release.apk ${RELEASEFILE}
Данные константы доступны по умолчанию
CIRCLE_BUILD_NUM — номер сборки
CIRCLE_SHA1 — ключ коммита
CIRCLE_ARTIFACTS — мы устанавливаем ее в cicircle.yml
general:
artifacts:
- /home/ubuntu/HabrCiCdCat/app/build/outputs/apk/
4. Добавляем в cicircle.yml часть, отвечающую за деплоймет
deployment:
beta:
branch: master
commands:
- cd scripts && ./build.sh
Всего лишь запускаем наш скрипт, при изменении мастер ветки
5. Делаем PR в мастер ветку, дожидаемся что все собирается успешно, выполняем слияние. Если перейти в консоль Ci то мы можем увидеть, как началась собираться master ветка.
Спустя какое то время, вы увидите, что сборка прошла успешно. Через консоль в Ci можно увидеть собранные APK
Фактически на этом можно закрывать создание apk. Мы можем скачать и сразу загрузить apk в маркет или отправить на почту нашим котам. Но чего то все таки не хватает. Главная цель статьи не была реализована, и нас все равно будут отрывать от выполнения текущей задачи. На помощь приходит CD.
Настройка Fabric Beta
В качестве CD сервиса я буду рассматривать Beta от Fabric. Опять же замечу, что существует множество альтернатив, но суть статьи не в холиварах а в описании процесса.
Итак. Когда корм для наших котов готов, осталось его до них донести. В этом нам помогают сервисы бета тестирования.
Начнем настройку:
1. Для начала наш проект должен зарегистрироваться в Fabric, существует несколько способов, включая добавление Fabric Plugin в Android Studio. Нужно внести изменения в build.gradle файлы. После выполнения этих операций в вашей консоли в crashlitics отобразится новое приложение.
2. В настройках аккаунта Fabric вам необходимо создать новую организацию, и получить от нее apiSecret и apiKey
3. Начнем настройку Beta сервиса от Fabric
Для начала нам нужно создать группу тестировщиков и добавить в нее хотя бы себя и
Тут главное запомнить Alias: habrcicdcat
и сделать связку организации и группы тестировщиков
Всем тестировщикам из группы придет уведомление на email, которое необходимо открыть с телефона, и перейти по ссылке внутри письма для скачивания или верификации приложения Beta.
Далее начнем настройку связки сервиса и приложения
Добавляем Alias в buildTypes
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
ext.betaDistributionGroupAliases = "habrcicdcat"
}
}
В папку app добавляем fabric.properties следующего содержания (константы из п.2)
apiSecret=23167a9cd00cb83f9dab952b47e7350e19dd7693071ceb2abe2d56dbfc6e1318
apiKey=3915c7e9ffe661c44a4db3935d34a5a8da525b9c
Далее, можно создавать PR и смотреть за сборкой master. Если все прошло успешно то вам придет нотификация в приложение Beta, и вы сможете его скачать и установить.
Конечная цель достигнута
Цели, поставленные в начале статьи выполнены. Теперь при любом изменении master ветки будет происходить сборка приложения, я отправка apk группе котов. И мы всегда имеем под рукой сборку, для публикации.
Теперь, когда вас будут отрывать от рабочего процесса, вы всегда можете ответить: «Последняя сборка всегда доступна в Beta» — а как побочный результат, вы можете спокойно продолжать работать над текущей задачей.
Что осталось за кадром:
- Сборка flavors (чтобы показать пример, как кормить нескольких котов)
- Возможные проблемы при создании сборок
В данной статье я хотел показать, что настройка CI и CD не такая страшная, однако крайне полезная вещь. Я не считаю проблемой, затратить час времени для настройки этой системы на фриланс проектах потому, что выгода от нее спустя 2 недели превысит этот час. Надеюсь, эта статья принесет в ваш проект CI и CD, ну или хотя бы вам было интересно.
Ссылка на GitHub проект где пошагово описана каждая итерация из данной статьи.
Автор: Jukobob