När man utvecklar ett projekt för Android-plattformen, även det minsta, måste man рано или поздно столкнуться с окружением для разработки. Förutom Android SDK krävs den senaste versionen av Kotlin, Gradle, platform-tools och build-tools. Och om utvecklarens maskin kan lösa dessa beroenden till stor del via Android Studio IDE, kan varje uppdatering på CI/CD-servern förvandlas till en huvudvärk. Och om Docker har blivit en standardlösning för miljöproblem inom webbutveckling, varför inte testa att lösa ett liknande problem även inom Android-utveckling...
För dem som inte vet vad Docker är — om man ska uttrycka det enkelt, så är det ett verktyg för att skapa så kallade "containrar" där det finns en minimal kärna av operativsystemet och en nödvändig uppsättning programvara som vi kan distribuera var vi vill och samtidigt behålla miljön. Vad som kommer att finnas i vår container bestäms i Dockerfile, som sedan byggs till en bild som kan köras var som helst och har egenskapen av idempotens.
Installationsprocessen och grunderna för Docker är väl beskrivna på deras . Så för att få ett litet försprång, här är en sådan Dockerfile som vi fick fram
# Т.к. основным инструментом для сборки 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"
Vi sparar den i mappen med vårt Android-projekt och kör containerbyggnaden med kommandot
docker build -t android-build:5.4-28-27 .Parameter -t sätter taggen eller namnet på vår container, som vanligtvis består av dess namn och version. I vårt fall kallade vi den android-build och specificerade en kombination av versioner av gradle, android-sdk och platform-tools. Det kommer att bli enklare för oss att hitta den bild vi behöver med hjälp av ett sådant "version".
Efter att bygget har slutförts kan vi använda vår bild lokalt, och vi kan ladda upp den med kommandot docker push till ett offentligt eller privat bildrepository för att ladda ner den till andra maskiner.
Som exempel ska vi bygga projektet lokalt. För detta, i mappen med projektet, kör vi kommandot
docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebugLåt oss bryta ner vad det betyder:
docker run — själva kommandot för att köra bilden
-rm — innebär att efter att containern stoppas tar den bort allt som skapades under sin livscykel
-v "$PWD":/home/gradle/ — monterar den aktuella mappen med vårt Android-projekt till den interna mappen i containern /home/gradle/
-w /home/gradle — anger arbetskatalogen för containern
android-build:5.4.1-28-27 — namnet på vår container som vi byggde
gradle assembleDebug — själva byggkommandot som bygger vårt projekt
Om allt går bra, kommer du efter ett par sekunder/minuter att se något liknande på din skärm BYGG FRAMGÅNGSRIK i 8m 3s! Och i mappen app/build/output/apk kommer den byggda applikationen att ligga.
På samma sätt kan man utföra andra gradle-uppgifter — kontrollera projektet, köra tester etc. Huvudfördelen är att när det krävs en byggning av projektet på en annan maskin, behöver vi inte oroa oss för att installera hela miljön, det räcker med att ladda ner den nödvändiga bilden och starta bygget i den.
Containern lagrar inga ändringar, och varje byggnation körs från grunden, vilket å ena sidan garanterar identiteten hos bygget oavsett var det körs, men å andra sidan måste vi varje gång ladda ner alla beroenden och kompilera hela koden på nytt, vilket ibland kan ta en betydande tid. Därför, förutom det vanliga "kalla" uppstarten, har vi alternativet att starta bygget och spara så kallad "cache", där vi sparar mappen ~/ .gradle bara genom att kopiera den till projektets arbetsmapp, och i början av nästa byggnation återför vi den tillbaka. Alla kopieringsprocedurer har vi flyttat till separata skript och själva startkommandot har nu blivit så här
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"Som ett resultat har den genomsnittliga byggtiden för projektet minskat flera gånger (beroende på antalet beroenden i projektet, men det genomsnittliga projektet kan nu byggas på 1 minut istället för 5 minuter).
Allt detta är förstås meningsfullt endast om du har en egen intern CI/CD-server, vars support du själv ansvarar för. Men nu finns det många molntjänster där alla dessa problem är lösta och du behöver inte oroa dig för detta, och de nödvändiga bygginställningarna kan också anges i projektinställningarna.
Endast registrerade användare kan delta i omröstningen. , tack.
Håller du CI/CD-systemet internt eller använder en extern tjänst
Vi använder en intern server
Vi använder en extern tjänst
Vi använder ingen CI/CD
Annat
42 användare röstade. 16 användare avstod.
Källa: habr.com
