Construindo um projeto Android em um contêiner de docker

Ao desenvolver um projeto para a plataforma Android, mesmo o menor, mais cedo ou mais tarde, precisa lidar com o ambiente de desenvolvimento. Além do SDK do Android, você precisa da versão mais recente do Kotlin, Gradle, ferramentas de plataforma, ferramentas de construção. E se na máquina do desenvolvedor todas essas dependências forem resolvidas em maior medida usando o Android Studio IDE, no servidor de CI / CD, cada atualização poderá se tornar uma dor de cabeça. E se no desenvolvimento da Web, o Docker se tornou a solução padrão para o problema do ambiente, por que não tentar resolver um problema semelhante no desenvolvimento do Android ...

Para quem não sabe o que é o Docker - se é bem simples, essa é a chamada ferramenta de criação "Contêineres", onde estão contidos o kernel mínimo do SO e o conjunto de software necessário, que podemos implantar onde quisermos, preservando o ambiente. O que exatamente estará em nosso contêiner é definido no Dockerfile, que é montado em uma imagem lançada em qualquer lugar e com propriedades de idempotência.

O processo de instalação e os conceitos básicos do Docker estão perfeitamente descritos em seu site oficial . Portanto, correndo um pouco à frente, aqui 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" 

Nós o salvamos na pasta com nosso projeto Android e iniciamos a montagem do contêiner com o comando

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

A opção -t especifica a tag ou o nome do nosso contêiner, que geralmente consiste em seu nome e versão. No nosso caso, chamamos isso de android-build e, na versão, especificamos um conjunto de versões do gradle, android-sdk e platform-tools. No futuro, será mais fácil procurar a imagem de que precisamos pelo nome usando esta "versão".

Após a montagem, podemos usar nossa imagem localmente, podemos carregá-la com o comando docker push em um repositório de imagens público ou privado para fazer o download para outras máquinas.

Como exemplo, coletamos o projeto localmente. Para fazer isso, execute o comando na pasta do projeto

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

Vamos ver o que isso significa:

docker run - o próprio comando de inicialização da imagem
-rm - significa que depois de parar o contêiner, ele remove para trás tudo o que foi criado no processo de 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
android-build: 5.4.1-28-27 - o nome do nosso contêiner que coletamos
gradle assembleDebug - na verdade, a equipe de criação que cria nosso projeto

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

Da mesma forma, você pode executar outras tarefas de classificação - verificar o projeto, executar testes etc. A principal vantagem é que, se você precisar criar o projeto em qualquer outra máquina, não será necessário se preocupar com a instalação de todo o ambiente e será suficiente fazer o download da imagem necessária e executar a montagem nela.

O contêiner não armazena nenhuma alteração e cada assembly começa do zero, o que, por um lado, garante a identidade do assembly, independentemente de onde foi lançado, por outro lado, toda vez que você precisa baixar todas as dependências e compilar todo o código novamente, e isso às vezes pode levar um tempo considerável. Portanto, além da partida "a frio" usual, temos a opção de iniciar a montagem enquanto mantém 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, retornamos de volta. Colocamos todos os procedimentos de cópia em scripts separados e o próprio comando de inicialização começou a se parecer com isso

 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 montagem do projeto para nós foi reduzido várias vezes (dependendo do número de dependências do projeto, mas o projeto médio começou a se montar em 1 minuto, em vez de 5 minutos).

Tudo isso, por si só, só faz sentido se você tiver seu próprio servidor de CI / CD interno, com o suporte do qual você mesmo está envolvido. Mas agora existem muitos serviços em nuvem nos quais todos esses problemas foram resolvidos e você não precisa se preocupar com isso. Também é possível especificar as propriedades de montagem necessárias nas configurações do projeto.

Source: https://habr.com/ru/post/pt465193/


All Articles