Solte o trem. Relatório Yandex

Os processos de liberação em diferentes equipes Yandex (e em qualquer grande empresa de TI) são organizados de maneira semelhante, mas diferem em muitos detalhes. Os desenvolvedores de dispositivos móveis têm suas próprias especificidades: seus lançamentos são afetados pela ordem do layout na App Store e no Google Play. Desenvolvedor Android Dmitry PolyakovDmpolyakov Ele falou sobre os processos ao seu redor - como sua equipe envia um trem de lançamento dentro do cronograma, como lançar lançamentos não programados, adicionar carros a um lançamento já deixado e o que fazer para permanecer na pista.


Olá pessoal, sou Dmitry Polyakov, desenvolvedor Android do aplicativo móvel que uso.



Agora, em duas equipes - desenvolvimento para Android e iOS - 13 pessoas cada. Isso nos permite realizar muitas tarefas legais em paralelo e enviá-las rapidamente aos usuários. No relatório, vou contar como aprendemos a trabalhar com o git e a viver em um repositório.

A seguir, mostrarei como nosso ciclo de lançamento funciona. Os gerentes vêm até nós e dizem que queremos implementar esse recurso o mais rápido possível. Então, provavelmente, qualquer gerente quer, então montamos o processo de lançamento para irmos à App Store e ao Google Play toda semana. Também vou falar sobre as ferramentas que temos e que eu recomendaria que você experimentasse, elas são legais.

Fluxo Git


Vamos começar com o Git Flow. Como base, adotamos o clássico Git Flow, no entanto, ele mudou muito nas nossas condições, na nossa equipe. Você parece também, e talvez algo disso sirva para você, mas algo não. Cada equipe tem sua própria abordagem para trabalhar com o git.

Como isso funciona conosco? Epic é o ramo raiz do seu recurso, para algumas ótimas funcionalidades. Para deixar mais claro, vejamos imediatamente o exemplo do produto.



O gerente vem e diz - o desenvolvedor, nos torna a funcionalidade da lista de desejos com os produtos selecionados no aplicativo. O desenvolvedor inicia uma nova epopeia da ramificação e a chama de lista de desejos.



Além disso, ele o decompõe em tarefas menores, que começam no rastreador. Talvez isso esteja funcionando com a rede, renderizando a interface do usuário, escrevendo testes. Para cada um desses recursos, ele inicia uma tarefa no rastreador. E assim que ele começa a concluir a tarefa, ele inicia o ramo de recurso correspondente. Brunches ela do mesmo épico.

Assim que ele termina o trabalho em um desses recursos, ele o derrama no épico através da solicitação de pool. A solicitação de pool é esse mecanismo quando outros desenvolvedores da sua equipe verificam seu código. Se eles não gostarem de algo, seu código poderá não chegar ao seu épico, o que significa que você não será liberado até encontrar um acordo com eles.

Existem dois desses revisores em nossa equipe. Eles são atribuídos aleatoriamente. Este é um processo automatizado, que seleciona os desenvolvedores que trabalharam recentemente com os mesmos arquivos que você alterou em sua solicitação de pool.



Assim, acontece que vários épicos com seu próprio conjunto de recursos vivem no projeto em paralelo. Um épico pode ter apenas um recurso. Isso pode acontecer se quisermos fazer o upload desse recurso por meio da solicitação de pool para épico.



Assim que o trabalho em todos os recursos de uma epopeia é concluído, a tarefa primeiro é deixada para a equipe de teste, a equipe de controle de qualidade e eles testam funcionalmente a ramificação. Depois que eles encontrarem erros, você os editará como parte deste épico. Uma vez que todos os bugs foram corrigidos, você preenche esse épico em desenvolvimento Aqui, nenhuma revisão de código adicional já é realizada por sua equipe, porque todo o código já foi analisado durante o estágio de congelamento de recursos em épico.

Nosso desenvolvimento é um ramo no qual o código já testado visita, porque no estágio épico ele é testado e o código passou pela solicitação de pool.



Isso nos permite criar com segurança uma nova ramificação de lançamento no início do ciclo de lançamento. Sem medo de que haja muitos bugs que ainda não foram testados. Portanto, estamos criando um novo ramo de lançamento a partir do desenvolvimento, ele está sendo testado. Assim que a versão for testada e estivermos prontos para deixar o portal ainda mais, esse ramo se fundirá no master.

Às vezes, temos hotfix e há um tipo de ramificação separado para ele. Esta é uma versão muito curta que precisa ser lançada rapidamente. Não temos tempo para esperar três ou quatro dias para o próximo ciclo de lançamento. Geralmente isso é algo pequeno.

Por exemplo, se algum tipo de bug entra em produção e é muito crítico, precisamos corrigi-lo com urgência. Portanto, paramos a versão atual, executamos o hotfix nesse bug e atualizamos nossa versão. Mas o hotfix nem sempre é uma história sobre bugs. Às vezes, temos uma necessidade de produto.



Por exemplo, assim que o modo de auto-isolamento foi introduzido em Moscou, tínhamos uma necessidade de produto para que os usuários pudessem solicitar produtos sem contato. Agora, ao fazer um pedido em nosso aplicativo, o usuário pode selecionar a função "Deixar na porta". O correio chega, deixa o pacote embaixo da porta e o entrega sem contato.

Com esta tarefa no hotfix, também incluímos widgets tão diferentes que exigem que você fique em casa e encomende mercadorias por correio. Não vá aos pontos de coleta agora. Implementamos essas tarefas por meio do hotfix para que possamos transmiti-las ao usuário o mais rápido possível, porque as consideramos importantes.

Quando temos hotfix, fazemos o brunch do mestre. Desde o desenvolvimento, ele não pode ser aproveitado, porque naquele momento o novo poderia se tornar épico, que ainda não havia sido lançado. Mas não queremos levar esses épicos conosco para o hotfix, para que eles não nos afetem aleatoriamente e bloqueiem nosso hotfix. Após a conclusão do hotfix, injetamos no master e também o adicionamos ao desenvolvimento, pois esse código ainda não existia no desenvolvimento.



Mestre é uma base de código correspondente à versão mais recente do aplicativo, que está agora na loja do usuário. É limpo, sem erros, porque os testes funcionais e de regressão já passaram por lá, este é um ramo de backup.

Quando nosso lançamento é concluído, também o devolvemos ao desenvolvimento. Como parte da versão, podem ser encontrados erros que não foram encontrados nos testes funcionais, e épicos diferentes podem entrar em conflito entre si. Portanto, também injetamos a liberação no develop para que também tenhamos essas correções.



Muito trabalho pode ser feito em épico e, para acompanhar o código em desenvolvimento, o desenvolvedor às vezes o adiciona ao seu épico, para que haja menos conflitos de congelamento.



Desde que adicionamos o desenvolvimento ao épico, o épico pelos mesmos motivos precisa ser adicionado ao seu recurso.



Nos nomes de ramos épicos e de recursos, temos um número de ticket no rastreador de tarefas. Isso é legal, porque é precisamente pelo número do ticket que podemos descobrir completamente de qualquer parte de nosso aplicativo, dentro do qual os tickets foram alterados, quem escreveu esse código e com que finalidade ele foi escrito.



A ramificação release e hotfix possui em seu nome o número da versão atual do aplicativo. Algumas equipes combinam o número do hotfix com o número da versão, justificando isso dizendo que o hotfix é algo pequeno e, talvez, não muito importante para o usuário. Portanto, eles não aumentam a versão do aplicativo. Não usamos essa abordagem, porque vários relatórios de falhas dos fabricantes chegam até nós e queremos entender exatamente se esse relatório está em hotfix ou no release, para saber onde procurar o problema.



Dominar e desenvolver são ramos que vivem constantemente em nosso repositório. Uma vez criado, e viva. Portanto, eles são nomeados de forma sucinta.

É assim que vivemos. Agora estamos confortáveis, convenientes.

Liberar trem


Passamos para nossos processos de liberação. Mas antes de falarmos sobre os lançamentos e como os construímos, falarei sobre os papéis que temos para apoiar o lançamento.

Temos um desenvolvedor de plantão que, em uma semana útil, deixa de lidar com as tarefas do produto e corrige os erros da versão atual. Se ele não tiver mais tarefas para a versão atual, ele corrigirá algumas dívidas técnicas que acumulamos, retira tarefas da lista de pendências e as corrige.

Há também um testador de plantão. Ele também para de testar as tarefas do produto em uma semana útil e verifica a versão atual. Se ele não tiver tarefas para a versão atual, ele testa o que foi corrigido como parte da dívida técnica.



O lançamento começa na sexta-feira. É neste dia que temos um prazo rígido. Às 18 horas da noite, o testador de serviço clica no botão "Iniciar Liberação". Após esse momento, tudo o que será despejado no desenvolvimento não cairá mais na versão atual, porque após clicar no botão, uma ramificação de versão foi criada, a adição foi adicionada e a versão mais não será despejada lá.

Outro processo importante está ocorrendo na sexta-feira, outro item do release atual, que discutirei mais adiante.



Nós temos um descanso nos finais de semana, então o segundo dia de lançamento é segunda-feira. O desenvolvedor de plantão começa o dia com uma análise. Ele está olhando para o que foi alterado na versão atual em termos de código. Leva git diff entre a ramificação de versão atual e o mestre. E por essa diferença, ele analisa quais componentes foram afetados. Isso pode afetar o processo de checkout ou a cesta, e o trabalho com pedestais não é afetado.

Assim, ele forma uma lista de vários casos que serão testados durante o teste. Isso nos ajuda a acelerar nossa regressão, verifique não o aplicativo inteiro. Quando a lista é compilada, a equipe de teste verifica o aplicativo e o desenvolvedor de plantão corrige os bugs. Se ele tiver muitos bugs, ele poderá delegar parte para outros desenvolvedores que trabalharam recentemente com esses trechos de código.



Na terça-feira, continuamos testando nossa versão e corrigindo bugs. No final da tarde, nossos testes de regressão terminam e estamos prontos para partir para o portão. Lançamos nosso trem de liberação - na verdade, até vários trens de liberação, porque recentemente entramos em um novo mercado para nós. Também recomendo que você tente publicar não apenas no Google Play, mas também em alguns outros. A vantagem não é apenas o fato de você ter um novo público fiel.

De alguma forma, publicamos nossa versão e, após algumas horas, descobrimos que o número de bugs entre os usuários aumentou significativamente. Analisamos esses bugs, analisamos e vimos que eles ocorrem apenas em dispositivos Huawei. Não entendemos imediatamente o que estava acontecendo, mas tínhamos a Huawei, testamos, encontramos um bug, corrigimos e atualizamos.

Assim que chegamos com a atualização no Google Play, vimos um banner grande, que dizia que, devido à situação atual no mundo, o Google Play tem uma carga muito pesada e eles não têm tempo para verificar os aplicativos o mais rápido possível. Descobrimos que ainda não tínhamos tempo para verificar nosso aplicativo, não alcançamos os usuários do Google Play, mas fomos publicados apenas na Huawei AppGallery. E essa foi a razão pela qual tivemos bugs apenas na Huawei. Assim, foi possível detectar e corrigir um erro crítico antes de publicar no Google Play.

Em seguida, mostrarei como as publicações são organizadas por meio do Google Play, porque temos uma parcela muito grande de usuários lá. E na Huawei AppGallery, saímos recentemente e ainda estamos tentando entender como tudo está organizado lá.

Não publicamos imediatamente para todos os usuários no Google Play, para que algum tipo de erro aleatório não afete todo o público. Publicamos apenas para todos os testadores que concordam com o fato de que podem ter um bug, mas serão os primeiros a receber nossas alterações e lançamentos. Além disso, publicamos apenas cinco por cento da audiência.



Na quarta-feira, o desenvolvedor de plantão está assistindo a um novo lançamento sem falhas. É importante para nós que não haja novos acidentes e que não haja muitos acidentes antigos. Se tudo estiver normal, ele ainda verifica as métricas do produto. Por exemplo, para que o número de pedidos não caia em comparação com o mesmo período. Se nossas métricas de produtos e sem falhas forem boas, lançaremos outros 5%, um total de 10%.



Na quinta-feira, o desenvolvedor de plantão verifica os comentários na loja. Na verdade, ele os assiste na quarta-feira. É verdade que na quarta-feira ainda temos uma pequena audiência, uma ou duas críticas. Mas na quinta-feira há mais críticas para julgar o lançamento. Pode haver 10-15 peças.

Por que ele olha as avaliações se temos muitas métricas e gráficos? O aplicativo pode não falhar, mesmo as métricas podem estar em ordem. Mas é possível que o usuário tenha fontes ou talvez algum filtro não funcione para ele. Tentamos fazer o uso do aplicativo para o usuário o mais conveniente possível e analisamos tais análises, bugs ou problemas corretos que o usuário encontra.

Se as revisões estiverem em ordem, a ausência de falhas também é normal e as métricas do produto não caíram, já estamos lançando 20%.



E assim começa sexta-feira, o dia do lançamento de nosso lançamento. O terceiro ponto que eu queria falar é que na sexta-feira concluiremos o lançamento atual. Nós passamos de 20% para 100% imediatamente. Parece ser um salto muito grande e muito arriscado. Mas isso depende da equipe e do seu público.

20% de nosso público nos permite com alta probabilidade julgar a estabilidade do lançamento. E se tudo estiver bem em 20% e na sexta-feira não tivermos problemas, iremos direto para o centésimo.

Conheço as equipes que usam o hacker no Google Play - talvez ele também o ajude. Você pode lançar não em 100%, mas em 99,9%. Isso deixará você com um botão no Google Play para interromper com urgência o lançamento. E se você lançar 100%, esse botão desaparecerá. Mas, como eu disse, por vinte por cento da nossa audiência, podemos julgar com precisão a estabilidade do lançamento. Portanto, lançamos calmamente para 100%, o que nos salva de etapas adicionais. E então você precisa rolar outros 0,01%.

Este é o nosso processo, por isso pedalamos toda semana e tentamos não nos perder.


Que outras ferramentas temos para apoiar a boa vida do usuário ao seu lado? São atualização forçada, atualização suave e alternância de recursos.



Forçar atualização - um mecanismo que bloqueia o uso do aplicativo se sua versão estiver muito desatualizada. A versão considerada obsoleta é configurada no painel de administração do servidor. E assim que o número for alterado lá, alguns aplicativos terão uma caixa que não permitirá que você vá. Só haverá um botão Atualizar, o usuário será forçado a atualizar.

Tentamos usar esse mecanismo o menos possível, mas às vezes é muito importante. Por exemplo, se quebrarmos a compatibilidade com versões anteriores, lançamos um novo recurso que não é suportado no código antigo. Em seguida, o usuário da versão desatualizada do aplicativo pode acabar em um estado inconsistente. Ele irá para a cesta e, por exemplo, ele não terá um pedido. Ele não entenderá o porquê, embora na nova versão todos os erros sejam registrados e fique claro por que não é possível fazer um pedido.



Para ajudar a Forçar atualização, existe o Soft Update. Isso é algo nativo do Google, que é simplesmente incorporado ao seu aplicativo e não impede o uso. Mas ela diz - há uma atualização no Google Play, instale-a e você terá novos itens interessantes.

