Evite que os galhos se acumulem

19

Estamos começando a encontrar um problema à medida que aumentamos, onde os recursos chegam à preparação para testes, mas quando tudo é testado e os novos recursos aprovados estão prontos para teste.

Isso está criando um ambiente no qual quase nunca podemos avançar para a produção porque temos uma combinação de recursos testados e não testados. Tenho certeza de que esse é um problema comum, mas ainda não encontrei bons recursos para nós.

Alguns detalhes:

  • GIT no BitBucket
  • Jenkins para implantação com script no Azure

O que eu espero é uma maneira de isolar os recursos à medida que eles se movem pelos ambientes e apenas empurram o que está pronto para produzir.

Wesley
fonte
1
Você está ramificando para cada recurso ou está enviando alterações de recursos diretamente para a ramificação do servidor de teste?
21816 Robert Harvey
1
Sem informações sobre como você gerencia recursos e ramificações, não podemos dar uma resposta específica aos seus problemas.
precisa
2
Você trabalha com iterações de alguma maneira (por exemplo, sprints de duas semanas ou lançamentos com versão)?
RemcoGerlich
@RobertHarvey: Estamos ramificando para cada recurso, mas temos uma ramificação Dev, Stage e Prod na qual nos fundimos, que cria e implanta automaticamente essa ramificação na mesclagem.
23416 Wesley
@RemcoGerlich: Trabalhamos em três semanas de corridas no momento, mas com oito desenvolvedores não há garantia de que o progresso que fazemos a cada ciclo seja perfeito em todos os aspectos.
23416 Wesley

Respostas:

22

Parece que você tem alguns problemas aqui:

1. Identificando recursos para uma liberação específica

Este é um problema de gerenciamento de projetos e um problema de coordenação. Será que este recurso ser liberado antes, ao mesmo tempo que, ou após este outro recurso? Se as liberações quiserem um recurso por vez, identifique-o. Se os recursos forem agrupados em lançamentos, descubra quais são os agrupamentos e aplique-os aos desenvolvedores e aos tomadores de decisão. Use seu sistema de rastreamento ou emissão de tickets para marcar lançamentos. Deixe claro que, se um dos recursos de uma versão específica não for possível, todos eles serão.

2. Estratégias de ramificação

Git-flow é a resposta fácil para questões como essas, e muitas vezes as pessoas usam uma variante do git-flow, mesmo que não saibam o que é. Não vou dizer que é um problema para todos os problemas, mas ajuda muito.

Parece que você está enfrentando um problema com estratégias de lançamento não determinísticas, em que os recursos são aprovados em dispersão e algo que iniciou o desenvolvimento há muito tempo pode ser lançado depois de algo iniciado mais recentemente - recursos de salto em distância.

Ramificações de recursos de longa duração ou ramificações de versão simultânea são provavelmente a melhor resposta para esses tipos de problemas. Mesclar (ou refazer, se você estiver confortável com isso) o mais recente do mestre em seus ramos de longa duração. Cuidado para mesclar apenas os recursos que já estão ativos, caso contrário, você encontrará os problemas que está enfrentando agora (muitos recursos misturados em uma ramificação).

As ramificações "Hotfix" ou "bugfix" são uma parte essencial desse processo; use-os para pequenas correções pontuais que possuem um ciclo curto de controle de qualidade.

Pela sua descrição, talvez seja melhor não manter um ramo de 'desenvolvimento' oficial. Em vez disso, ramifique todos os recursos do mestre e crie ramificações de release mescladas assim que um release for identificado.

3. Ambientes

Não combine as ramificações git com seus ambientes, exceto a produção == master. O ramo 'desenvolvimento' deve ser considerado quebrado. As ramificações de liberação são enviadas para ambientes de teste, seja um ambiente de controle de qualidade ou um ambiente de preparação. Se necessário, envie uma ramificação de recurso específico para um ambiente.

Se você possui mais de uma ramificação de recursos que precisam ser liberadas separadamente, mas estão sendo testadas ao mesmo tempo ..... ¯ \ _ (ツ) _ / ¯ .... gerencie outro servidor? Talvez junte-os em uma ramificação descartável ... confirme correções / alterações nas ramificações originais e junte novamente na ramificação descartável; faça a aprovação final e o UAT em ramificações de liberação individuais.

