Sviluppando un progetto per la piattaforma Android, anche il più semplice, prima o poi ci si deve confrontare con l'ambiente di sviluppo. Oltre all'Android SDK, è necessario avere l'ultima versione di Kotlin, Gradle, platform-tools e build-tools. Se sul computer del sviluppatore queste dipendenze sono in gran parte gestite attraverso Android Studio IDE, su un server CI/CD ogni aggiornamento può diventare un vero incubo. E se nel web development la soluzione standard per il problema dell'ambiente è diventato Docker, perché non provare a risolvere un problema simile anche nello sviluppo Android…
Per chi non sa cos'è Docker — in parole semplici, è uno strumento per creare i cosiddetti 'container' che contengono un nucleo minimo del sistema operativo e un set di software necessario, che possiamo implementare ovunque, mantenendo così l'ambiente. Cosa conterrà il nostro container è definito nel Dockerfile, che poi viene assemblato in un'immagine che può essere eseguita ovunque e possiede le proprietà di idempotenza.
Il processo di installazione e le basi di Docker sono ben descritti nel suo . Pertanto, anticipando un po', ecco come si presenta il nostro 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"
Lo salviamo nella cartella del nostro progetto Android e avviamo la costruzione del container con il comando
docker build -t android-build:5.4-28-27 .Caratteristica -t assegna il tag o il nome del nostro container, che di solito è composto dal suo nome e versione. Nel nostro caso, l'abbiamo chiamato android-build e nella versione abbiamo indicato la combinazione delle versioni di gradle, android-sdk e platform-tools. In seguito ci sarà più facile cercare l'immagine necessaria per nome usando tale 'versione'.
Dopo che la costruzione è avvenuta con successo, possiamo usare la nostra immagine localmente, possiamo caricarla con il comando docker push su un repository pubblico o privato di immagini per scaricarla su altre macchine.
Come esempio, costruiremo localmente un progetto. Per questo, nella cartella del progetto eseguiremo il comando
docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebugAnalizziamo cosa significa:
docker run — il comando stesso per avviare l'immagine
-rm — significa che dopo l'interruzione del container rimuove tutto ciò che è stato creato durante la sua esistenza
-v "$PWD":/home/gradle/ — monta la cartella corrente del nostro progetto Android nella cartella interna del container /home/gradle/
-w /home/gradle — imposta la directory di lavoro del container
android-build:5.4.1-28-27 — il nome del nostro container che abbiamo costruito
gradle assembleDebug — in sostanza, il comando di costruzione che compila il nostro progetto
Se tutto va a buon fine, dopo un paio di secondi/minuti vedrete sullo schermo qualcosa come BUILD SUCCESSFUL in 8m 3s! E nella cartella app/build/output/apk ci sarà l'applicazione compilata.
Analogamente, è possibile eseguire altre attività di gradle — controllare il progetto, eseguire test, ecc. Il principale vantaggio è che se è necessario costruire il progetto su un'altra macchina, non dobbiamo preoccuparci dell'installazione di tutto l'ambiente e sarà sufficiente scaricare l'immagine necessaria e avviare la costruzione al suo interno.
Il container non memorizza alcuna modifica, e ogni costruzione inizia da zero, il che da un lato garantisce l'identità della costruzione indipendentemente da dove venga eseguita, dall'altro lato, ogni volta dobbiamo scaricare tutte le dipendenze e compilare di nuovo tutto il codice, e questo a volte può richiedere un tempo considerevole. Pertanto, oltre al normale avvio 'freddo', abbiamo un'opzione per avviare la costruzione mantenendo il cosiddetto 'cache', in cui salviamo la cartella ~/.gradle semplicemente copiandola nella cartella di lavoro del progetto, e all'inizio della costruzione successiva la rimettiamo indietro. Tutte le procedure di copia sono state spostate in script separati e il nostro comando di avvio è diventato così
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"Di conseguenza, il tempo medio di costruzione del progetto è stato ridotto di diversi volte (a seconda del numero di dipendenze nel progetto, ma in questo modo un progetto medio è ora costruito in un minuto anziché in cinque minuti).
Tutto ciò ha senso solo se si dispone di un proprio server CI/CD interno, di cui ci si occupa personalmente. Ma ora ci sono molti servizi cloud in cui tutti questi problemi sono risolti e non dovete preoccuparvene e le proprietà di costruzione necessarie possono essere anche specificate nelle impostazioni del progetto.
Solo gli utenti registrati possono partecipare al sondaggio. , per favore.
Utilizzate un sistema CI/CD interno o un servizio esterno?
Utilizziamo un server interno
Utilizziamo un servizio esterno
Non utilizziamo CI/CD
Altro
Hanno votato 42 utenti. Si sono astenuti 16 utenti.
Fonte: habr.com