Inicialmente, é implementado por esse diálogo. Este é um design nativo do Android. E então ele pode ser incorporado ao seu aplicativo. Por exemplo, o implementamos em nosso widget "Atualizar o aplicativo" em nosso esquema de cores.

O Soft Update nos permitiu reduzir bastante a cauda das versões e é implementado simplesmente de acordo com a documentação. Experimente se você tiver muitos lançamentos.



Outra ferramenta importante é a Alternância de recursos. Permite ajustar parte da funcionalidade no lado do usuário, alterando-a no painel de administração. Há um conjunto de recursos que podemos ativar e desativar em nosso servidor sem atualizações adicionais de aplicativos.

Vamos falar sobre como o recurso Alternar funciona no exemplo de um aplicativo de terceiros - um veículo. Inicialmente, os desenvolvedores têm exatamente essa bicicleta, que já possui dois Feature Toggle: um motor e um tamanho grande. Os clientes usam a bicicleta e a equipe de teste diz: testamos o motor, ele funciona, dirige, esfria, vamos ligá-lo para o usuário.



Vamos ao painel de administração, ativamos o recurso Alternar e a bicicleta sem atualizar o usuário; em qualquer lugar, ele se transforma em um ciclomotor. O usuário está confortável, isso permite que ele se mova mais rápido e mais conveniente.

O produto está em desenvolvimento, o público está crescendo, não cabe mais em um ciclomotor. Os usuários querem levar a família com eles, andar juntos. Os desenvolvedores e gerentes forneceram uma alternância de recursos adicional - um tamanho grande. Nós o ativamos no painel de administração e o veículo do usuário fica maior em movimento.



Parece legal: o recurso Alternar nos ajuda. Isso é verdade, mas há problemas que você pode encontrar. Por exemplo, você precisa monitorar a compatibilidade com versões anteriores e a compatibilidade de alternância de recursos. Suponha que, em algum momento, o aplicativo quebre o motor, ocorra um acidente ou um bug. Ou esse motor consumirá muitos de nossos recursos e não poderemos oferecer suporte a muitos usuários com o motor. Então temos que desligá-lo.

Mas não queremos que o aplicativo do usuário desapareça. Queremos dar a ele a oportunidade de usar o aplicativo, apesar de ele ainda ter um Toggle com um tamanho grande. Portanto, quando desligamos o motor, precisamos ter um mecanismo de segurança para controlar o veículo. Neste caso, este é um híbrido.



Talvez valesse a pena considerar que o telhado reclina. Talvez o motorista não se sinta à vontade para se sentar em um banco desses. Mas ele ainda será capaz de dirigir um veículo, usar o aplicativo e não andar.

De que outra forma usamos o recurso Alternar? Suponha que os back-end ainda estejam sendo desenvolvidos e não estejam prontos para lançamento. Em seguida, podemos desenvolver parte da funcionalidade, oferecer suporte ao contrato de API para todas as comunicações com o back-end, suportar a interface do usuário e implementar com a alternância de recursos desativada. Assim que os back-end estiverem prontos, testaremos se tudo funciona bem e, se houver, habilitaremos a alternância de recursos. Em seguida, o usuário não precisará ser atualizado para obter novos recursos. Ou seja, já teremos uma audiência, apareceremos imediatamente nessa audiência. Tão bom também.



Agora, como eu já disse, temos 13 pessoas em cada uma das equipes de desenvolvimento para Android e iOS. Trabalhamos em um Git Flow, em um repositório, configuramos nosso processo de lançamento planejado, reduzimos o tempo de lançamento no mercado e rodamos toda semana. Lançamos recentemente o Huawei AppGallery e consultamos outras lojas. Aprendemos como alterar aplicativos de usuário sem atualizações devido à alternância de recursos. Obrigado pela atenção.

All Articles