4. Removendo recursos não aprovados de uma ramificação

É isso que os pensamentos acima estão tentando evitar, porque essa é sem dúvida a coisa mais dolorosa a se fazer. Se você tiver sorte, os recursos foram mesclados em suas ramificações de desenvolvimento ou teste atomicamente usando confirmações de mesclagem. Se você não tiver sorte, os desenvolvedores se comprometeram diretamente com o ramo de desenvolvimento / teste.

De qualquer forma, se você estiver se preparando para uma liberação e tiver alterações não aprovadas, precisará usar o Git para recuperar as confirmações não aprovadas do ramo de liberação; a melhor idéia é fazer isso antes de testar o lançamento.

Boa sorte.

Jen
fonte
NB: por "ciclo curto de controle de qualidade" para ramificações de hotfix, estou falando sobre algo que será enviado à produção dentro de um dia, basicamente. Emergências. Algumas pessoas não as usam dessa maneira, mas é isso que eu e minha equipe fazemos e parece funcionar bem para nós.
21916 Jen
anúncio 1: a pergunta tem uma tag de "integração contínua", então acho que o OP quer liberar recursos imediatamente para produção depois de testados (o suficiente). Portanto, o resultado do teste pode controlar a ordem de liberação para produção, o que é um pouco contrário à sua recomendação.
Doc Brown
... no entanto, acho que é uma resposta muito boa.
Doc Brown
Concordo - removi o bit "pedido" da primeira seção. Eu acho que "ordem" é menos importante do que identificar lançamentos. Se o objetivo é o IC, manter os recursos distintos para testes e versões é definitivamente mais importante do que manter um cronograma.
21916 Jen
Normalmente, eu também não recomendaria isso - mas a pergunta foi feita especificamente sobre a tentativa de gerenciar código onde certos recursos não foram testados e não foram aprovados. Raramente trabalho em projetos que têm tanta incerteza sobre quais recursos serão lançados quando - geralmente o cronograma de lançamento é bastante planejado, e um atraso em um lançamento atrasaria o próximo também. O que você faria em vez disso?
21916 Jen
4

Aqui está uma idéia: Pare de usar os ramos de lançamento. Em vez disso, comece a criar alternâncias de recursos e gerenciá-lo através da configuração. Dessa forma, você está sempre mesclando ramificações de recursos no mestre e nunca deve haver uma pergunta sobre qual versão está em teste ou prod. Se você tiver alguma dúvida sobre quais recursos / implementações estão ativos em um ambiente, basta verificar o arquivo de configuração.

Pato de borracha
fonte
3

Isso deve ser uma simples questão de coordenação entre teste e produção. Se você estiver usando ramificações de recursos no Git, simplesmente pare de enviar ramificações de recursos concluídas para Teste durante um ciclo de teste e continue quando o teste estiver concluído.

Se você precisar de um controle melhor do que isso, separe o Teste em um servidor de Desenvolvimento e um servidor de Teste de Aceitação e coordene as ramificações que serão enviadas ao servidor de Teste de Aceitação com a equipe de teste. Alguém pode ser responsável por iniciar a implantação final do Teste de aceitação para a produção.

Robert Harvey
fonte
2

O trabalho empilha-se

Este é um problema universal na minha experiência. Dirijo-me com:

  • Forte gerenciamento de lançamentos de recursos pelo proprietário do produto
  • Verifique se as ramificações são excluídas quando são mescladas
  • Limitar o trabalho em andamento (com limites de coluna em Jira)
  • Revisão trimestral de tickets antigos que estão definhando, tanto bugs quanto recursos
  • Retrospectivas para discutir os componentes da questão
  • Incentivo constante à revisão de códigos por todos
  • Oportunidades de emparelhamento para enfrentar tíquetes e problemas de longa data
  • Reuniões trimestrais para revisar e limpar tickets antigos
  • Abordagem da equipe para obter desenvolvedores, produtos e QA / QE trabalhando juntos
  • Bons relatórios e ferramentas para tornar óbvios os novos recursos do produto e o backlog
  • Revise as sessões para passar por ramificações antigas e excluí-las
Michael Durrant
fonte
2

Ramos

Você precisa de algumas ramificações para controlar esse processo:

  • característica : estes ramos nascem do mestre. Use algum aplicativo de gerenciamento de projetos para identificar cada ramificação de recurso com alguma tarefa. Por exemplo, se você usar TRAC, você vai acabar se ramos como: 1234-user-crud, 1235-bug-delete-catalog, etc. Identificar seus commits com o número de tarefa demasiado, isso vai ajudá-lo muito quando você tem problemas em fusões (você).
  • teste : todas as ramificações de recursos concluídas serão mescladas à ramificação de teste. Você nunca mescla a ramificação de teste em alguma ramificação de recursos , porque não deseja código de outros recursos que não estão na produção (mestre). O mesmo é válido para a releaseramificação.
  • release : quando você decide quais recursos testados podem estar na produção, mescla essas ramificações (novamente ...) nesta ramificação. Você precisa testar todos os recursos novamente, porque essa mesclagem pode trazer novos problemas. Quando a liberação é testada e concluída, você mescla essa ramificação para dominar e cria uma tag no mestre para a versão.
  • master : contém apenas o código de produção.

Veja o fluxo git:

                              |FEAT_2|
                                  |
                             .---C06<-------.---------.
                            /                \         \
                           /   |FEAT_1|        \         \
                          /       |            \         \
                         /    .--C07<--.--------\---------\---------.
                        /    /          \        \  |TEST| \         \
                       /    /            \        \    |    \         \
                      /    /        .-----`--C09<--`--C10    \         \ |RELEASE|
                     /    /        /                          \         \    |
    <v4.6.0>        /    /        /                       .----`--C11<---`--C12<--.
       |           /    /        /                       /                         \
C01<--C02<--C04<--´----´--------´-----------------------´---------------------------`--C13
 |           |                                                                          |
<v4.5.0>  <v4.6.1>                                                                   |MASTER|
                                                                                        |
                                                                                     <v4.7.0>

Ambientes

Muito simples:

  • teste : esse ambiente usa a ramificação de teste.
  • release : esse ambiente usa o ramo de release real.

Os desenvolvedores trabalham em sua máquina, cada um usando seu próprio banco de dados. Se não for possível, cada desenvolvedor possui um banco de dados individual (por causa de licenças, tamanho do banco de dados, etc.), haverá muitos problemas ao compartilhar um banco de dados entre os desenvolvedores: quando alguém exclui uma coluna ou tabela em sua filial, os outros ramos ainda conta com esta coluna / tabela no banco de dados.

Problemas

O maior problema nesse processo é a mesclagem.

Você precisa refazer as mesmas mesclagens em teste release. Isso será doloroso se um bom refatoramento for feito no código, como excluir uma classe, mover / renomear métodos etc. Como você não pode obter código da ramificação test(ou release) na ramificação do recurso, as confirmações de mesclagem podem ser resolvidas apenas em o test(ou release). Então, você acaba resolvendo os mesmos conflitos em duas ramificações diferentes, provavelmente produzindo código diferente em cada mesclagem e, no futuro, descobrirá que a equipe de teste precisará testar os recursos duas vezes: nas ramificações teste release, porque cada mesclagem pode resultar em diferentes erros.

Outro problema é o testramo. Você precisará "reciclar" este ramo (excluir e criar um novo master) periodicamente, porque alguns ramos antigos (ou mesclagens antigas, filiais mescladas que foram excluídas) podem trazer muitos problemas para o novo código, divergindo muito do que está dentro master. Nesse momento, você precisa do controle de quais ramificações você gostaria de mesclar novamente no arquivo test.

A melhor solução é que a equipe de negócios saiba o que precisa ser entregue na próxima versão e todos trabalhem em um ramo único (ramo de desenvolvimento). É bom para eles a possibilidade de escolherem o recurso "pronto" que gostariam de ter na próxima versão a qualquer momento que desejarem (acho que esse é o seu cenário), mas esse é um pesadelo para os desenvolvedores e (acredito) para o equipe de teste.

Dherik
fonte
@DownVoter, por quê?
Dherik
0

Parece que você está mesclando alterações do seu ramo de integração no seu ramo de produção, o que IMHO não é uma boa prática, exatamente pelos motivos mencionados. Assim que um ramo de produção para um determinado release é retirado do ramo de integração principal, o ramo de integração pode, a qualquer momento, divergir (afinal, ele deve evoluir para o próximo release). A mesclagem do ramo de integração no ramo de release atual pode trazer alterações incompatíveis com esse release.

IMHO um processo adequado seria:

  • puxe um ramo de produção do ramo de integração somente quando for considerado próximo o suficiente do nível de qualidade desejado, para que apenas algumas mudanças sejam esperadas para concluir o lançamento. Em outras palavras, a conclusão do recurso deve ser avaliada (continuamente) no ramo de integração, antes de puxar o ramo de produção.
  • depois que o ramo de produção é puxado, apenas as mudanças escolhidas são trazidas, tratadas como alterações autônomas / correção de pontos - ou seja, verificadas se elas realmente funcionam como o esperado (apenas porque uma alteração funciona em um ramo não significa necessariamente que também funciona) em outro ramo).
Dan Cornilescu
fonte
0

Pessoalmente, isso pode parecer um problema de processo mais do que um problema de ferramentas. Algumas coisas que eu sugiro aqui:

  • Não tenho certeza se você tem grupos separados de desenvolvimento e controle de qualidade. Se o fizer, verifique se o Dev e o QA participam das reuniões de planejamento e estimativa do sprint. Em uma das minhas empresas anteriores, garantimos que o número de pontos da história que atribuímos fosse responsável pelos esforços de desenvolvimento e teste. (Você também pode, teoricamente, ter duas estimativas separadas para o esforço de desenvolvimento e controle de qualidade, mas de qualquer maneira é necessário que sua estimativa inclua as duas; o tempo necessário para uma história é o tempo necessário para realmente entregá-la). Mesmo se você não tiver um grupo de controle de qualidade separado, inclua o esforço de teste em suas estimativas.
  • Da mesma forma que acima, concorde com antecedência em quantas histórias você incluirá em um sprint específico. O número de pontos da história que você aceita baseia-se na quantidade que seus desenvolvedores podem concluir no sprint e no número de itens que o controle de qualidade pode testar no sprint. (Suponho, é claro, que os sprints de controle de qualidade estejam por trás dos sprints de desenvolvimento, mas você pode adaptar isso ao seu processo). Se seus desenvolvedores podem terminar 200 pontos da história, mas seu controle de qualidade só pode terminar 150 pontos da história, obviamente você pode fazer 150 pontos da história antes que o trabalho comece a "acumular" e você termine com um caso como o que você descreve. (Em um caso como esse, convém investigar a causa do bloqueio para tentar mitigá-lo).
  • Ninguém envia nada ao controle de qualidade até que tudo o que está atualmente no controle de qualidade seja testado e entregue .
  • Um recurso completo é aquele que foi testado e entregue. Se não for entregue, não será feito.
  • Obviamente, você deseja tentar fazer isso em algum tipo de horário fixo. Uma das idéias por trás da Integração Contínua e do Agile é a iteração. Por definição, a iteração envolve entrega frequente. Integrações e entregas frequentes minimizam o risco de cada uma.

Honestamente, acho que a maior coisa será disciplina quando você estiver entregando e quantas tarefas você pode realmente concluir completamente em um determinado período de tempo.

Para resumir: entregue apenas ao controle de qualidade quando terminar de testar e fornecer os recursos antigos.

EJoshuaS - Restabelecer Monica
fonte
-2

Quando "tudo for testado e aprovado", implante o que foi testado e aprovado para produção. Isso pode ser um commit específico ou um artefato de construção específico gerado por Jenkins.

Não importa que confirmações posteriores no mesmo ramo ainda não tenham sido testadas.

bdsl
fonte
1
Certamente importa que as confirmações posteriores na mesma ramificação não tenham sido testadas e aprovadas - implantar código na produção que não foi testada é uma maneira infalível de obter um cliente irritado.
23416 Jen
Não estou sugerindo que as confirmações posteriores sejam implantadas. Estou dizendo para deixar os commits posteriores em paz, implantar o que foi testado.
bdsl
Em outras palavras, ignore as ramificações, tome a decisão de implantação com relação a confirmações individuais ou construções individuais.
bdsl