Зборка Android-праекта ў Docker-кантэйнеры

Распрацоўваючы праект пад платформу Android, нават самы невялікі, рана ці позна даводзіцца сутыкацца з асяроддзем для распрацоўкі. Акрамя Android SDK, неабходна, каб была апошняя версія Kotlin, Gradle, platform-tools, build-tools. І калі на машыне распрацоўніка ўсе гэтыя залежнасці вырашаюцца ў большай меры з дапамогай Android Studio IDE, то на серверы CI/CD кожнае абнаўленне можа ператварыцца ў галаўны боль. І калі ў web-распрацоўцы, рашэннем праблемы асяроддзя стандартам стаў Docker, то чаму-то не паспрабаваць вырашыць з дапамогай яго аналагічную праблему і ў Android-распрацоўцы…

Для тых, хто не ведае што такое Docker – калі зусім проста, то гэта прылада стварэння т.зв. "кантэйнераў" дзе ўтрымоўваецца мінімальнае ядро ​​АС і неабходны набор ПА, якія мы можам разгортваць дзе захочам, захоўваючы пры гэтым асяроддзе. Што менавіта будзе ў нашым кантэйнеры вызначаецца ў Dockerfile, які потым збіраецца ў выяву які запускаецца дзе заўгодна і які валодае ўласцівасці ідэмпатэнтнасці.

Працэс усталёўкі і асновы Docker выдатна апісаны на яго афіцыйным сайце. Таму, забягаючы крыху наперад, вось такі Dockerfile у нас атрымаўся

# Т.к. основным инструментом для сборки Android-проектов является Gradle, 
# и по счастливому стечению обстоятельств есть официальный Docker-образ 
# мы решили за основу взять именно его с нужной нам версией Gradle
FROM gradle:5.4.1-jdk8

# Задаем переменные с локальной папкой для Android SDK и 
# версиями платформы и инструментария
ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" 
    ANDROID_HOME="/usr/local/android-sdk" 
    ANDROID_VERSION=28 
    ANDROID_BUILD_TOOLS_VERSION=28.0.3

# Создаем папку, скачиваем туда SDK и распаковываем архив,
# который после сборки удаляем
RUN mkdir "$ANDROID_HOME" .android 
    && cd "$ANDROID_HOME" 
    && curl -o sdk.zip $SDK_URL 
    && unzip sdk.zip 
    && rm sdk.zip 
# В следующих строчках мы создаем папку и текстовые файлы 
# с лицензиями. На оф. сайте Android написано что мы 
# можем копировать эти файлы с машин где вручную эти 
# лицензии подтвердили и что автоматически 
# их сгенерировать нельзя
    && mkdir "$ANDROID_HOME/licenses" || true 
    && echo "24333f8a63b6825ea9c5514f83c2829b004d1" > "$ANDROID_HOME/licenses/android-sdk-license" 
    && echo "84831b9409646a918e30573bab4c9c91346d8" > "$ANDROID_HOME/licenses/android-sdk-preview-license"    

# Запускаем обновление SDK и установку build-tools, platform-tools
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" 
    "platforms;android-${ANDROID_VERSION}" 
    "platform-tools"

Захоўваем яго ў тэчку з нашым Android-праектам і запускаем зборку кантэйнера камандай

docker build -t android-build:5.4-28-27 .

Параметр -t задае tag ці імя нашага кантэйнера, якое звычайна складаецца з яго назву і версіі. У нашым выпадку мы назвалі яго android-build, а ў версіі паказалі сукупнасць версій gradle, android-sdk і platform-tools. У далейшым нам прасцей будзе шукаць патрэбны нам вобраз па імені выкарыстоўваючы такую ​​"версію".

Пасля таго як зборка прайшла мы можам выкарыстоўваць нашу выяву лакальна, можам загрузіць яго камандай docker push у публічны або прыватны рэпазітар вобразаў каб спампоўваць яго на іншыя машыны.

У якасці прыкладу збяром лакальна праект. Для гэтага ў тэчцы з праектам выканаем каманду

docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebug

Разбяром што яна азначае:

докер прабег - сама каманда запуску выявы
-rm - азначае што пасля прыпынку кантэйнера ён выдаляе за сабой усё што стваралася ў працэсе яго жыцця
-v $PWD:/home/gradle/ - мантуе бягучую тэчку з нашым Android-праектам ва ўнутраную тэчку кантэйнера /home/gradle/
-w /home/gradle - задае працоўную дырэкторыю кантэйнера
android-build:5.4.1-28-27 - імя нашага кантэйнера, які мы сабралі
gradle assembleDebug - уласна каманда зборкі, якая збірае наш праект

Калі ўсё скласціся ўдала, то праз пару секунд/хвілін вы ўбачыце ў сябе на экране нешта накшталт BUILD SUCCESSFUL in 8m 3s! А ў тэчцы app/build/output/apk будзе ляжаць сабранае прыкладанне.

Аналагічнай выявай можна выконваць іншыя задачы gradle - правяраць праект, запускаць тэсты і г.д. Асноўная перавага — пры неабходнасці зборкі праекта на любой іншай машыне, нам не трэба турбавацца аб усталёўцы ўсяго асяроддзя і досыць будзе спампаваць неабходную выяву і запусціць у ім зборку.

Кантэйнер не захоўвае ніякіх змен, і кожная зборка запускаецца з нуля, што з аднаго боку гарантуе ідэнтычнасць зборкі незалежна ад месца яе запуску, з іншага боку кожны раз даводзіцца спампоўваць усе залежнасці і кампіляваць увесь код нанова, а гэта часам можа займаць істотны час. Таму акрамя звычайнага халоднага запуску ў нас ёсць варыянт запуску зборкі з захаваннем т.зв. "кэша", дзе мы захоўваем тэчку ~/.gradle проста капіюючы яе ў працоўную тэчку праекту, а ў пачатку наступнай зборкі вяртаем яе зваротна. Усе працэдуры капіравання мы вынеслі ў асобныя скрыпты і сама каманда запуску ў нас стала выглядаць так

docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 /bin/bash -c "./pre.sh; gradle assembleDebug; ./post.sh"

У выніку, сярэдні час зборкі праекту ў нас скараціўся ў некалькі разоў (у залежнасці ад колькасці залежнасцяў на праекце, але сярэдні праект такім чынам стаў збірацца за 1 хвіліну замест 5 хвілін).

Усё гэта само сабой мае сэнс толькі калі ў вас есць уласны ўнутраны CI/CD сервер, падтрымкай якога вы самі і займаецеся. Але цяпер ёсць шмат хмарных сэрвісаў у якіх усе гэтыя праблемы вырашаны і вам не трэба пра гэта перажываць і патрэбныя ўласцівасці зборкі можна гэтак жа ўказаць у наладах праекта.

Толькі зарэгістраваныя карыстачы могуць удзельнічаць у апытанні. Увайдзіце, Калі ласка.

Ці трымаеце вы сістэму CI/CD усярэдзіне ці карыстаецеся іншым сэрвісам

  • Выкарыстоўваны ўнутраны сервер

  • Выкарыстоўваны знешні сэрвіс

  • Не выкарыстоўваем CI/CD

  • Іншая

Прагаласавалі 42 карыстальніка. Устрымаліся 16 карыстальнікаў.

Крыніца: habr.com

Дадаць каментар