Compilação de projeto Android em um contêiner Docker

Ao desenvolver um projeto para a plataforma Android, mesmo o menor, cedo ou 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 e build-tools. E se no computador do desenvolvedor todas essas dependências são normalmente resolvidas em grande parte com o Android Studio IDE, no servidor CI/CD cada atualização pode se transformar em uma dor de cabeça. E se na web, a solução padrão para o problema do ambiente se tornou o Docker, por que não tentar resolver um problema semelhante na Android-desenvolvimento…

Para aqueles que não sabem o que é o Docker — se formos simplificar, é uma ferramenta para criar os chamados "contêineres", que contêm o núcleo mínimo do sistema operacional e um conjunto necessário de software, que podemos implantar onde quisermos, mantendo assim o ambiente. O que estará exatamente em nosso contêiner é definido no Dockerfile, que depois é compilado em uma imagem que pode ser executada em qualquer lugar e possui propriedades de idempotência.

O processo de instalação e os fundamentos do Docker estão bem descritos em seu site oficial. Portanto, avançando um pouco, aqui está o Dockerfile que conseguimos criar

# Т.к. основным инструментом для сборки 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"

Salve-o na pasta do nosso projeto Android e execute a construção do contêiner com o comando

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

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

Depois que a construção foi concluída, podemos usar nossa imagem localmente, podemos carregá-la com o comando docker push para um repositório público ou privado de imagens para baixá-la em outras máquinas.

Como exemplo, vamos compilar o projeto localmente. Para 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 analisar o que isso significa:

docker run — o próprio comando para executar a imagem
-rm — significa que após parar o contêiner, ele remove tudo o que foi criado durante o seu ciclo de vida
-v "$PWD":/home/gradle/ — monta a pasta atual com o nosso projeto Android para a 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 compilamos
gradle assembleDebug — a equipe de construção que compila nosso projeto

Se tudo correr bem, em alguns segundos/minutos você verá algo como BUILD SUCCESSFUL in 8m 3s! E na pasta app/build/output/apk estará o aplicativo compilado.

Da mesma forma, você pode executar outras tarefas do gradle — verificar o projeto, executar testes, etc. A principal vantagem é que, se precisarmos compilar o projeto em qualquer outra máquina, não precisamos nos preocupar com a instalação de todo o ambiente; basta baixar a imagem necessária e executar a compilação nela.

O container não armazena nenhuma alteração, e cada compilação é iniciada do zero, o que, por um lado, garante a identidade da compilação independentemente de onde ela seja iniciada, mas, por outro lado, significa que, a cada vez, precisamos baixar todas as dependências e compilar todo o código novamente, o que pode levar um tempo considerável. Portanto, além da execução 'fria' habitual, temos a opção de iniciar a compilação mantendo o chamado '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 restauramos. Todos os procedimentos de cópia foram isolados em scripts separados e a própria equipe de execução ficou 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 no projeto, mas um projeto médio passou a ser compilado em 1 minuto em vez de 5 minutos).

Tudo isso faz sentido apenas se você tiver seu próprio servidor CI/CD interno, cuja manutenção é de sua responsabilidade. Mas agora existem muitos serviços em nuvem onde todos esses problemas são resolvidos e você não precisa se preocupar com isso; as propriedades necessárias da construção podem ser definidas nas configurações do projeto.

Apenas usuários registrados podem participar da pesquisa. Entre, por favor.

Você mantém o sistema CI/CD internamente ou utiliza um serviço de terceiros?

  • Usamos servidor interno

  • Usamos serviço externo

  • Não usamos CI/CD

  • Outro

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

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster