Construindo um projeto Android em um contêiner Docker

Ao desenvolver um projeto para a plataforma Android, mesmo o menor, mais cedo ou mais tarde você terá que lidar com o ambiente de desenvolvimento. Além do Android SDK, é necessário ter a versão mais recente do Kotlin, Gradle, platform-tools, build-tools. E se na máquina do desenvolvedor todas essas dependências são resolvidas em maior medida usando o Android Studio IDE, então no servidor CI / CD cada atualização pode se transformar em uma dor de cabeça. E se no desenvolvimento web o Docker se tornou a solução padrão para o problema do ambiente, por que não tentar resolver um problema semelhante com ele no desenvolvimento do Android ...

Para quem não sabe o que é Docker - se é bem simples, então esta é uma ferramenta para criar o chamado. "Contêineres" que contêm o kernel mínimo do sistema operacional e o conjunto necessário de software que podemos implantar onde quisermos, mantendo o ambiente. O que exatamente estará em nosso contêiner é determinado no Dockerfile, que é então montado em uma imagem que pode ser iniciada em qualquer lugar e possui propriedades de idempotência.

O processo de instalação e os fundamentos do Docker são lindamente descritos em seu o site oficial. Portanto, olhando um pouco à frente, temos um 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"

Salvamos na pasta com nosso projeto Android e começamos a construir o container com o comando

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

Parâmetro -t define a tag ou nome do nosso contêiner, que geralmente consiste em seu nome e versão. No nosso caso, chamamos de android-build e na versão especificamos uma combinação das versões gradle, android-sdk e platform-tools. No futuro, será mais fácil para nós procurar a imagem que precisamos pelo nome usando essa "versão".

Após a conclusão da compilação, podemos usar nossa imagem localmente, podemos baixá-la com o comando empurrão do docker para um repositório de imagens público ou privado, a fim de baixá-lo para outras máquinas.

Como exemplo, vamos construir um projeto local. Para fazer isso, na pasta do projeto, execute o comando

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

Vamos descobrir o que significa:

Docker Run - o próprio comando de lançamento de imagem
-rm - significa que após parar o container, ele apaga tudo que foi criado durante sua vida
-v "$PWD":/home/gradle/ - monta a pasta atual com nosso projeto Android na pasta interna do contêiner /home/gradle/
-w /home/gradle - define o diretório de trabalho do contêiner
compilação do Android: 5.4.1-28-27 - o nome do nosso contêiner que coletamos
gradle assembleDebug - a própria equipe de construção, que monta nosso projeto

Se tudo correr bem, depois de alguns segundos / minutos você verá algo como CONSTRUA COM SUCESSO em 8m 3s! E na pasta app/build/output/apk haverá um aplicativo montado.

Da mesma forma, você pode executar outras tarefas gradle - verificar o projeto, executar testes, etc. A principal vantagem é que se precisarmos construir o projeto em qualquer outra máquina, não precisamos nos preocupar em instalar todo o ambiente, bastando baixar a imagem necessária e rodar o build nela.

O container não armazena nenhuma alteração, e cada assembly é iniciado do zero, o que, por um lado, garante a identidade do assembly independentemente de onde seja iniciado, por outro lado, cada vez que você precisa baixar todas as dependências e compilar todo o código novamente, e às vezes isso pode levar um tempo significativo. Portanto, além da habitual partida "a frio", temos a opção de iniciar a montagem mantendo a chamada. "cache", onde salvamos a pasta ~/.gradle simplesmente copiando-a para a pasta de trabalho do projeto, e no início da próxima compilação a devolvemos. Movemos todos os procedimentos de cópia para scripts separados e o próprio comando de inicialização começou a ficar assim

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, o tempo médio de compilação do projeto foi reduzido várias vezes (dependendo do número de dependências do projeto, mas o projeto médio começou a ser compilado em 1 minuto em vez de 5 minutos).

Tudo isso por si só faz sentido se você tiver seu próprio servidor CI / CD interno, ao qual você mesmo oferece suporte. Mas agora existem muitos serviços em nuvem nos quais todos esses problemas são resolvidos e você não precisa se preocupar com isso, e as propriedades de construção necessárias também podem ser especificadas nas configurações do projeto.

Apenas usuários registrados podem participar da pesquisa. Entrarpor favor

Você mantém seu sistema de CI/CD interno ou usa um serviço de terceiros

  • Usando um servidor interno

  • Usando um serviço externo

  • Não usamos CI/CD

  • Outro

42 usuários votaram. 16 usuários se abstiveram.

Fonte: habr.com

Adicionar um comentário