Monorepositórios: por favor

imagem


Uma tradução do artigo foi preparada para os alunos do curso DevOps Practices and Tools no projeto educacional OTUS .




Você deve escolher um mono-repositório, porque o comportamento que ele promove em suas equipes é a transparência e a responsabilidade coletiva, especialmente quando as equipes crescem. De qualquer forma, você terá que investir em ferramentas, mas é sempre melhor quando o comportamento padrão é o que você deseja ver em seus comandos.


Por que estamos falando sobre isso?


Matt Klein escreveu um artigo, "Monorepos: Por favor, não!" (comentário do tradutor: tradução em um hub "Monorepositórios: por favor, não" ). Eu gosto de Matt, acho que ele é muito inteligente, e você deve ler o ponto de vista dele. Ele originalmente twittou a enquete:


imagem


Tradução:
Neste dia de ano novo, discutirei sobre o quão ridículos são os monorepositórios. 2019 começou despercebido. Nesse espírito, ofereço-lhe uma pesquisa. Quem são os grandes fanáticos? Apoiantes:
- Monorepositório
- Ferrugem
- Inquérito errado / aqueles e aqueles


Minha resposta foi: "Eu literalmente sou essas duas pessoas". Em vez de falar sobre que tipo de droga Rust, vamos descobrir por que acho que ele está errado sobre os mono-repositórios. Um pouco sobre você. Eu sou o CTO do Chef Software. Temos cerca de 100 engenheiros, uma base de código de 11 a 12 anos e 4 produtos principais. Parte desse código está no poli-repositório (minha posição inicial), parte no monorepositório (minha posição atual).


Antes de começar: todo argumento que cito aqui será aplicado aos dois tipos de repositórios. Na minha opinião, não há razões técnicas para você escolher um ou outro tipo de repositório. Você pode fazer qualquer abordagem funcionar. Fico feliz em falar sobre isso, mas não estou interessado nas razões técnicas artificiais pelas quais uma é superior à outra.


Eu concordo com a primeira parte do ponto de vista de Matt:


Como, em grande escala, o monorepositório resolverá todos os mesmos problemas que o poli-repositório, mas ao mesmo tempo, provocará uma forte coerência do seu código e exigirá esforços incríveis para aumentar a escalabilidade do seu sistema de controle de versão.


Você precisa resolver os mesmos problemas, independentemente de escolher um monorepositório ou poli-repositório. Como você libera lançamentos? Qual é a sua abordagem para atualizações? Compatível com versões anteriores? Dependências entre projetos? Quais estilos de arquitetura são aceitáveis? Como você gerencia sua infraestrutura de construção e teste? A lista é interminável. E você resolverá todos eles à medida que crescer. Não há queijo grátis.


Eu acho que o argumento de Matt é semelhante às opiniões compartilhadas por muitos engenheiros (e gerentes) que eu respeito. Isso acontece do ponto de vista do engenheiro que trabalha no componente ou da equipe que trabalha no componente. Você ouve coisas como:


  • A base de código é complicada - não preciso de todo esse lixo.
  • Isso é mais difícil de testar porque tenho que verificar todo esse lixo que não preciso.
  • É mais difícil trabalhar com dependências externas.
  • Eu preciso dos meus próprios sistemas de controle de versão virtual.

Claro, todos esses pontos são razoáveis. Isso acontece nos dois casos - no poli-repositório, eu tenho minhas próprias coisas, além do que é necessário para a montagem ... Eu também posso precisar de outras coisas. Portanto, "apenas" crio ferramentas que fazem checkout de todo o projeto. Ou estou criando um repositório mono falso com submódulos. Nós poderíamos andar o dia todo por isso. Mas acho que o argumento de Matt erra o principal motivo, que eu quase virei a favor do monorepositório:


Provoca comunicação e mostra problemas.


Quando compartilhamos repositórios, de fato criamos um problema de coordenação e transparência. Isso corresponde à maneira como pensamos sobre as equipes (especialmente à maneira como os participantes pensam sobre elas): somos responsáveis ​​por um componente específico. Trabalhamos em relativo isolamento. Os limites são fixos na minha equipe e nos componentes em que estamos trabalhando.


Com a complexidade da arquitetura, uma equipe não pode mais gerenciá-la sozinha. Muito poucos engenheiros mantêm todo o sistema em mente. Suponha que você controle um componente comum A, usado pelos comandos B, C e D. Os refatoradores da equipe A, aprimoram a API e também alteram a implementação interna. Como resultado, as mudanças são incompatíveis com versões anteriores. Que conselho você daria?


  • Encontre todos os lugares onde a API antiga é usada.
  • Existem lugares onde a nova API não pode ser usada?
  • Você pode consertar e testar outros componentes para garantir que eles não quebrem?
  • Essas equipes podem verificar suas alterações agora?

Observe que essas perguntas são independentes do tipo de repositório. Você precisará encontrar as equipes B, C e D. Você precisará conversar com elas, descobrir o tempo, entender suas prioridades. Pelo menos, esperamos que você faça isso.


