Neste artigo, compartilharei minha experiência de implementação do Release Train para o aplicativo Dodo Pizza (Android e iOS) e os problemas que enfrentamos que fizeram nossa equipe implementar o Release Train.
Se você é líder de equipe/líder técnico de um projeto Android ou iOS que está crescendo rapidamente e ainda não gerenciou o processo de lançamento, espero que nossa experiência o ajude.
O tamanho da equipe ou do aplicativo afeta o processo de lançamento? Bem, isto depende. Vamos imaginar uma startup com uma pequena equipe. Nesse caso, a equipe geralmente faz um recurso e depois é só lançá-lo. Agora, vamos imaginar um projeto grande, por exemplo, um aplicativo bancário, com muitas equipes trabalhando nele.
Nesse caso, provavelmente deveria haver um processo, ciclos de lançamento e talvez alguma burocracia. Sem isso, haverá caos.
Então, quando fica claro que é hora de configurar esse processo para seu aplicativo?
Neste artigo, compartilharei minha experiência de implementação do Release Train para o aplicativo Dodo Pizza (Android e iOS) e os problemas que enfrentamos que fizeram nossa equipe implementar o Release Train.
Se você é líder de equipe/líder técnico de um projeto Android ou iOS que está crescendo rapidamente e ainda não gerenciou o processo de lançamento, espero que nossa experiência o ajude.
Como costumava ser
Em 2021, já usávamos uma abordagem de Desenvolvimento Baseado em Trunk (TBD) em nossas equipes. Cobrimos o código com alternância de recursos, tarefas decompostas e executamos testes de unidade e de IU. Nossas ramificações de recursos não duraram muito e tínhamos o CI funcionando.
O processo de lançamento foi muito simples: quem estava pronto para lançar seu recurso, lançou-o.
Cenário Ideal
Esta é aproximadamente a aparência do fluxo de trabalho de nossa filial. Várias equipes (cinza, azul, laranja e verde) trabalharam em diferentes recursos. Como estávamos trabalhando de acordo com o TBD, cada recurso poderia passar por vários ramos consecutivos.
Por exemplo, a equipe cinza fez sua característica em 4 etapas, as equipes azul e laranja fizeram a sua em 1 etapa e a equipe verde fez a sua em 2 etapas.
Quando uma equipe terminasse um recurso, ela poderia lançar um lançamento. Por exemplo, se a equipe azul terminasse um recurso, eles poderiam fazer um lançamento. Então, a equipe laranja terminaria um longa e faria outro lançamento.
Tínhamos o fluxo perfeito, como parecia então. Funcionou muito bem até certo ponto, mas todas as coisas boas chegam ao fim.
Algo deu errado: difícil, lotado e imprevisível
Mamute
O primeiro problema que encontramos foi que os lançamentos começaram a acumular muitos recursos e ficaram grandes demais.
As equipes nem sempre queriam lançar seus recursos imediatamente. O processo de liberação e regressão foi demorado e levou de 3 a 4 dias. Portanto, se o seu recurso fosse pequeno e não urgente, você nem sempre conseguiria lançá-lo sozinho, porque provavelmente alguma outra equipe faria um lançamento em breve e ele seria incluído nesse lançamento. Aproximadamente parecia assim:
Este era um arranjo bastante frágil, especialmente quando o número de equipas começou a crescer. Muitas equipes desenvolveram muitos recursos pequenos e o volume total de novo código em cada nova versão tornou-se enorme. Quando alguém lançava seu grande filme, tinha que lançar um mamute inteiro junto com ele.
Os lançamentos gigantescos resultaram em:
regressão tardia;
maior risco de bugs de regressão;
maior risco de obter um bug na produção.
Precisávamos fazer com que mesmo que a equipe azul e laranja do exemplo não quisesse liberar, a liberação seria feita de alguma forma.
Gargalos
Cada equipe é única e cada recurso é diferente. Às vezes, as coisas aconteciam de tal forma que várias equipes terminavam seus recursos ao mesmo tempo. Nesse caso, houve muito “espere por mim, vou mesclar amanhã de manhã, prometo!” andando por aí.
No final, esses gargalos resultaram em:
liberações se transformando em mamutes;
lançamentos atrasados afetando negativamente os planos da equipe de lançamento, especialmente se as necessidades de todos os outros forem atendidas.
Precisávamos fazer duas mudanças cruciais:
A equipe de liberação não deveria precisar esperar por ninguém;
todas as outras equipes devem saber quando o próximo lançamento é esperado.
Falta de previsibilidade
Imagine, o time azul fez um pequeno feature e esperava que o time laranja o lançasse em breve. Mas algo deu errado e a equipe laranja também não lançou o lançamento devido a alguns problemas próprios.
Como resultado, a equipe azul disse à empresa que o recurso estaria em produção em breve, mas não foi o suficiente. Como resultado, é impossível prever quando o recurso estará em produção.
Isso não significa que o time azul seja irresponsável. Se eles tiverem um recurso super importante ou urgente, é claro que eles próprios o lançarão. Mas em outros casos, não há como saber exatamente quando o recurso estará disponível para os usuários.
Como você pode imaginar, enfrentávamos esses problemas com bastante frequência. Precisávamos saber exatamente quando os clientes receberiam um recurso em produção, independentemente de seu tamanho ou urgência. Todos os três problemas (liberações gigantescas, gargalos e falta de previsibilidade) estão intimamente relacionados e se complementam.
No entanto, provavelmente o mais fundamental e importante de todos é a falta de previsibilidade. Gera outros problemas.
Trem de liberação
Já estamos fartos; era hora de fazer uma mudança. O Release Train deveria nos ajudar a fazer isso.
O termo Release Train significa coisas diferentes: um ou uma que gerencia o processo de lançamento. Aqui, vamos falar sobre o processo de lançamento agendado.
Gosto da maneira como o Release Train é descrito por Martin Fowler no artigo “ ” e da definição dada pela (talvez pertença a Martin também).
É assim que definimos o Release Train para nós mesmos:
Release Train é o processo de coordenação de lançamentos entre equipes. Todos os lançamentos acontecem em um cronograma fixo, independentemente de os recursos estarem prontos ou não. O trem não espera por ninguém. Se você se atrasar, terá que esperar pelo próximo.
Vamos analisar isso com alguns exemplos usando nossas equipes codificadas por cores.
Resolvendo o problema do mamute
O Release Train acontece dentro do cronograma e não depende de quem fundiu o quê no branch principal. No exemplo abaixo serão divulgadas as funcionalidades dos times azul e laranja. O resto esperará pelo próximo trem. Poderíamos esperar um pouco mais, mas então pegaríamos um mamute.
Resolvendo Gargalos
Ao mesmo tempo, o Release Train nos ajuda a planejar nosso trabalho com mais eficiência. Digamos que a equipe azul planejou originalmente terminar um recurso mais tarde. Mas como todos sabem a data de lançamento, eles podem reorganizar um pouco seus planos para terminar o recurso mais cedo.
Ou, pelo contrário, podem perceber que definitivamente não chegarão a tempo para o próximo trem e, portanto, podem terminar o trecho com segurança, pois conhecem todo o horário.
No exemplo abaixo, a equipe azul queria chegar ao lançamento e mesclar todas as alterações antes do lançamento. Caso contrário, poderia ter havido um gargalo.
Mais importante ainda, o Release Train nos deu previsibilidade desde o design .
Esses exemplos podem parecer óbvios para alguns, mas resolvemos os problemas à medida que surgiram. Quando não houve problemas com lançamentos, não nos preocupamos em usar o Release Train. Quando os problemas se acumularam, percebemos que havia chegado a hora.
Como implementar o Release Train em sua equipe
A primeira coisa que fizemos foi escrever uma . Uma RFC refere-se ao processo em si e ao documento de design que usam antes de começarem a trabalhar em um projeto. Alguns usam RFCs especificamente, alguns usam ADRs e alguns apenas os chamam pelo termo mais genérico Design Doc.
Na Dodo Engineering, usamos RFCs e ADRs.
Nosso processo RFC ficou assim:
Elaboramos um documento RFC;
discutimos o assunto em um pequeno grupo, coletamos comentários e fizemos ajustes;
então a RFC foi comunicada a um grupo mais amplo;
então nós implementamos;
depois disso, coletamos feedback, rastreamos métricas e avaliamos resultados.
A estrutura do documento RFC para nosso Release Train era a seguinte:
descrição do processo de Release Train;
quais equipes estão envolvidas, o que estão fazendo;
qual será o cronograma;
Métricas.
Na elaboração da RFC, contamos com a experiência de outras empresas:
Primeira Implementação
Primeiro, criamos este processo:
lançamento toda semana;
crie um branch de lançamento na manhã de quarta-feira;
completar a regressão e enviar o aplicativo para revisão na sexta-feira;
comece a lançar o lançamento na segunda-feira.
Equipe de lançamento:
1 desenvolvedor iOS e 1 desenvolvedor Android de uma das equipes de recursos;
2 engenheiros de controle de qualidade.
crie um novo branch de lançamento na quarta-feira;
faça um cronograma com um trimestre de antecedência, indicando quando será a vez de cada equipe liberar. Depois de um quarto, reúna-se e estenda o cronograma.
Esquematicamente, nosso Release Train ficou assim:
Nem tudo correu bem
Depois de um mês, ficou claro que, embora a primeira experiência tenha sido ótima,
Foi muito difícil fazer uma regressão toda semana e terminar até sexta;
não havia tempo para hotfixes, e eles às vezes aconteciam.
Em 2021, nosso teste de regressão demorava em média de 3 a 4 dias. Conseguimos encurtá-lo para 2–3 dias em 2022, mas às vezes ultrapassava esse prazo. Continuamos cobrindo casos de regressão com testes e2e, mas ainda não tínhamos 100% de cobertura. Tivemos cerca de 70% e 60% de cobertura de casos de regressão em cada plataforma, respectivamente.
A conclusão disso é que , contanto que os testes de regressão levem alguns dias para serem concluídos, provavelmente será desconfortável executar um ciclo de lançamento toda semana.
A resposta final
Acabamos mudando para ciclos de lançamento de 2 semanas, e o Release Train agora se parece com isto:
liberar a cada 2 semanas;
crie um branch de lançamento na manhã de quarta-feira;
regredir e enviar o aplicativo para análise na sexta-feira;
comece a lançar o lançamento na segunda-feira.
Equipe de lançamento:
1 desenvolvedor iOS e 1 desenvolvedor Android de uma das equipes de recursos;
2 engenheiros de controle de qualidade.
faça um cronograma com um trimestre de antecedência, indicando quando será a vez de cada equipe liberar. Depois de um trimestre, reúnam-se e ampliem o cronograma.
lançar o lançamento gradualmente;
faça os hotfixes se necessário, agora que tivermos tempo para eles;
uma semana depois, na quarta-feira, crie um novo branch de lançamento.
É assim que o processo fica se tudo correr conforme o planejado:
Tudo parece um ciclo semanal, exceto que ainda resta muito tempo para possíveis hotfixes. Esta é a aparência no caso de testes de regressão estendidos:
Também não é grande coisa; ainda há tempo até para hotfixes.
Como o novo processo afetou a previsibilidade?
O principal objetivo para nós era aumentar a previsibilidade . Pode ser dividido em duas partes:
Quando o aplicativo será lançado;
Em qual versão meu recurso entrará?
Respondemos à pergunta “Quando haverá um lançamento?” implementando o processo Release Train. Agora, cada equipe poderá responder à pergunta “em qual versão meu recurso irá parar?” de forma independente no momento em que planejam e avaliam o recurso.
Antes era impossível ter certeza porque outra equipe poderia ou não fazer o lançamento. Agora, tudo depende apenas do planejamento daquela equipe.
Para confirmar isso ainda mais, realizamos pesquisas entre desenvolvedores móveis, controle de qualidade e gerentes de produto, onde, juntamente com outras perguntas, perguntamos:
Quando é o próximo lançamento? (100% responderam a esta pergunta).
O Release Train ajudou você a planejar seu trabalho em equipe? (75% responderam positivamente, mas alguns previram perfeitamente seu trabalho mesmo sem um Release Train).
O Release Train também nos ajudou com congelamentos de código e lançamento. Tivemos vários deles, além do Réveillon (por exemplo, 1º de setembro e alguns feriados). Agora, com o Release Train, não precisamos nos ajustar a essas datas criando ramificações de lançamento, testes de regressão e tudo mais. Libera o trabalho dentro do cronograma; nós apenas os abrimos nas lojas mais tarde.
Impacto nas métricas
Além de apenas resolver problemas, também medimos métricas. Vamos dar uma olhada nos principais.
Tempo de espera
A primeira métrica importante que medimos foi o comprometimento do Lead Time com o lançamento .
Esta é a aparência do gráfico. Marquei o ponto em que iniciamos o processo Release Train com uma seta.
O gráfico mostra que o Lead Time caiu para algo em torno de seis dias. Seis dias é um tempo longo ou curto?
Comparativos de mercado do Google
Há , mas é principalmente para o back-end. Em sua escala, eles distinguem os seguintes grupos:
Elite: menos de uma hora
Alto: 1 hora a 1 semana
Médio: 1 semana a 6 meses
Baixo: 6 meses ou mais
Acredito que, para aplicativos móveis padrão, o prazo de entrega deveria idealmente ser metade da duração do ciclo de lançamento. Isso equivale a mesclar uma tarefa na ramificação principal todos os dias. Dito isto, se o ciclo de lançamento for de 14 dias, o Lead Time deverá ser de 7 dias .
Bugs por regressão
Outra métrica que rastreamos é o número de bugs por regressão. Ele descreve o quão estável é o release candidate. Se a versão anterior foi há muito tempo, provavelmente criamos muitos códigos novos que podem conter um grande número de bugs e podemos gastar mais tempo em regressões e correções.
A certa altura, essa métrica caiu para três bugs. Os números específicos não são tão cruciais, mas no geral, você pode ver que a tendência diminuiu.
Mais métricas
Discutirei brevemente quais métricas também foram monitoradas como parte do Release Train.
Livre de falhas. Sempre ficamos de olho nessa métrica. Havia a hipótese de que cairia devido às nossas tentativas de enquadrar a regressão em um prazo mais apertado. Bem, nenhuma queda aconteceu.
Ficamos nos perguntando se lançamentos frequentes (semanais) teriam impacto na rotatividade de clientes e na exclusão do aplicativo. Como resultado, não detectamos nenhum impacto.
Implementar, melhorar
Gostamos do processo actual porque pensamos que atingiu os seus objectivos. Também sabemos como melhorá-lo ainda mais:
Continuamos trabalhando na automatização da regressão para torná-la mais simples e rápida.
Até o momento deixamos de fora a parte de automação de trabalho (scripts para ramificação), mas isso também seria um grande ponto de crescimento no futuro.
Nosso aplicativo funciona em 20 países e precisamos traduzi-lo para vários idiomas diferentes. Existe um serviço interno para isso, mas os desenvolvedores ainda precisam participar desse processo manualmente antes do lançamento. Automatizar esse processo pode melhorar ainda mais o ciclo de lançamento.
Resumo
Embora fôssemos relativamente pequenos, não precisávamos de um Release Train. Quando nos deparamos com o fato de que não podíamos prever os lançamentos, seu tamanho e número, decidimos implementar o Release Train. No início, tentamos ciclos de lançamento semanais, mas devido às regressões demoradas, tivemos que mudar para ciclos de lançamento de duas semanas. Temos vivido assim desde então.
Agora, temos previsibilidade de lançamentos e as métricas mostram dinâmica positiva. Pretendemos aumentar a cobertura de casos de regressão com testes e2e, automatizar o processo de trabalho com filiais e otimizar o processo de traduções.
Espero que este artigo e nossa experiência ajudem você, principalmente se você já enfrentou problemas semelhantes e eles fizeram você pensar no processo de lançamento. Muito obrigado por ler meu artigo. Espero que tenha gostado. Se você tiver alguma dúvida ou sugestão, deixe-me uma mensagem nos comentários e com certeza lerei!
E . Normalmente eu posto sobre desenvolvimento Android e engenharia de software em geral.