Continuous Delivery com Fastlane e Android

Uma introdução sobre como a Fastlane pode ser útil em projetos Android

Wilson Martins
Android Dev BR
12 min readMay 23, 2020

--

Robôs autônomos da Amazon.

A medida que o software passou a ser mais importante na vida das pessoas e empresas, foi requerido cada vez que os desenvolvedores pudessem disponibilizá-lo o mais constante e rápido possível.

Muitas vezes durante o desenvolvimento de um projeto é necessário disponibilizar o entregável, ou seja o produto, para os mais variados tipos de pessoas: testadores, stakeholders, clientes finais, etc. Porém, mais importante aqui(no nosso contexto), é a necessidade de fazer isso várias vezes ao dia ou várias vezes na semana.

Independente de qual stack você atue, fazer esse processo manualmente sempre será um trabalho repetitivo e que obviamente consumirá o seu tempo, e isso provavelmente impactará na sua produtividade. Além do tempo gasto, provavelmente você não é a única pessoa no projeto em que trabalha e sendo assim, outras pessoas necessitarão fazer essas entregas também.

Consegue perceber como todo esse processo de várias pessoas entregando software várias vezes ao dia com várias versões diferentes e tentando fazer o mais rápido possível é um tanto complexo de entender e gerenciar? É realmente difícil garantir a qualidade e agilidade dessas entregas nesse cenário.

Aqui entra o Continuous Delivery…

Dentro desse contexto “caótico” surge o conceito de Continuous Delivery, ou traduzindo para o português Entrega Contínua. Esse termo se caracteriza exatamente pela prática de disponibilizar todos os tipos de alterações de forma rápida, segura e estável.

Ao mencionar “todos tipos de alterações” me refiro a: correção de bugs, novas funcionalidades, mudanças em configurações, etc.

Essa prática, por sua vez, nos fornece um conjunto de princípios que nos norteiam quanto a fazer entregas mais consistentes e eficientes. Segue abaixo a lista de princípios:

  • Builds de qualidade: esse princípio passa pela necessidade de serem realizados testes antes mesmo que as builds sejam disponibilizadas para uso. Isso garante a rapidez na detecção de bugs além de deixar o entregável menos suscetível a comportamentos inesperados para quem os usa.
  • Poucas mudanças: trabalhar com pequenas alterações entre as versões caracteriza um dos princípios do CD pelo fato de que é muito mais fácil de descobrir onde estão os problemas e corrigi-los. Além claro, de poder receber feedbacks mais rápidos.
  • O trabalho repetitivo fica para as máquinas: automatizar processos repetitivos nos ajuda a ganhar um tempo precioso, além claro de ser uma preocupação a menos. Dentro da entrega de software isso é útil pois nos possibilita manter a rapidez e estabilidade entre as diversas entregas que precisamos fazer.
  • Melhoria contínua: o software muda rapidamente e todas as mudanças requerem pequenos ajustes. É necessário sempre reavaliar o processo para que as melhorias possam surgir e continuem a impulsionar o projeto.
  • A responsabilidade é de todo mundo: no nosso mundo de devs somos todos inteiramente responsáveis pela qualidade das builds e estabilidade do software que estamos trabalhando. Ou seja, não existe: “esse bug não foi eu quem criei”.

Como podemos notar, são princípios interessantes que enfatizam boas práticas durante a entrega de software, não podendo deixar de mencionar os diversos benefícios que isso traz para o nosso processo como um todo, sendo estes: menos riscos para disponibilizar o produto, uma melhora considerável na qualidade do entregável, etc.

Enfim, os benefícios para o nosso processo de desenvolvimento de software são os mais variados possíveis. Porém como isso tudo se relaciona ao Fastlane? E ainda mais, o que o Android tem a ver com isso?

O papel da Fastlane

Bom dentro do cenário que estamos descrevendo, a Fastlane entra como uma peça fundamental que nos ajudará a colocar tudo isso em prática, pois o propósito dela é justamente esse: ser uma ferramenta que nos ajude a automatizar o processo de deploy em aplicações Android e iOS.

Sim, a Fastlane é uma ferramenta de Continuous Delivery focada no mundo mobile.

Nós, enquanto desenvolvedores mobile, sabemos devidamente os diversos passos que temos que fazer para lançar uma aplicação para teste e até mesmo na loja. Entre essas etapas muitas das vezes temos que: tirar screenshots do app, alterar versão do app, alterar ícone de acordo com o tipo de build, avisar aos colegas no Slack que tem build nova, etc. São muitos passos que se fôssemos fazer manualmente daria um trabalho gigantesco todas as vezes.

Porém, como já sabemos, o Fastlane está aí para nos ajudar nisso. Dessa forma, uma das suas principais características que nos permite fazer os passos descritos anteriormente e muito mais, é sua grande quantidade de integrações e plugins. Caso queira saber quais plugins o Fastlane disponibiliza, basta abrir este link.

Lembra que nos perguntamos como o Android se encaixaria nisso? Pois bem, nesse post vamos aprender um pouco como podemos utilizar a Fastlane para praticar a entrega contínua em projetos [Android] nativos.

Instalando a Fastlane em um projeto Android

O primeiro passo antes mesmo de colocarmos a Fastlane em um projeto Android é instalá-la na nossa máquina, uma vez que essa é uma ferramenta utilizada via linha de comando.

O pré-requisito para fazer essa instalação é possuir o xcode-tools instalado, pois até a última vez em que esse post foi editado a Fastlane oferecia suporte oficial apenas ao macOS. Caso deseje ler mais sobre, poderá encontrar informações neste link. Tendo esse requisito pronto, podemos começar executando o seguinte comando:

Após rodar o comando anterior, finalmente, vamos instalar a Fastlane. Você poderá escolher entre as duas opções abaixo, ambas produzirão o mesmo resultado. Segue as alternativas de comando para instalar a ferramenta:

Caso prefira instalar via howebrew:

Por fim, vamos rodar o comando para colocar o Fastlane dentro do nosso projeto Android. Uma coisa que vale ressaltar antes de executá-lo é que você deverá entrar no seu projeto, ou seja, o comando deverá ser executado no diretório onde fica os módulos do seu projeto Android. Resumindo: você precisa estar na raiz do projeto. Segue abaixo o comando:

O resultado do comando acima será a instalação e configuração de algumas dependências default da Fastlane. Você também irá se deparar com 3 perguntas, são elas:

  • Primeira pergunta: perguntará qual é o namespace do seu projeto. A resposta, sendo assim, é óbvia. Você deverá colocar o package name do seu projeto Android. Segue abaixo um exemplo:
  • Segunda pergunta: perguntará onde está o arquivo em json que possui uma chave de acesso às APIs da Google. Por agora, não vamos nos preocupar com isso e sua resposta deverá ser apenas um [enter];
  • Terceira pergunta: perguntará se deseja baixar os metadados já salvos dentro da pasta Fastlane. Apenas digite n e pressione [enter];

Entendendo a Fastlane

Ao executar o último comando citado perceberemos que uma pasta com o nome Fastlane foi criada, mas além disso, dentro dela, outros arquivos foram criados. Cada um deles possuem funções importantes para a ferramenta, sendo assim, segue abaixo a utilidade de cada um:

  • Fastfile: local onde definimos todos os comandos e passos que a Fastlane em nosso projeto executará. Por exemplo, é lá que iremos dizer que nós queremos tirar screenshots do nosso app, que queremos executar os testes, que queremos buildar com determinado build type, etc.
  • Appfile: local onde fica todas as configurações globais do nosso app Android;

Sintaxe no Fastfile

Como já mencionado, no arquivo Fastfile ficarão todos os passos que poderão ser executados no nosso projeto através da Fastlane. Trazendo para o nosso contexto, quando falamos em criar "passos" estamos nos referindo a criar "lanes". Este é o termo mais correto a ser utilizado.

A Fastlane é uma ferramenta escrita em Ruby, sendo assim, muito da sintaxe que usaremos dentro do Fastfile será bastante similar com essa sintaxe. Para entendermos sobre ela, iremos utilizar o código fornecido inicialmente no arquivo Fastfile. Sendo assim, código presente no seu arquivo se parecerá com algo assim:

Ao olhar o código acima é possível, rapidamente, ver um certo padrão e realmente existe. Sempre que formos criar uma lane devemos primeiramente fornecer uma descrição. Sendo assim, usa-se a keyword desc, como é possível ver nas linhas 4, 9 e 18.

Para definir o bloco de código de uma lane, ou seja, tudo que ela pode fazer devemos fazer da seguinte maneira:

É possível também criar lanes privadas. Para fazer isso basta substituir a keyword lane por private_lane. Exemplo:

Executando uma lane

Executar uma lane é bastante simples, basta rodar o comando no terminal:

Todas as lanes declaradas no arquivo Fastfile estão disponíveis nesse comando. Sendo assim, utilizando o código que já está lá, podemos executar por exemplo:

Caso tenha dado tudo certo, aparecerá um resultado similar ao da imagem abaixo.

Executando uma lane a partir de outra

Chamar uma lane a partir de outra acontece da mesma forma que chamamos uma função a partir de outra no código normal. Por exemplo:

Ao executar fastlane test_print veremos a mensagem impressa entre as outras mensagens que a Fastlane também exibe. Algo importante a ressaltar é que: quando uma função declarada em Ruby não possui parâmetro é possível chamá-la omitindo os parênteses. Por isso podemos escrever apenas print_msg para invocá-la.

Passando parâmetros para uma lane

Podemos incrementar o exemplo acima e ao invés de exibirmos uma mensagem pré-definida exibiremos qualquer mensagem que desejarmos. Para isso é preciso que na assinatura da lane, que desejamos receber o parâmetro, adicionemos o trecho|options|.

Utilizando o exemplo anterior, ficaria da seguinte maneira:

Além da adição na assinatura da lane, também é necessário "nomear" os parâmetros. Na realidade, como já mencionado, a Fastlane utiliza a linguagem Ruby e nela existe um tipo chamado hash. Esse tipo nada mais é do “equivalente” um Hash que nós possuímos no Java/Kotlin, também é equivalente aos dicionários no Python. Dessa forma, a Fastlane só permite que sejam passados parâmetros de uma lane para outra através desse tipo.

Também é possível chamar uma lane e passar parâmetros a partir do terminal. Segue o exemplo abaixo:

"Ciclo de vida" de uma lane

Basicamente, o ciclo de vida de uma lane se resume a: momento anterior a execução, momento da execução e posterior a execução. Em relação ao momento anterior a execução possuímos dois "eventos" que são chamados automaticamente, porém com condições diferentes. São eles:

  • before_all
  • before_each

A diferença entre eles é clara: o primeiro é chamado uma única vez antes da execução de qualquer lane, já o segundo é chamado antes de cada execução. Segue abaixo um exemplo:

Eventos similares também existe para a pós-execução, sendo elas respectivamente: after_all e after_each.

Identificando erros

Como o mundo não é perfeito e nem sempre as coisas dão certo, é bem provável que durante a execução de uma lane ocorra algum erro inesperado e seja preciso interromper a execução dela. Saber se a lane deu erro é um feedback muito importante para nós. Isso serve por exemplo para quando automatizarmos o build de Android e por algum motivo durante a execução da lane ela falha, ao saber que falhou podemos enviar uma mensagem para o Telegram ou Slack.

O "evento" responsável por nos dá essa informação é o error. Segue abaixo um exemplo:

OBS: caso não tenha conseguido ver a mensagem "Lane crashed" à primeira vista devido ao volume de texto que a Fastlane mostra junto com o erro, basta olhar logo abaixo das mensagens destacadas na cor verde.

Automatizando processo de deploy no Android

Bom, agora que sabemos o básico da Fastlane podemos brincar um pouco com exemplos que são utilizados no mundo real. Um dos mais recorrentes desses exemplos é a automatização no deploy. O que faremos será o seguinte:

  • Rodar os testes do nosso projeto
  • Buildar nosso projeto em release
  • Fazer upload do apk na loja do Android
  • Exibir mensagem no Slack que deu sucesso(ou talvez falha)

Todas essas etapas serão automatizadas com o Fastlane e faremos isso tudo, ao final, executando apenas um comando: fastlane deploy.

Criando lane e rodando testes

Essa etapa é a mais simples dentre as descritas pelo fato de já termos visto antes. Sendo assim, nosso Fastfile ficará inicialmente assim:

Compilando projeto em release

A próxima etapa será gerar uma apk no modo release para que nós consigamos fazer upload dela na Google Play. Sendo assim, o Fastfile será atualizado para o código abaixo:

Integrando Fastlane à Google Play

Agora que já estamos compilando e gerando uma apk que possa ser colocada na Google Play, vamos configurar a Fastlane para que ela suba a apk automaticamente ao rodar a lane. Esse é um passo simples, porém poderá dar um pouco de trabalho.

A action que usaremos e que é recomendada pela Fastlane é a supply. Para utilizá-la é preciso recuperar um json de acesso nossa conta da Google. Isso é importante pois ela usa a API da Google Play para fazer o upload automaticamente. Sendo assim, segue os passos abaixo:

  • Vá até a Google Play Console.
  • Ao chegar lá, clique em Configurações.
  • No menu lateral, selecione Acesso à API.
  • Após entrar no item anterior, clique em Criar uma conta de serviço.

Ao clicar no botão sugerido anteriormente, você provavelmente verá o seguinte dialog:

Basta seguir os passos que são demonstrados pela Google e ao final baixar o json de acesso. Lembra que nós ignoramos a segunda pergunta que falava de um tal json, lá quando estávamos configurando a Fastlane? Pois bem, vamos voltar nisso agora.

O que precisamos fazer é dizer à Fastlane onde que está esse arquivo json que acabamos de baixar. A título de exemplo, vamos colocá-lo dentro da pasta do nosso projeto Android e chamá-lo de app-key.json. Por exemplo:

Bom, o que devemos fazer agora é bem simples. Basta abrir o arquivo Appfile que está dentro da pasta Fastlane e substituir a primeira linha pela linha a seguir:

Outra coisa que precisamos fazer nesse arquivo Appfile é verificar se está com o package_name correto. Ou seja, se o package_name que estamos referenciando corresponde à um app presente no nosso Google Play Console. Por exemplo, para este post estou usando um app com o pacote com.wilson.fastlaneexample. Segue abaixo:

Sendo assim, o meu arquivo Appfile está da seguinte maneira:

Por fim, precisamos apenas rodar o comando abaixo para que a Fastlane baixe todos os dados do nosso app, tais como: screenshoots, nome, descrição, etc.

Fazendo upload automático do APK

Agora que temos tudo configurando, precisamos apenas adicionar uma linha ao nosso Fastfile, que será o comando para fazer upload do APK. Ficará da seguinte maneira:

O que fizemos acima foi apenas adicionar: upload_to_play_store. Após isso precisamos apenas rodar nossa lane novamente para a Fastlane fazer upload do nosso APK para a Faixa de Produção no Google Play Console. Você perceberá algo similar à imagem abaixo.

É possível também mudar a faixa que você deseja para fazer o upload da APK. Por exemplo, caso quiséssemos preparar a APK para disponibilizar aos usuários beta, faríamos a seguinte mudança:

Para saber mais sobre todas as customizações que você pode fazer, basta seguir a documentação: https://docs.fastlane.tools/actions/supply/.

Integrando Fastlane ao Slack

Por fim, vamos aprender como fazer uma integração ao Slack para nos informar se o APK foi upado com sucesso ou deu algum problema durante esse processo. Essa é uma integração bem simples. A primeira coisa que devemos ter em mão é o webhook do seu canal no Slack.

Com o webhook em mãos, utilizaremos aquele "evento" que descrevemos mais acima, o before_all e error. O que queremos aqui é setar o nosso webhook antes de executar qualquer lane. Em relação ao error, queremos enviar para o Slack uma mensagem diferente da mensagem de sucesso. Sendo assim, nosso Fastfile ficará da seguinte maneira:

Por padrão ao chamar o Slack o parâmetro success é definido como true. Sendo assim, para informarmos que deu erro precisamos setar ele como false. Para finalizar podemos rodar novamente a lane de deploy e poderemos ver as mensagens de erro ou sucesso, como segue a imagem abaixo:

Problemas que você pode ter

Ao tentar fazer upload automaticamente do APK a Fastlane pode te apresentar alguns erros. Sendo assim, segue a lista com alguns deles e suas possíveis soluções:

  • #1 — Only releases with status draft may be created on draft app: Significa que no seu projeto lá na Google Play Console ainda não foi lançado nenhum APK para a loja, sendo assim você não pode fazer upload de um APK com o release_status de completed, que é o default utilizado pela Fastlane. Para resolver isso basta alterá-lo para draft. Ficaria assim:
  • #2 — Não consigo subir o primeiro APK de todos na Google Play automaticamente: Vamos supor que você acabou de criar o projeto na Google Play Console e quer upar o primeiro APK dele automaticamente. Isso não é possível, pois como nunca nenhum APK foi upado nesse projeto então ele não possui um package name associado. Sendo assim, quando a Fastlane tentar dar match em algum dos apps na Google Play Console não conseguirá encontrar nenhum. Ou seja, o primeiro APK de todos deve ser upado na mão, os posteriores podem ser upados automaticamente.

Concluindo

Embora tenha sido um post um tanto longo, o objetivo era que este fosse um apanhado geral sobre a Fastlane, não apenas dando o código pronto mas também explicado alguns porquês importantes. Para explorar mais essa ferramenta incrível sugiro que entre em sua documentação oficial.

Espero que tenha aproveitado a leitura, até mais.

--

--