Android platformra projektet fejlesztve, még a legkisebbek is előbb-utóbb szembesülnek a fejlesztési környezettel. Az Android SDK mellett szükséges, hogy a legfrissebb Kotlin, Gradle, platform-tools és build-tools verziók is legyenek. Míg a fejlesztő gépén ezeket többnyire az Android Studio IDE segítségével kezeljük, a CI/CD szerveren minden frissítés potenciálisan fejfájást okozhat. A webfejlesztésben a Docker a környezeti problémák standard megoldása, miért ne próbálnánk meg hasonlóan megoldani ezt Android fejlesztésnél is...
Aki nem ismeri a Dockert — ha nagyon egyszerűen fogalmazunk, ez a "konténerek" létrehozására szolgáló eszköz, amelyek egy minimális operációs rendszer magot és a szükséges szoftvercsomagokat tartalmaznak, amiket bárhol ki tudunk telepíteni, miközben megtartjuk a környezetet. Hogy pontosan mi lesz a konténerünkben, azt a Dockerfile határozza meg, amely később egy olyan képpé áll össze, amit bárhol futtathatunk és rendelkezik idempotencia tulajdonságokkal.
A Docker telepítésének folyamata és alapjai kiválóan vannak leírva a . Tehát, egy kicsit előreugorva, ez a Dockerfile jött létre nálunk
# Т.к. основным инструментом для сборки 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"
Mentjük a Android-projektünkkel egy könyvtárba, és a konténer buildelését ezzel a parancssal indítjuk
docker build -t android-build:5.4-28-27 .A parameter - folyamatosan „pingelni” (a leállításhoz nyomjuk meg a Ctrl+C kombinációt) megadja a konténerünk címkéjét vagy nevét, amely általában a neve és a verziója összetevőiből áll. Az esetünkben android-build névre kereszteltük, a verzióba pedig a gradle, android-sdk és platform-tools verziókat állítottuk be. A jövőben könnyebb lesz megtalálni a szükséges képet a nevének felhasználásával a "verzió" segítségével.
Miután a build sikeresen lezajlott, helyben használhatjuk a képet, vagy feltölthetjük a következő paranccsal docker push nyilvános vagy privát képtárba, hogy más gépeken is letölthessük azt.
Példaként lokálisan építjük fel a projektet. Ehhez a projekt könyvtárában futtassuk a parancsot
docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebugNézzük meg, mit jelent ez:
docker run — maga a parancs az image elindítására
-rm — azt jelenti, hogy a konténer leállítása után eltávolít minden létrehozott dolgot a működése során
-v "$PWD":/home/gradle/ — a jelenlegi mappát, amely az Android-projektünket tartalmazza, a konténer belső mappájába /home/gradle/ csatolja
-w /home/gradle — beállítja a konténer munkakönyvtárát
android-build:5.4.1-28-27 — a konténerünk neve, amelyet összeraktunk
gradle assembleDebug — a tényleges build parancs, amely összeállítja a projektünket
Ha minden jól megy, akkor néhány másodpercen vagy percen belül a képernyőn ilyesmit fog látni: BUILD SUCCESSFUL in 8m 3s! Az app/build/output/apk mappában található majd a létrehozott alkalmazás.
Hasonló módon más gradle feladatokat is végrehajthatunk — ellenőrizheti a projektet, futtathat teszteket stb. A fő előny, hogy ha szükség van a projekt más gépen való buildelésére, nem kell aggódni a teljes környezet telepítése miatt, elég letölteni a szükséges képet és elindítani benne a buildet.
A konténer nem tárol semmilyen módosítást, és minden build nulláról indul, ami egyrészt garantálja a build azonosságát, függetlenül a futtatási helytől, másrészt viszont minden alkalommal le kell tölteni az összes függőséget és újra kell fordítani az összes kódot, ami néha jelentős időt vehet igénybe. Ezért a szokásos 'hideg' indítás mellett van egy lehetőség is, hogy a buildet úgy indítsuk, hogy megőrizzük az úgynevezett 'cache'-t, ahol a ~ /.gradle mappát egyszerűen átmásoljuk a projekt munkakönyvtárába, majd a következő build elején visszatesszük. Minden másolási eljárást külön szkriptekbe szerveztünk, így a buildindító parancsunk a következőképpen néz ki:
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"Ennek eredményeként a projekt buildelési ideje többszörösére csökkent (a projekt függőségeinek számától függően, de ezzel a módszerrel az átlagos projekt 1 perc alatt felépül az 5 perc helyett).
Mindez természetesen csak akkor van értelme, ha van saját belső CI/CD szervere, amelynek támogatásával maga foglalkozik. De manapság sok felhőszolgáltatás létezik, amelyek ezt a problémát megoldják, és nem kell aggódnia emiatt; a szükséges buildbeállításokat szintén megadhatja a projekt beállításaiban.
Csak a regisztrált felhasználók vehetnek részt a szavazáson. , kérem.
Belső CI/CD rendszert működtet, vagy külső szolgáltatást használ?
Használunk belső szervert
Külső szolgáltatást használunk
Nem használunk CI/CD-t
Egyéb
42 felhasználó szavazott. 16 felhasználó tartózkodott.
Forrás: habr.com
