Assemblaggio del progetto Android in un contenitore Docker

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 sito ufficiale. 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 assembleDebug

Analizziamo 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. Accedi, 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

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster