Fonte: Roman Pentin — link

Como aplicamos CI/CD para o Android aqui na Empiricus. — Parte 1

Lucas Pires
#EmpiricusTech
Published in
5 min readApr 13, 2022

--

Bem, antes de começarmos a falar sobre como aplicamos o CI/CD, devemos falar o que é uma CI/CD para o Android, para os íntimos esteira/pipeline.

A grosso modo é automatizar tarefas que sem a esteira teriam que ser feitas a mão. — Ora, ficou vago essa explicação — , calma jovem padawan, vou descrever um processo de publicação de um versão de um app, assim ficará mais fácil o entendimento.

O processo de publicação de um app são os seguintes:

1) Rodar todos os testes;

2) Gerar APK;

3) Fazer upload na loja;

4) Controlar liberação para os usuários.

Existem outros passos, mas vamos focar apenas nesses.

Executar esses passos vai demandar um tempo do desenvolvedor, pois cada etapa só pode ser feita após a anterior e com isso pode se perder facilmente uns bons minutos (dependendo do projeto boas horas) — Mas, parece pouco benefício colocar uma esteira para executar apenas essas etapas — , acredite, não é. Temos as tarefas diárias que o time de QA tem que testar para garantir a qualidade e por muitas vezes é necessário gerar alguns artefatos por dia.
Já com a esteira(somos íntimos), podemos configurar um trigger quando alguma alteração for lançada naquela branch(normalmente chamada de release) uma versão será publicada na loja, com todos os testes passando, assinada, com versão e aumento gradativo na liberação para os usuários e no caso de uma versão apenas para testes gerar artefato para o time de QA.

Vou deixar um link que melhor explica o que é CI/CD, aqui.

Agora que temos um conhecimento básico sobre o que é uma esteira, vamos falar de como aplicamos ela aqui na Empiricus.

O que motivou a construção da nossa esteira.

Devido a alta demanda de tarefas e consequentemente geração de muitos artefatos, estávamos desperdiçando muito tempo nessas tarefas que poderiam ser automatizadas, isso sem falar que temos diversos módulos que são importados dentro do App principal, ou seja, gerar dois artefatos caso a tarefa seja relacionada a algum módulo. Gerado os artefatos temos que enviar para o time de QA e ocasionalmente algum demandante para garantir a qualidade e com isso alguns minutos foram perdidos.

Com passar o tempo começou a ficar muito custoso fazer isso manualmente, e como tempo é dinheiro, foi colocado na mesa a ideia da esteira.

Agora vamos entrar na parte interessante.

Primeiro temos que entender como estamos:

Fonte: Autor

O app importa alguns módulos e estão em um repositório Maven, com suas respectivas versões.

Agora surgiu um problema interessante de resolver: “Como podemos fazer alguma alteração no módulo que reflita no app principal sem termos que gerar as versões manualmente?”

Primeiro criamos uma variável para receber um valor externo via bash script dentro do build.gradle do projeto:

Fonte: Autor

E outra variável para ser a versão do módulo concatenada com o valor recebido via script.

Essa propriedade “versionSuffix” é criada a partir da branch da task. Exemplo:

O código da tarefa(ticket no board) EMP-999, logo se for uma nova funcionalidade ficará com esse nome a branch: feature/emp-999.

Com isso passamos esse valor para uma variável de ambiente com esse comando:

(-SNAPSHOT sempre é adicionado via código para que o repositório Maven aceite sem problemas e /(barra) é substituída por -(hífen))

Fonte: Author

Agora preciso criar uma task no gradle que me informe a versão atual do módulo:

Fonte: Autor

De forma simples e rápida a mesma foi criada.

Até aqui tudo belezinha?!

Agora vamos pra parte de concatenar as versões e preparar para publicar uma snapshot.

Com a criação de uma variável de ambiente e poucos comandos podemos rapidamente fazer isso. Segue os comandos:

Fonte: Autor

gradlew -q printVersion: Execute a task que criamos sem logs, apenas com resultado que será 0.0.1.

-DversionSuffix=$EXTERNAL_SUFFIX_VERSION: Adiciona o valor do sufixo lá onde colocamos uma variável para receber valor externo.

E o resultado é que a variável MODULE_VERSION possui o valor de 0.0.1-emp-999-SNAPSHOT

Com tudo isso feito, adicionamos também nas variáveis de ambiente a versão do módulo:

Agora publicamos essa versão no repositório Maven via comando:

Lembrando que a task de publicação já está configurada

Fonte: Autor
Fonte: Autor

Após a task ser finalizada com sucesso, temos o resultado:

Fonte: Autor

Versão publicada no repositório com sucesso.

Até o momento executamos esses passos na nossa esteira:

Fonte: Autor

O que cada etapa faz até aqui:

SSH KEY: Nessa etapa, configuramos o usuário do repositório git para a esteira se autenticar no repositório. Com isso feito podemos clonar o projeto para prosseguir com a esteira.

GIT CLONE: Efetua a clonagem do repositório.

CHECK BRANCH SYNC: Como uma medida de garantia para quando o artefato for criado, esteja com o código da branch develop juntamente com o código novo. Efetuamos a checagem se a branch atual (no caso feature/emp-999) está sincronizada com a develop. Caso não esteja a esteira é interrompida.

CREATE SUFFIX: Esse processo é o explicado nesse post, cria um sufixo para a versão que está sendo criada.

PUT ENV VARIABLES: Aqui colocamos os nomes das versões nas variáveis de ambiente para que a próxima etapa consiga recuperar esses valores.

TASK ANDROID: Aqui executamos os testes e geramos o artefato.

PUBLISH SNAPSHOT VERSION: Publicamos a versão do módulo no repositório Maven através da task ./gradlew publishSnapshotAarModuleSnapshotRepository

Por hoje é apenas isso. Na parte 2 continuo com as explicações até chegar no final do processo.

--

--

Lucas Pires
#EmpiricusTech

Android Engineer at Empiricus. MBA Software Engineering.