Construyendo un proyecto Android en un contenedor Docker

Al desarrollar un proyecto para la plataforma Android, incluso el más pequeño, tarde o temprano tienes que lidiar con el entorno de desarrollo. Además del SDK de Android, es necesario tener la última versión de Kotlin, Gradle, platform-tools, build-tools. Y si en la máquina del desarrollador todas estas dependencias se resuelven en mayor medida utilizando el IDE de Android Studio, entonces en el servidor CI/CD, cada actualización puede convertirse en un dolor de cabeza. Y si en el desarrollo web, Docker se ha convertido en la solución estándar para el problema del entorno, ¿por qué no intentar resolver un problema similar con él en el desarrollo de Android?

Para aquellos que no saben qué es Docker, si es bastante simple, entonces esta es una herramienta para crear los llamados. "Contenedores" que contienen el kernel mínimo del sistema operativo y el conjunto de software necesario que podemos implementar donde queramos, manteniendo el entorno. Lo que habrá exactamente en nuestro contenedor se determina en el Dockerfile, que luego se ensambla en una imagen que se puede iniciar en cualquier lugar y tiene propiedades de idempotencia.

El proceso de instalación y los conceptos básicos de Docker están bellamente descritos en su el sitio web oficial. Por lo tanto, mirando un poco hacia adelante, tenemos un 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 guardamos en la carpeta con nuestro proyecto de Android y comenzamos a construir el contenedor con el comando

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

Parámetro -t establece la etiqueta o nombre de nuestro contenedor, que normalmente consta de su nombre y versión. En nuestro caso, lo llamamos android-build y en la versión especificamos una combinación de versiones de gradle, android-sdk y plataforma-herramientas. En el futuro, será más fácil para nosotros buscar la imagen que necesitamos por nombre utilizando dicha "versión".

Después de que haya pasado la compilación, podemos usar nuestra imagen localmente, podemos descargarla con el comando docker push a un repositorio de imágenes público o privado para descargarlo a otras máquinas.

Como ejemplo, construyamos un proyecto local. Para hacer esto, en la carpeta del proyecto, ejecute el comando

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

Averigüemos qué significa:

Docker Run - el comando de inicio de imagen en sí
-rm - significa que después de detener el contenedor, elimina todo lo que se creó durante su vida
-v "$PWD":/inicio/gradle/ - monta la carpeta actual con nuestro proyecto de Android en la carpeta interna del contenedor /home/gradle/
-w /casa/gradle - establece el directorio de trabajo del contenedor
compilación de Android: 5.4.1-28-27 - el nombre de nuestro contenedor que hemos recogido
gradle ensamblar Depurar - el propio equipo de construcción, que ensambla nuestro proyecto

Si todo va bien, luego de un par de segundos / minutos verá algo como CONSTRUYE CON ÉXITO en 8m 3s! Y en la carpeta app/build/output/apk habrá una aplicación ensamblada.

De manera similar, puede realizar otras tareas de Gradle: verificar el proyecto, ejecutar pruebas, etc. La principal ventaja es que si necesitamos compilar el proyecto en cualquier otra máquina, no debemos preocuparnos por instalar todo el entorno, y bastará con descargar la imagen necesaria y ejecutar la compilación en ella.

El contenedor no almacena ningún cambio, y cada ensamblaje se lanza desde cero, lo que, por un lado, garantiza la identidad del ensamblaje independientemente de dónde se lance, por otro lado, cada vez que debe descargar todas las dependencias y vuelva a compilar todo el código, y esto a veces puede llevar mucho tiempo. Por tanto, además del habitual arranque “en frío”, tenemos la opción de iniciar el montaje manteniendo el denominado. "caché", donde guardamos la carpeta ~/.gradle simplemente copiándola en la carpeta de trabajo del proyecto, y al comienzo de la siguiente compilación la devolvemos. Movimos todos los procedimientos de copia a secuencias de comandos separadas y el comando de inicio comenzó a verse así

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"

Como resultado, el tiempo promedio de compilación del proyecto se redujo varias veces (según la cantidad de dependencias del proyecto, pero el proyecto promedio comenzó a compilarse en 1 minuto en lugar de 5 minutos).

Todo esto por sí solo tiene sentido solo si tiene su propio servidor interno de CI / CD, que usted mismo admite. Pero ahora hay muchos servicios en la nube en los que se resuelven todos estos problemas y no tiene que preocuparse por eso, y las propiedades de compilación necesarias también se pueden especificar en la configuración del proyecto.

Solo los usuarios registrados pueden participar en la encuesta. Registrarsepor favor

¿Mantiene su sistema CI/CD interno o utiliza un servicio de terceros?

  • Usando un servidor interno

  • Uso de un servicio externo

  • No usamos CI/CD

  • Otro

42 usuarios votaron. 16 usuarios se abstuvieron.

Fuente: habr.com

Añadir un comentario