Ninguém realmente quer fazer isso. Isso é muito menos divertido do que apenas consertar a maldita API. Tudo isso é humano e confuso. No repositório, você pode simplesmente fazer alterações, revisar aqueles que estão trabalhando neste componente (provavelmente não B, C ou D) e seguir em frente. As equipes B, C e D podem simplesmente permanecer na versão atual. Eles serão atualizados quando perceberem seu gênio!


Em um único repositório, a responsabilidade é alterada por padrão. A equipe A altera seu componente e, se não tomar cuidado, interrompe imediatamente B, C e D. Isso faz com que B, C e D apareçam na porta A, perguntando-se por que a equipe A interrompeu a montagem. Isso ensina A que eles não podem pular minha lista acima. Eles devem falar sobre o que vão fazer. B, C e D podem se mover? E se B e C puderem, mas D estiver intimamente relacionado a um efeito colateral do antigo algoritmo?


Então precisamos conversar sobre como saímos dessa situação:


  1. Suporte para várias APIs internas, enquanto o algoritmo antigo será marcado como obsoleto até que D possa parar de usá-lo.
  2. Suporte para várias versões de versões, uma com a interface antiga e outra com a nova.
  3. Liberação atrasada das alterações em A até que B, C e D possam aceitá-la.

Suponha que selecionemos 1, várias APIs. Nesse caso, temos dois pedaços de código. Velho e novo. Muito útil em algumas situações. Retornamos o código antigo, marcamos como obsoleto e concordamos com uma programação para sua remoção com o comando D. É essencialmente idêntico para poli e para o mono-repositório.


Para lançar várias versões, precisamos de um ramo. Agora temos dois componentes - A1 e A2. As equipes B e C usam A2 e D usa A1. Precisamos que cada componente esteja pronto para o lançamento, porque antes que o D possa seguir em frente, podem ser necessárias atualizações de segurança e outras correções. No repositório, podemos ocultá-lo em um ramo de longa duração que se sente bem. No mono-repositório, forçamos o código no novo módulo. A equipe D ainda precisará fazer alterações no componente "antigo". Todos podem ver o custo que pagamos aqui - agora temos o dobro do código e quaisquer correções de erros que se apliquem a A1 e A2 devem ser aplicadas a ambos. Com a abordagem de usar ramificações em um repositório, isso está oculto por trás da seleção de cereja. Consideramos o custo menor porque não há duplicação. Do ponto de vista prático, o custo é o mesmo: você criará, liberará e manterá duas bases de código basicamente idênticas até poder excluir uma delas. A diferença é que, no monorepositório, essa dor é direta e visível. Isso é ainda pior e bom.


Finalmente, chegamos ao terceiro ponto. Atraso de liberação. É possível que as alterações feitas por A melhorem a vida da equipe A. É importante, mas não urgente. Podemos apenas aguentar? No repositório, estamos pressionando isso para consolidar o artefato. Claro, estamos falando sobre esse time D. Apenas fique na versão antiga até você se atualizar! Isso cria um jogo covarde. A equipe A continua trabalhando no seu componente, ignorando o fato de que a equipe D está usando uma versão cada vez mais desatualizada (esse é um problema para a equipe D, eles são estúpidos). Enquanto isso, a equipe D está falando mal da atitude descuidada da equipe A em relação à estabilidade do código, se é que falam sobre isso. Meses se passam. Finalmente, a equipe D decide dar uma olhada na opção de atualização, mas há apenas mais alterações em A. A equipe A mal lembra quando e como eles quebraram D. A atualização é mais dolorosa e levará mais tempo. O que o envia mais abaixo na pilha de prioridades. Até aquele dia, até que tenhamos um problema de segurança em A, o que nos força a fazer uma filial. A equipe A deve voltar no tempo, encontrar o momento em que D estava estável, corrigir o problema e prepará-lo para o lançamento. Essa é a escolha de fato que as pessoas fazem, e é de longe a pior. Isso parece ser bom para as equipes A e D, desde que possamos nos ignorar.


No monorepositório, o terceiro não é realmente uma opção. Você é forçado a lidar com a situação de duas maneiras. Você precisa ver os custos de ter duas ramificações de liberação. Aprenda a se proteger de atualizações que quebram a compatibilidade com versões anteriores. Mas a principal coisa: você não pode evitar uma conversa difícil.


Na minha experiência, quando as equipes se tornam grandes, não é mais possível manter todo o sistema em mente, e essa é a parte mais importante. Você precisa melhorar a visibilidade das divergências no sistema. Você deve trabalhar ativamente para que as equipes desviem os olhos dos componentes e examinem o trabalho de outras equipes e consumidores.


Sim, você pode criar ferramentas que tentarão resolver o problema dos poli-repositórios. Mas minha experiência no ensino da entrega e automação contínuas em grandes empresas me diz o seguinte: o comportamento padrão sem o uso de ferramentas adicionais é o que você espera ver. O comportamento padrão do repositório é o isolamento, esse é o ponto. O comportamento padrão de um mono-repositório é responsabilidade e transparência compartilhadas, esse é o ponto. Nos dois casos, vou criar uma ferramenta que suavizará cantos afiados. Como líder, sempre escolherei um mono-repositório, porque os instrumentos devem fortalecer a cultura que eu quero, e a cultura vem de pequenas decisões e do trabalho diário da equipe.

Source: https://habr.com/ru/post/pt453958/


All Articles