Sviluppando un progetto per la piattaforma Android, anche il più piccolo, 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. E se sulla macchina del programmatore tutte queste dipendenze vengono risolte principalmente utilizzando l'IDE Android Studio, sul server CI/CD, ogni aggiornamento può trasformarsi in un incubo. Se nel web-development, la soluzione ai problemi ambientali è diventata lo standard Docker, perché non provare a risolvere la stessa problematica anche nello sviluppo Android...
Per coloro che non sanno cos'è Docker — in parole semplici, è uno strumento per la creazione dei cosiddetti "contenitori" che contengono un nucleo minimo del sistema operativo e il set necessario di software, che possiamo distribuire dove vogliamo, mantenendo comunque l'ambiente. Cosa ci sarà nel nostro contenitore è definito nel Dockerfile, che poi viene compilato in un'immagine eseguibile ovunque e dotata di proprietà di idempotenza.
Il processo di installazione e le basi di Docker sono ben descritti nel suo . Pertanto, andando un po' oltre, ecco come è venuto 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 contenitore con il comando
docker build -t android-build:5.4-28-27 .Parametro -t assegna un tag o un nome al nostro contenitore, che di solito consiste nel suo nome e nella versione. Nel nostro caso lo abbiamo chiamato android-build e nella versione abbiamo indicato la combinazione delle versioni di gradle, android-sdk e platform-tools. In futuro sarà più semplice cercare l'immagine di cui abbiamo bisogno per nome utilizzando tale "versione".
Dopo che la compilazione è completata, possiamo utilizzare la nostra immagine localmente, oppure possiamo caricarla con il comando docker push su un repository pubblico o privato di immagini per scaricarla su altre macchine.
Come esempio, assembleremo un progetto localmente. Per fare ciò, nella cartella del progetto eseguiamo 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 eseguire l'immagine
-rm — indica che dopo l'arresto del contenitore elimina tutto ciò che è stato creato durante la sua vita
-v "$PWD":/home/gradle/ — monta la cartella attuale con il nostro progetto Android nella cartella interna del contenitore /home/gradle/
-w /home/gradle — imposta la directory di lavoro del contenitore
android-build:5.4.1-28-27 — il nome del nostro contenitore, che abbiamo assemblato
gradle assembleDebug — il comando di build che compila il nostro progetto
Se tutto va bene, dopo un paio di secondi/minuti vedrete sul vostro schermo qualcosa di simile a BUILD SUCCESSFUL in 8m 3sOgni tanto nella cartella app/build/output/apk ci sarà l'applicazione compilata.
Allo stesso modo, si possono eseguire altre attività di gradle — controllare il progetto, eseguire test, ecc. Il principale vantaggio è che se abbiamo bisogno di compilare il progetto su un'altra macchina, non dobbiamo preoccuparci di installare tutto l'ambiente, basta scaricare l'immagine necessaria e avviare la compilazione su di essa.
Il container non conserva alcuna modifica, e ogni compilazione inizia da zero, il che da una parte garantisce l'identità della compilazione indipendentemente dal luogo in cui viene eseguita, ma dall'altra ogni volta dobbiamo scaricare tutte le dipendenze e ricompilare tutto il codice da zero, il che a volte può richiedere un tempo significativo. Pertanto, oltre al normale avvio "freddo", abbiamo l'opzione di avviare una compilazione mantenendo il cosiddetto "cache", dove salviamo la cartella ~/ .gradle semplicemente coprendola nella cartella di lavoro del progetto, e all'inizio della successiva compilazione la restituiamo indietro. Tutte le procedure di copia sono state estratte in script separati e il comando stesso di avvio è diventato
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"Il risultato è che il tempo medio di compilazione del progetto è diminuito di diversi volte (a seconda del numero di dipendenze nel progetto, ma in media un progetto così è diventato compilabile in 1 minuto invece di 5 minuti).
Tutto questo ha senso solo se avete un proprio server CI/CD interno, di cui vi occupate voi stessi. Ma ora ci sono molti servizi cloud in cui tutti questi problemi sono stati risolti e non dovete preoccuparvene, e le proprietà necessarie della compilazione possono essere indicate anche 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
