Como automatizei e aprimorei 40 minutos repetitivos de trabalho manual
Nesse artigo conto como automatizei aproximadamente 40 minutos de trabalho manual de build e deploy de um aplicativo white label para iOS, com o uso de comandos bash (programa shell interpretador de comandos) e da plataforma Bitrise de integração e entrega contínua (CI/CD).
O Problema
Na empresa em que atuo, sou um dos desenvolvedores de um aplicativo white label, ou seja, um aplicativo de desenvolvimento único, que pode ter aparência e funcionalidades personalizáveis para diferentes clientes.
No início da jornada, tínhamos aproximadamente 30 clientes, os quais, para cada um, eram necessários aproximadamente 40 minutos para realizar a build e deploy. Com essas informações, você pode imaginar quanto tempo era necessário para atualizar todos os clientes, não é?
O processo de build consistia em:
- Executar alguns scripts já implementados que definiam cores, imagens e funcionalidades que o cliente utilizava;
- Abrir o projeto no Xcode e realizar várias configurações padrões entre as builds, como alterações de workspace, assinatura do aplicativo, vínculos com plugins, entre outras. Esse era o processo que mais demandava trabalho manual, e a principal dor no processo, pois além de demorado, era passível de erro humano.
- Empacotar os arquivos de build (Archive), e enviar o aplicativo para a plataforma App Store Connect, onde é feita a distribuição para a loja.
Na busca de alguma plataforma CI/CD para aplicativos iOS que nos auxiliasse, encontrei o Bitrise, que além de ter uma ótima interface para criação e edição, tem um plano gratuito que encaixa perfeitamente com os nossos requisitos.
O desafio
O aplicativo é desenvolvido com o framework Ionic/Angular. Para automatizar o processo, era necessário solucionar vários problemas. Na arquitetura do projeto, há um arquivo chamado config.xml
que tem as principais informações do app, como nome, versão e bundle ID. Essas informações eram adquiridas através de arquivos JSON, onde cada cliente tem o seu objeto.
Com essas informações do arquivo config.xml
, a build cria pastas e arquivos com identificação vinculadas à elas. Sendo assim, o nome dos arquivos e pastas podem variar muito de acordo com o nome do cliente, e toda a navegação bash e alteração de arquivos teriam que respeitar esses nomes. Além disso, se o nome do cliente continha espaço, acento específico ou caracter especial, na build, alguns arquivos os substituíam por underline _
, o que dificultava ainda mais.
O próximo desafio era vincular plugins ao projeto, como Firebase e OneSignal, utilizados no envio de push notifications. Porém, esses vínculos eram realizados manualmente pelo Xcode, ou seja, era necessário descobrir alguma forma de realizá-los de forma automatizada.
Para isso, comecei a comparar os arquivos do projeto antes e depois de realizar os vínculos pelo Xcode, porém logo percebi que seria muito difícil, pois ao realizar tais mudanças, eram gerados de forma aleatória vários hashs nos arquivos, além de diversificar a localização dessas mudanças de uma build para outra, impossibilitando alguma lógica de automatização.
Foram escritos muitos códigos bash que abria pastas, inseria linhas, substituia partes do código fonte dos arquivos de build. Após incontáveis horas e frustradas tentativas de sucesso, o processo não andava mais para frente, ou ocorria erro na build, ou os plugins não funcionavam corretamente.
A ideia
Certo dia, surgiu uma lâmpada sobre minha cabeça:
Criar numa única vez, uma build genérica com nome, versão e bundle ID fictícios para o cliente, que na verdade eram as informacões do nosso aplicativo de demonstração. Depois executar a build do framework Ionic, realizar todas as alterações necessárias no Xcode, assim como fazemos com todos os clientes.
Após isso, buscar nos arquivos gerados, as informações do “cliente”, e as trocar para identificadores. Dessa forma, saberia exatamente o que substituir, de forma automatizada por bash. Exemplo:
Gerar o aplicativo com nome “Cliente”, e fazer a busca por este termo nos arquivos, e trocar todos para “NOME_CLIENTE”, com algum editor de texto, notepad++ como exemplo.
Após substituir essas informações com termos identificadores, salvei os arquivos editados em uma pasta específica do projeto. Com esse insight, finalmente tornou-se possível atingir o objetivo.
A execução
Escolhemos o Bitrise para a plataforma base da automatização, por já incluir várias funcionalidades de fácil utilização. Foi necessário apenas conectar a conta do Gitlab do projeto, e realizar algumas configurações de assinatura do aplicativo, com a ajuda da documentação da plataforma.
O processo final ficou o seguinte:
Executar alguns scripts bash pré-build, que alteram informações do aplicativo para o cliente em questão. Porém, o principal identificador no config.xml, que é o nome do cliente, fica como “Cliente”, para que a navegação e edição dos arquivos fique muito mais fácil.
Depois executar a build do framework Ionic, com uma função do Bitrise, substitui-se nos arquivos genéricos, via bash, os identificadores pelas informações do cliente. Em seguida, esses arquivos são movidos para o projeto, substituindo os arquivos existentes gerados pela build do Ionic.
Por fim, apenas é realizado o Archive do aplicativo, empacotando tudo em um só arquivo .app, e em seguida realizado o upload do mesmo para o App Store Connect. Estas etapas são realizadas com funções do próprio Bitrise, agilizando tudo e dando finalizando ao processo de build e deploy do aplicativo.
Plataforma utilitária
Para auxiliar ainda mais, foi criada uma plataforma utilitária em React.js, onde são apenas informados os clientes a serem gerados, e se necessário, sua versão de build.
Essa plataforma utilitária adquire os clientes pelo arquivo JSON que está no projeto, e exibe um formulário bem simples, que se comunica com o Bitrise via REST API para executar as builds conforme são solicitadas, passando os parâmetros que foram inseridos no formulário.
Depois de implementada, essa plataforma foi disponibilizada publicamente com deploy gratuito na Vercel, possuindo um controle de autenticação pelo Gitlab, onde apenas os membros do projeto tem acesso as funcionalidades.
Os resultados
O trabalho que antes era 100% manual, agora tem grande parte automatizada, demandando apenas o trabalho de acessar a plataforma utilitária para informar quais clientes gerar e realizar deploy para a App Store Connect.
De aproximadamente 40 minutos de trabalho manual, quando realizada a automatização no findar de 2020, o processo caiu para aproximadamente 25 minutos, mas no momento, é realizada na média de 13 minutos, por avanços no processamento da plataforma.
Conclusão
A partir desta automatização, economizamos muito tempo e esforço, que podem ser direcionados para outras etapas do produto.
Além disso, houve um aumento na confiabilidade, pois automatizando o processo, não há possibilidade de algum erro humano durante a build, que, na maioria das vezes, fazia com que o processo se resetava para a etapa zero.
Muitos aprendizados de comandos bash e da arquitetura Apple foram adquiridos nesse processo, e considero que foi a melhor coisa que desenvolvi para nossa equipe.