Всем привет! Меня зовут Ларионов Михаил и я, как можно догадаться, Android-разработчик.
Думаю ни для кого не секрет, что создание мобильных приложений с каждым годом становится все более значимой и востребованной сферой, так как их популярность стремительно растет, и соответственно спрос на них увеличивается. На сегодняшний день одной из ведущих операционных систем является Android, которая, судя по статистике, занимает около 72% рынка мобильных устройств.
Естественно, такой растущий интерес к мобильным приложениям порождает все новые вызовы. Крупные компании формируют огромные команды разработчиков для реализации своих проектов, однако объемы и сложность их кодовой базы часто увеличиваются до критических размеров.
Но, чем больше приложение, тем больше ответственность...
А также, тем сложнее и труднее процесс как его разработки, так и поддержки. Именно поэтому разработчики ищут любые способы, чтобы упростить и как-то его ускорить. В результате они нередко прибегают к использованию различных инструментов, одним из которых является Docker.
Почему Docker?
Для начала вспомним, что речь идет о технологии, которая позволяет упаковать приложение в контейнер, а затем доставить и запустить его в целевой системе.
Контейнер — это изолированные среда, в которой можно запустить приложение вместе со всеми его зависимостями.
Если говорить о Docker в контексте Android-разработки, то чаще всего кейсы его использования встречаются в тестировании и развертывании приложений.
Docker позволяет создать изолированную среду, в которой можно запустить приложение вместе со всеми его зависимостями, что очень ценится в тестировании. Ключевым фактором является то, что внесенные изменения, никак не влияют на другие контейнеры или систему. Конвейеризация же только ускоряет эти и другие процессы.
Звучит непросто? Но на самом же деле, в этом нет ничего сложного.
Чтобы в этом убедиться, напишем небольшой Pipeline для Android проекта.
Практический пример
Данный пример будет продемонстрирован на одном моем стареньком проекте на ГитХабе, в котором я разрабатывал погодное приложение.
Первым делом нам необходимо создать файл с любым названием в формате .yml
в папке .github/workflows
в корне вашего проекта. В этом файле укажем название нашего pipeline.
name: WeatherIt Pipeline
После чего опишем, при каких условиях будет запускаться наш флоу.
on:
# Запуск флоу после пуша в указанные ветки
push:
branches: [ "main","dev" ]
# Запуск флоу после создания пулл реквеста в указанные ветки
pull_request:
branches: [ "main","dev" ]
Как можно заметить, в моем примере он запускается при создании пулл реквеста и пуше в ветки main и dev.
Добавим задачу на сборку приложения.
Создадим job под названием BUILD (например) и укажем образ контейнера, который мы хотим использовать за основу:
jobs:
BUILD:
# Использование образа крайней версии Ubuntu
runs-on: ubuntu-latest
В данном случае, пока что мы запускаем пустой контейнер с убунту, поэтому подтянем наш проект и установим Java JDK при помощи GitHub Actions, указав их в качестве этапов:
# Этапы флоу
steps:
# Загрузка проекта из ветки
- name: Checkout
uses: actions/checkout@v4.1.7
# Установка 17 версии Java JDK
- name: Setup Java JDK
uses: actions/setup-java@v4.2.1
with:
java-version: 17
distribution: "temurin"
Наконец нам осталось добавить лишь запуск GradleTask, но перед этим выдадим необходимые права для работы ./gradlew
.
# Выдача прав для запуска команды
- name: Get Permissions
run: chmod +x ./gradlew
# Запуск сборки проекта
- name: Build
run: ./gradlew app:assembleRelease
Теперь при каждом пулл реквесте в main или dev мы, если увидим такой результат, можем быть уверены, что вливаем работающий код.
Помимо этого, всегда можно изучить логи каждого шага более детально, особенно, если на каком-то из них произошла ошибка.
Артефакты
Попробуем написать еще одну задачу, которая уже будет возвращать нам какой-нибудь артефакт.
Артефакт — это файлы или директории, которые генерируются в результате выполнения задач.
Добавим линт-проверку для нашего проекта. И на самом деле, в начале код не будет сильно отличаться от предыдущего:
LINT:
# Использование образа крайней версии Ubuntu
runs-on: ubuntu-latest
steps:
# Загрузка проекта из ветки
- name: Checkout
uses: actions/checkout@v4.1.7
# Установка 17 версии Java JDK
- name: Setup Java JDK
uses: actions/setup-java@v4.2.1
with:
java-version: 17
distribution: "temurin"
# Выдача прав для запуска команды
- name: Get Permissions
run: chmod +x ./gradlew
# Запуск линтера проекта
- name: Lint
run: ./gradlew lintDebug
Чтобы выгрузить отчет, воспользуемся еще одним GitHub Action, для которого укажем путь к файлу со сгенерированными результатами:
# Выгрузка отчета в виде артефакта
- name: Upload Lint Report
uses: actions/upload-artifact@v4.3.3
with:
name: LintReport.html
path: app/build/reports/lint-results-release.html
Аналогичным образом можно добавить множество различных проверок, которые позволят Вам автоматизировать как процесс проверки приложения, так и его развертывания.
Зависимости
Если же Вы хотите, чтобы какая-то из задач запускалась только при успешном выполнении другой, то для этого необходимо указать для нее needs
и название необходимой задачи, например:
UNIT-TESTS:
# Зависит от успешного выполнения задачи
needs: [ LINT ]
runs-on: ubuntu-latest
В целом, такие проверки уже стали неотъемлемой частью разработки программного обеспечения. Они помогают выявлять и исправлять ошибки еще на ранних этапах, тем самым, обеспечивая стабильность и надежность продукта.
Android плагины
Пара слов о полезных плагинах в Android.
Gradle Docker Plugin — плагин, который позволяет разработчикам включать задачи, связанные с Docker, в сборки Gradle, обеспечивая контейнеризацию приложений и управление ресурсами.
Jib — плагин от Google для систем сборки Maven и Gradle, который не требует долгой конфигурации. Позволяет создавать образы Docker прямо из проекта, без необходимости использовать Dockerfile.
Оба плагина предоставляют возможность создавать образы Docker прямо из проекта, однако между ними есть некоторые различия, которые стоит учитывать. Например, Gradle Docker Plugin может показаться более сложным в освоении, чем Jib, но при этом, он предоставляет больше возможностей для настройки.
Да и в целом, они оба прекрасно выполняют свои функции в виде контейнеризации приложений и управлении ресурсами. Каждый из них нацелен на упрощение процесса разработки и тестирования, обеспечивая стабильность и надёжность работы приложений.
Заключение
Если подводить итоги, то можно сказать, что интеграция Docker в процесс Android-разработки позволяет значительно упростить и оптимизировать процесс создания мобильных приложений. А возможность изолировать приложение вместе со всеми его зависимостями в контейнере позволяет избежать множества проблем. Особенно это полезно в задачах на тестирование, сборки и развертывания приложений.
Создание автоматизированных конвейеров позволяет минимизировать количество ручной работы, исключить человеческий фактор и ускорить проверку кода.
Понимаю, что данная тема может показаться сложной на первый взгляд, но на практике это понятный и логичный процесс, который, я считаю, стоит затраченных усилий. Ведь, чем больше мы автоматизируем рутину, тем больше времени остается на главное — создание самих продуктов.