Настройка CI/CD для Android поднимает больше вопросов, чем кажется. Частая ситуация: разработчик пушит код, CI падает с ошибкой "Keystore not found" или сборка длится 15 минут, а релиз задерживается на день. Недавно команда из 5 разработчиков обратилась к нам: их сборка длилась 30 минут, релиз выходил раз в две недели. После внедрения CI/CD с Gradle кэшированием и параллельной сборкой время сократилось до 10 минут, частота релизов выросла до еженедельных. Сокращение времени сборки напрямую снижает затраты на CI-раннеры и ускоряет выход обновлений, что экономит бюджет команды.
Основные грабли: keystore в репозитории, ручное версионирование, отсутствие кэша на CI, неправильная конфигурация build variants. Каждая из этих ошибок способна заблокировать релиз или привести к утечке секретов. Наша услуга по настройке CI/CD включает полный аудит текущей сборки, конфигурацию Gradle с учётом лучших практик, интеграцию с CI-системой и деплой в Google Play. Инвестиции в настройку CI/CD окупаются за счёт ускорения релизного цикла и снижения ручного труда. Гарантируем стабильную работу после внедрения.
Как правильно подписать APK в CI?
Keystore в Git — критическая ошибка, даже в приватном репозитории. Правильная схема: keystore Base64-encoded → CI secret → декодируем на лету.
# GitHub Actions
- name: Decode Keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > app/release.keystore
- name: Build Release AAB
run: ./gradlew bundleRelease
env:
SIGNING_STORE_FILE: release.keystore
SIGNING_STORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
SIGNING_KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
SIGNING_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}В app/build.gradle.kts:
signingConfigs {
create("release") {
storeFile = file(System.getenv("SIGNING_STORE_FILE") ?: "debug.keystore")
storePassword = System.getenv("SIGNING_STORE_PASSWORD") ?: ""
keyAlias = System.getenv("SIGNING_KEY_ALIAS") ?: ""
keyPassword = System.getenv("SIGNING_KEY_PASSWORD") ?: ""
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}Keystore не попадает в артефакты — после сборки удаляем: rm -f app/release.keystore. Процесс состоит из нескольких шагов:
- Загрузите keystore в CI secrets в виде Base64-строки.
- Создайте job для декодирования и сборки.
- Настройте signingConfig в build.gradle.kts с использованием переменных окружения.
- После сборки удалите keystore из файловой системы.
Почему автоматическое версионирование — стандарт?
versionCode в Android должен быть уникальным для каждой сборки. Ошибка — использовать ручное обновление. На CI — автоматически:
// build.gradle.kts
val ciPipelineNumber = System.getenv("CI_BUILD_NUMBER")?.toIntOrNull() ?: 1
val gitCommitCount = "git rev-list --count HEAD".runCommand().trim().toIntOrNull() ?: 1
android {
defaultConfig {
versionCode = ciPipelineNumber.takeIf { it > 1 } ?: gitCommitCount
versionName = "2.4.${gitCommitCount}"
}
}Сравнение методов:
| Метод | Описание | Монотонность | Зависимость от CI |
|---|---|---|---|
| CI_BUILD_NUMBER | Номер сборки от провайдера | Да, если не сбрасывается | Да (при смене CI — проблемы) |
| git commit count | Количество коммитов | Всегда монотонно | Нет (универсально) |
Рекомендуем git commit count — не привязан к CI-системе.
Как ускорить Gradle сборку?
Медленный Gradle — главная жалоба Android CI. Несколько конкретных настроек в gradle.properties:
-
org.gradle.parallel=true— параллельная сборка модулей. -
org.gradle.configureondemand=true— конфигурирование только нужных модулей. -
org.gradle.caching=true— локальный кэш задач. При неизменном коде модуля Gradle берёт результат из кэша без перекомпиляции. На CI это работает черезactions/cache(GitHub) с ключом по хэшу*.gradle*файлов. -
org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC— увеличенный heap. -
android.defaults.buildfeatures.buildconfig=false— генерация BuildConfig только для активной сборки.
Подробнее о настройке кэша — в Gradle Build Cache. Сравнение времени сборки с разными конфигурациями на ubuntu-latest раннере:
| Конфигурация | Время сборки (минуты) |
|---|---|
| Без оптимизаций | 10–15 |
| Параллельность + configureondemand | 6–8 |
| Полное кэширование + JVM heap 4GB | 2–4 |
Правильное кэширование сокращает время в 3-4 раза. Используйте R8 вместо ProGuard — он быстрее.
Какие build variants настраивать?
Разные variant-ы для разных окружений — стандарт:
flavorDimensions += "env"
productFlavors {
create("dev") {
applicationIdSuffix = ".dev"
buildConfigField("String", "API_URL", "\"https://api.dev.example.com\"")
}
create("prod") {
buildConfigField("String", "API_URL", "\"https://api.example.com\"")
}
}На CI — separate jobs для каждого variant-а:
- PR →
assembleDevDebug+ тесты - merge to develop →
assembleDevRelease+ Firebase App Distribution - release tag →
bundleProdRelease+ Google Play
Загрузка в Google Play через Gradle
gradle-play-publisher plugin:
// build.gradle.kts
plugins {
id("com.github.triplet.play") version "3.9.1"
}
play {
serviceAccountCredentials.set(file(System.getenv("PLAY_STORE_JSON") ?: "play-store-credentials.json"))
track.set("internal")
defaultToAppBundles.set(true)
}Credentials JSON — service account из Google Play Console с доступом Release manager. На CI передаём через environment variable, аналогично keystore.
Что входит в настройку CI/CD?
| Этап | Описание | Сроки |
|---|---|---|
| Анализ | Аудит текущей сборки, инфраструктуры и CI-конфигурации | 1 день |
| Конфигурация Gradle | Настройка подписания, версионирования, флейворов, кэширования | 1–2 дня |
| Интеграция CI | Настройка workflow (GitHub Actions/GitLab CI/Bitrise), секретов, деплоя | 1–2 дня |
| Оптимизация | Ускорение сборки, внедрение тестов, параллельных задач | 1–2 дня |
| Документация | Описание процесса, руководство для команды | 1 день |
Сроки
Базовая настройка CI/CD (подписание, версионирование, один CI) занимает 2–4 дня. Полная конфигурация с build variants, деплоем в Google Play, оптимизацией сборки — 1–2 недели. Стоимость рассчитывается индивидуально.
Если ваша сборка занимает слишком много времени или релизы постоянно срываются, пора внедрить профессиональный CI/CD. Свяжитесь с нами — мы проведём аудит и настроим процесс, чтобы вы забыли о релизных проблемах. Гарантируем стабильный результат.







