Budowanie projektu na Androida w kontenerze Docker

Tworząc projekt na platformę Android, nawet najmniejszy, prędzej czy później trzeba się zmierzyć ze środowiskiem deweloperskim. Oprócz Android SDK konieczne jest posiadanie najnowszej wersji Kotlina, Gradle, platform-tools, build-tools. A jeśli na maszynie programisty wszystkie te zależności zostaną rozwiązane w większym stopniu za pomocą Android Studio IDE, to na serwerze CI/CD każda aktualizacja może przyprawić o ból głowy. A jeśli w tworzeniu stron internetowych Docker stał się standardowym rozwiązaniem problemu środowiska, to dlaczego nie spróbować rozwiązać podobnego problemu w rozwoju Androida…

Dla tych, którzy nie wiedzą, czym jest Docker – jeśli jest to w miarę proste, to jest to narzędzie do tworzenia tzw. „Kontenery”, które zawierają minimalne jądro systemu operacyjnego i niezbędny zestaw oprogramowania, które możemy wdrożyć gdziekolwiek chcemy, przy jednoczesnym zachowaniu środowiska. To, co dokładnie znajdzie się w naszym kontenerze, określane jest w pliku Dockerfile, który następnie składany jest w obraz, który można uruchomić w dowolnym miejscu i który ma właściwości idempotentne.

Proces instalacji i podstawy Dockera są pięknie opisane na jego stronie Oficjalna strona. Dlatego patrząc trochę w przyszłość, mamy taki plik 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"

Zapisujemy go do folderu z naszym projektem na Androida i rozpoczynamy budowę kontenera za pomocą polecenia

docker build -t android-build:5.4-28-27 .

Parametr -t ustawia tag lub nazwę naszego kontenera, która zwykle składa się z jego nazwy i wersji. W naszym przypadku nazwaliśmy to Android-build i w wersji określiliśmy kombinację wersji gradle, android-sdk i platform-tools. W przyszłości łatwiej będzie nam wyszukać potrzebny obraz po nazwie, korzystając z takiej „wersji”.

Po zakończeniu kompilacji możemy użyć naszego obrazu lokalnie, możemy go pobrać za pomocą polecenia dokowanie do doku do publicznego lub prywatnego repozytorium obrazów w celu pobrania ich na inne maszyny.

Jako przykład zbudujmy projekt lokalny. W tym celu w folderze projektu uruchom polecenie

docker run --rm -v "$PWD":/home/gradle/ -w /home/gradle android-build:5.4.1-28-27 gradle assembleDebug

Zastanówmy się, co to znaczy:

uruchamianie dokera - samo polecenie uruchomienia obrazu
-rm - oznacza, że ​​po zatrzymaniu kontenera usuwa wszystko, co powstało w trakcie jego życia
-v "$PWD":/home/gradle/ - montuje bieżący folder z naszym projektem na Androida do wewnętrznego folderu kontenera /home/gradle/
-w /home/gradle - ustawia katalog roboczy kontenera
kompilacja Androida: 5.4.1-28-27 - nazwa naszego kontenera, który zebraliśmy
gradle assembleDebug - sam zespół budujący, który montuje nasz projekt

Jeśli wszystko pójdzie dobrze, to po kilku sekundach/minutach zobaczysz coś takiego BUDUJ SUKCES w 8m 3s! A w folderze app/build/output/apk będzie zmontowana aplikacja.

Podobnie możesz wykonywać inne zadania stopniowe - sprawdzać projekt, uruchamiać testy itp. Główną zaletą jest to, że jeśli będziemy musieli zbudować projekt na innej maszynie, nie musimy się martwić o instalację całego środowiska, wystarczy pobrać potrzebny obraz i uruchomić na nim kompilację.

Kontener nie przechowuje żadnych zmian, a każdy montaż uruchamiany jest od zera, co z jednej strony gwarantuje tożsamość zestawu niezależnie od miejsca jego uruchomienia, z drugiej strony za każdym razem trzeba pobrać wszystkie zależności i skompiluj cały kod ponownie, co czasami może zająć znaczną ilość czasu. Dlatego oprócz zwykłego „zimnego” startu mamy możliwość uruchomienia montażu z zachowaniem tzw. „cache”, gdzie zapisujemy folder ~/.gradle po prostu kopiując go do folderu roboczego projektu i na początku kolejnej kompilacji zwracamy go z powrotem. Wszystkie procedury kopiowania przenieśliśmy do osobnych skryptów i samo polecenie uruchomienia zaczęło wyglądać tak

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"

W rezultacie średni czas budowy projektu został skrócony kilkukrotnie (w zależności od liczby zależności w projekcie, ale przeciętny projekt zaczął się zatem budować w 1 minutę zamiast 5 minut).

Wszystko to samo w sobie ma sens tylko wtedy, gdy masz własny wewnętrzny serwer CI/CD, który sam wspierasz. Ale teraz istnieje wiele usług w chmurze, w których wszystkie te problemy zostały rozwiązane i nie musisz się tym martwić, a niezbędne właściwości kompilacji można również określić w ustawieniach projektu.

W ankiecie mogą brać udział tylko zarejestrowani użytkownicy. Zaloguj się, Proszę.

Czy utrzymujesz swój system CI/CD wewnętrznie, czy korzystasz z usług strony trzeciej?

  • Korzystanie z serwera wewnętrznego

  • Korzystanie z usługi zewnętrznej

  • Nie używamy CI/CD

  • Inny

Głosowało 42 użytkowników. 16 użytkowników wstrzymało się od głosu.

Źródło: www.habr.com

Dodaj komentarz