Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Vamos discutir por que as ferramentas de CI e a CI são coisas completamente diferentes.

Que dor o CI pretende resolver, de onde surgiu a ideia, quais as últimas confirmações de que funciona, como entender que você tem uma prática e não apenas instalou o Jenkins.

A ideia de fazer uma reportagem sobre Integração Contínua surgiu há um ano, quando eu estava indo para entrevistas e procurando emprego. Conversei com 10 a 15 empresas, apenas uma delas conseguiu responder claramente o que é CI e explicar como perceberam que não o tinham. O resto estava falando bobagens ininteligíveis sobre Jenkins :) Bem, nós temos o Jenkins, ele constrói, CI! Durante o relatório, tentarei explicar o que realmente é Integração Contínua e por que Jenkins e ferramentas similares têm uma relação muito fraca com isso.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Então, o que geralmente vem à mente quando você ouve a palavra CI? A maioria das pessoas pensará em Jenkins, Gitlab CI, Travis, etc.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Mesmo se pesquisarmos no Google, isso nos dará essas ferramentas.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Se você estiver familiarizado com perguntas, imediatamente após listar as ferramentas, elas dirão que CI é quando você cria e executa testes em uma solicitação pull para um commit.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Integração Contínua não se trata de ferramentas, nem de assemblies com testes em uma ramificação! Integração Contínua é a prática de integração muito frequente de novo código e para utilizá-lo não é necessário cercar Jenkins, GitLab, etc.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Antes de descobrirmos como é um IC completo, vamos primeiro mergulhar no contexto das pessoas que o criaram e sentir a dor que estavam tentando resolver.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

E resolveram a dor de trabalhar juntos em equipe!

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Vejamos exemplos das dificuldades que os desenvolvedores enfrentam ao desenvolver em equipes. Aqui temos um projeto, um branch master em git e dois desenvolvedores.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

E eles começaram a trabalhar como todos estavam acostumados. Assumimos uma tarefa no grande esquema das coisas, criamos uma ramificação de recursos e escrevemos o código.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Um finalizou o recurso mais rápido e o fundiu no master.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

O segundo precisou de mais tempo, fundiu-se posteriormente e acabou em conflito. Agora, em vez de escrever os recursos que o negócio precisa, o desenvolvedor gasta seu tempo e energia resolvendo conflitos.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Quanto mais difícil for combinar seu recurso com um mestre comum, mais tempo gastamos nisso. E mostrei isso com um exemplo bastante simples. Este é um exemplo onde existem apenas 2 desenvolvedores. Imagine se 10, 15 ou 100 pessoas em uma empresa escrevessem em um repositório. Você ficará louco para resolver todos esses conflitos.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Há um caso um pouco diferente. Temos um mestre e alguns desenvolvedores fazendo alguma coisa.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Eles criaram um galho.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Um morreu, estava tudo bem, ele passou na tarefa.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

O segundo desenvolvedor, entretanto, entregou sua tarefa. Digamos que ele o enviou para revisão. Muitas empresas têm uma prática chamada revisão. Por um lado, esta prática é boa e útil, por outro lado, ela nos atrasa em muitos aspectos. Não entraremos nisso, mas aqui está um ótimo exemplo do que uma história de crítica negativa pode levar. Você enviou uma solicitação pull para revisão. Não há mais nada para o desenvolvedor fazer. O que ele começa a fazer? Ele começa a assumir outras tarefas.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Durante esse tempo, o segundo desenvolvedor fez outra coisa.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

O primeiro completou a terceira tarefa.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

E depois de muito tempo, sua revisão foi testada e ele está tentando chegar a um acordo. Então o que está acontecendo? Ele captura um grande número de conflitos. Por que? Porque enquanto sua solicitação pull estava pendente na revisão, muitas coisas já haviam mudado no código.

Além da história dos conflitos, há uma história das comunicações. Enquanto seu tópico está em revisão, enquanto espera por algo, enquanto você trabalha em um recurso por um longo tempo, você para de rastrear o que mais está mudando na base de código do seu serviço. Talvez o que você está tentando resolver agora já tenha sido resolvido ontem e você possa pegar algum método e reutilizá-lo. Mas você não verá isso porque está sempre trabalhando com um branch desatualizado. E esse branch desatualizado sempre resulta na necessidade de resolver um conflito de mesclagem.

Acontece que se trabalharmos em equipe, ou seja, não uma pessoa está fuçando no repositório, mas de 5 a 10 pessoas, quanto mais tempo não adicionarmos nosso código ao mestre, mais sofreremos porque, em última análise, precisamos algo então mescle-o. E quanto mais conflitos tivermos, e quanto mais antiga for a versão com a qual trabalhamos, mais problemas teremos.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Fazer algo juntos é doloroso! Sempre nos atrapalhamos.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Esse problema foi percebido há mais de 20 anos. Encontrei a primeira menção à prática de Integração Contínua em Extreme Programming.

Extreme Programming é o primeiro framework ágil. A página apareceu em 96. E a ideia era usar algum tipo de prática de programação, planejamento e outras coisas, para que o desenvolvimento fosse o mais flexível possível, para que pudéssemos responder rapidamente a qualquer mudança ou exigência de nossos clientes. E eles começaram a encarar isso há 24 anos, que se você faz algo por muito tempo e à margem, você gasta mais tempo nisso porque tem conflitos.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Agora analisaremos a frase “Integração Contínua” individualmente. Se traduzirmos diretamente, obteremos integração contínua. Mas até que ponto é contínuo não está muito claro; é muito descontínuo. Mas quanta integração tem também não é muito óbvia.

E é por isso que estou dando citações de Extreme Programming agora. E analisaremos as duas palavras separadamente.

Integração - Como já disse, nos esforçamos para que cada engenheiro trabalhe com a versão mais atual do código, de forma que ele se esforce para adicionar seu código o mais rápido possível a um branch comum, de forma que estes sejam pequenos branchs. Porque se eles forem grandes, podemos facilmente ficar presos em conflitos de mesclagem por uma semana. Isso é especialmente verdadeiro se tivermos um ciclo de desenvolvimento longo, como o cascata, onde o desenvolvedor ficou ausente por um mês para cortar algum recurso enorme. E ele ficará preso na fase de integração por muito tempo.

Integração é quando pegamos nosso branch e integramos com o master, fazemos merge. Existe uma opção definitiva quando somos desenvolvedores de transbase, onde nos esforçamos para garantir que escreveremos imediatamente para o master, sem quaisquer ramificações extras.

Em geral, integração significa pegar seu código e arrastá-lo para o master.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

O que se entende aqui pela palavra “contínuo”, o que se chama continuidade? A prática implica que o desenvolvedor se esforce para integrar seu código o mais rápido possível. Este é o seu objetivo ao executar qualquer tarefa - colocar seu código no master o mais rápido possível. Em um mundo ideal, os desenvolvedores fariam isso a cada poucas horas. Ou seja, você pega um pequeno problema e o mescla no mestre. Tudo é bom. É por isso que você se esforça. E isso deve ser feito continuamente. Assim que você faz algo, você imediatamente o coloca no mestre.

E o desenvolvedor que faz algo é responsável pelo que fez para que funcionasse e não quebrasse nada. É aqui que geralmente surge a história do teste. Queremos executar alguns testes em nosso commit, em nosso merge, para ter certeza de que funciona. E é aqui que Jenkins pode ajudá-lo.

Mas com histórias: vamos fazer pequenas mudanças, vamos deixar as tarefas serem pequenas, vamos criar um problema e imediatamente tentar incorporá-lo de alguma forma no master - nenhum Jenkins vai ajudar aqui. Porque Jenkins apenas ajudará você a executar testes.

Você pode viver sem eles. Isso não vai te machucar de jeito nenhum. Porque o objetivo da prática é medir com a maior freqüência possível, para não perder muito tempo com conflitos no futuro.

Vamos imaginar que por algum motivo estamos em 2020 sem Internet. E trabalhamos localmente. Não temos Jenkins. Isto é bom. Você ainda pode ir em frente e criar uma filial local. Você escreveu algum código nele. Concluímos a tarefa em 3-4 horas. Mudamos para master, fizemos um git pull e mesclamos nosso branch lá. Preparar. Se você faz isso com frequência, parabéns, você tem Integração Contínua!

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Que evidências existem no mundo moderno de que vale a pena gastar energia? Porque em geral é difícil. Se você tentar trabalhar assim, vai entender que parte do planejamento agora será afetado, terá que dedicar mais tempo à decomposição de tarefas. Porque se você fizer isso, cara..., então você não conseguirá chegar a um acordo rapidamente e, conseqüentemente, terá problemas. Você não terá mais prática.

E será caro. Não será possível trabalhar imediatamente a partir de amanhã utilizando Integração Contínua. Você vai levar muito tempo para se acostumar com isso, vai demorar muito para se acostumar com a decomposição de tarefas, vai demorar muito para se acostumar a refazer a prática de revisão, se você tiver uma . Porque nosso objetivo é que derreta hoje. E se você fizer uma revisão dentro de três dias, terá problemas e a Integração Contínua não estará funcionando para você.

Mas temos neste momento alguma evidência relevante que nos diga que faz sentido investir nesta prática?

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

A primeira coisa que me veio à mente foi Estado do DevOps. Esse é um estudo que a galera vem realizando há 7 anos. Agora eles fazem isso como uma organização independente, mas sob o comando do Google.

E o seu estudo de 2018 mostrou uma correlação entre empresas que tentam utilizar filiais de curta duração que se integram rapidamente, integram frequentemente e têm melhores indicadores de desempenho de TI.

Quais são esses indicadores? Estas são 4 métricas que eles coletam de todas as empresas em seus questionários: frequência de implantação, tempo de espera para mudanças, tempo para restaurar o serviço, taxa de falhas de mudanças.

E, em primeiro lugar, existe essa correlação, sabemos que empresas que medem com frequência têm métricas muito melhores. E eles têm uma divisão de empresas em várias categorias: são empresas lentas que produzem algo lentamente, de médio desempenho, de alto desempenho e de elite. A elite são Netflix, Amazon, que são super rápidas, fazem tudo com rapidez, beleza e eficiência.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

A segunda história, que aconteceu há apenas um mês. O Technology Radar tem um ótimo artigo sobre o Gitflow. O Gitflow é diferente de todos os outros porque seus ramos têm vida longa. Existem ramificações de lançamento que duram muito tempo e ramificações de recursos que também duram muito tempo. Esta prática no Technology Radar mudou para HOLD. Por que? Porque as pessoas enfrentam a dor da integração.

Se o seu galho vive muito tempo, ele emperra, apodrece e começamos a gastar mais tempo tentando fazer algum tipo de mudança nele.

E recentemente o autor do Gitflow disse que se o seu objetivo é integração contínua, se o seu objetivo é rolar o mais rápido possível, então o Gitflow é uma má ideia. Ele acrescentou separadamente ao artigo que se você tiver um back-end onde possa se esforçar para isso, então o Gitflow será supérfluo para você, porque o Gitflow irá atrasá-lo, o Gitflow criará problemas para você com integração.

Isso não significa que o Gitflow seja ruim e não deva ser usado. É para outras ocasiões. Por exemplo, quando você precisa de suporte a diversas versões de um serviço ou aplicativo, ou seja, quando você precisa de suporte por um longo período de tempo.

Mas se você conversar com pessoas que oferecem suporte a esses serviços, você ouvirá muita dor sobre o fato de que esta versão era 3.2, que foi há 4 meses, mas essa correção não foi incluída nela e agora, para torná-la, você precisa fazer um monte de mudanças. E agora eles estão presos novamente e estão brincando há uma semana tentando implementar algum novo recurso.

Como Alexander Kovalev observou corretamente no bate-papo, correlação não é o mesmo que causalidade. Isto é verdade. Ou seja, não existe uma ligação direta de que se você tiver Integração Contínua, então todas as métricas ficarão ótimas. Mas há uma correlação positiva de que se um é um, então muito provavelmente o outro também o é. Não é um fato, mas muito provavelmente. É apenas uma correlação.

Integração Contínua como prática, não Jenkins. Andrei Alexandrov

Parece que já estamos fazendo alguma coisa, parece que já estamos nos fundindo, mas como podemos entender que ainda temos Integração Contínua, que estamos nos fundindo com bastante frequência?

Jez Humble é autor de Handbook, Accelerate, do site Continuous Delivery e do livro Continuous Delivery. Ele oferece este teste:

  • O código do engenheiro chega ao mestre todos os dias.
  • Para cada commit você executa testes unitários.
  • A construção no master caiu, foi consertada em cerca de 10 minutos.

Ele sugere usar um teste como este para garantir que você tenha prática suficiente.

Acho este último um pouco controverso. Ou seja, se você consegue consertar em 10 minutos, então você tem Integração Contínua, parece um pouco estranho, na minha opinião, mas faz sentido. Por que? Porque se você congela com frequência, significa que suas alterações são pequenas. Se uma pequena alteração significar que sua compilação mestre está quebrada, você poderá encontrar um exemplo rapidamente porque a alteração é pequena. Aqui você teve uma pequena mesclagem, 20 a 30 linhas foram alteradas. E, consequentemente, você consegue entender rapidamente qual foi o motivo, porque as mudanças são minúsculas, você tem uma área muito pequena para procurar o problema.

E mesmo que nosso produto desmorone após o lançamento, então se tivermos a prática da Integração Contínua fica muito mais fácil agirmos, porque as mudanças são minúsculas. Sim, isso afetará o planejamento. Isso vai doer. E, provavelmente, o mais difícil nessa prática é se acostumar a quebrar tarefas, ou seja, como fazer para que você possa pegar algo e fazer em poucas horas e ao mesmo tempo passar na revisão, se você tem um. A revisão é uma dor separada.

Os testes unitários são apenas um assistente que ajuda você a entender se sua integração foi bem-sucedida e se nada foi quebrado. Na minha opinião, isso também não é totalmente obrigatório, porque esse não é o objetivo da prática.

Esta é uma breve introdução à Integração Contínua. Isso é tudo que existe nesta prática. Estou pronto para perguntas.

Vou apenas resumir brevemente novamente:

  • Integração Contínua não é Jenkins, não é Gitlab.
  • Isto não é uma ferramenta, é uma prática mesclarmos nosso código no mestre sempre que possível.
  • Fazemos isso para evitar a enorme dor que surge com as fusões no futuro, ou seja, sentimos um pouco de dor agora para não sentir mais no futuro. Esse é o ponto principal.
  • Do lado há comunicação por código, mas muito raramente vejo isso, mas também foi para isso que foi projetado.

perguntas

O que fazer com tarefas não decompostas?

Decompor. Qual é o problema? Você pode dar um exemplo de que existe uma tarefa e ela não está decomposta?

Existem tarefas que não podem ser decompostas da palavra “completamente”, por exemplo, aquelas que exigem um conhecimento muito profundo e que podem realmente ser resolvidas ao longo de um mês para alcançar algum resultado digerível.

Se bem entendi, então existe alguma tarefa grande e complexa, cujo resultado só será visível em um mês?

Sim está certo. Sim, será possível avaliar o resultado não antes de um mês.

Multar. Em geral isso não é um problema. Por que? Porque neste caso, quando falamos de galhos, não estamos falando de um galho com característica. Os recursos podem ser grandes e complexos. Eles podem afetar um grande número de componentes. E talvez não possamos fazê-los completamente em um único ramo. Isto é bom. Só precisamos destrinchar essa história. Se um recurso não estiver completamente pronto, isso não significa que algumas partes do seu código não possam ser mescladas. Você adicionou, digamos, migração e há alguns estágios dentro do recurso. Digamos que você tenha um estágio - faça uma migração, adicione um novo método. E você já pode medir essas coisas todos os dias.

Multar. Qual é o objetivo então?

Qual é o sentido de matar pequenas coisas todos os dias?

Sim.

Se eles quebrarem alguma coisa, você verá imediatamente. Você tem um pequeno pedaço que quebrou alguma coisa, é mais fácil para você consertar. A questão é que mesclar uma peça pequena agora é muito mais fácil do que mesclar algo grande em algumas semanas. E o terceiro ponto é que outros engenheiros trabalharão com a versão atual do código. Eles verão que algumas migrações foram adicionadas aqui e então apareceu algum método que eles também podem querer usar. Todos verão o que está acontecendo no seu código. É para essas três coisas que a prática é feita.

Obrigado, o problema está encerrado!

(Oleg Soroka) Posso acrescentar? Você disse tudo corretamente, só quero acrescentar uma frase.

Então

Com a Integração Contínua, o código é mesclado em uma ramificação comum não quando o recurso está completamente pronto, mas quando a construção para de falhar. E você pode se comprometer com segurança a dominar quantas vezes por dia quiser. O segundo aspecto é que se por algum motivo você não conseguir dividir a tarefa mensal em tarefas por pelo menos três dias, fico em silêncio por cerca de três horas, então você tem um grande problema. E o fato de não ter Integração Contínua é o menor desses problemas. Isso significa que você tem problemas com arquitetura e zero práticas de engenharia. Porque mesmo que se trate de uma investigação, em qualquer caso, deve ser formulada em forma de hipóteses ou de ciclo.

Falamos sobre 4 métricas que distinguem as empresas de sucesso das que estão atrasadas. Ainda temos que viver para ver essas 4 métricas. Se sua tarefa média leva um mês para ser concluída, eu me concentraria primeiro nessa métrica. Eu diminuiria para 3 dias primeiro. E depois disso comecei a pensar em Contínuo.

Entendi bem que você acha que em geral não adianta investir em práticas de engenharia se alguma tarefa leva um mês para ser concluída?

Você tem integração contínua. E existe um tópico que em 10 minutos você pode consertar uma correção ou revertê-la. Imagine que você o lançou. Além disso, você ainda tem implantação contínua, lançou para produção e só então percebeu que algo deu errado. E você precisa revertê-lo, mas já migrou seu banco de dados. Você já tem o esquema do banco de dados da próxima versão, além disso, também tinha algum tipo de backup, e os dados também foram gravados lá.

E que alternativa você tem? Se você reverter o código, ele não poderá mais funcionar com esse banco de dados atualizado.

A base só avança, sim.

Pessoas que têm práticas de engenharia ruins provavelmente também não leram o livro grosso sobre... também. O que fazer com o backup? Se você restaurar a partir de um backup, significa que perderá os dados acumulados naquele momento. Por exemplo, trabalhamos três horas com a nova versão do banco de dados, usuários cadastrados lá. Você recusa o backup antigo porque o esquema não funciona com a nova versão, então você perdeu esses usuários. E eles estão insatisfeitos, eles juram.

Para dominar toda a gama de práticas que suportam a Integração Contínua e a Entrega Contínua, não basta apenas aprender a escrever.... Em primeiro lugar, pode haver muitos deles, será impraticável. Além disso, existem várias outras práticas como a Científica. Existe tal prática, o GitHub a popularizou uma vez. É quando você tem o código antigo e o novo em execução ao mesmo tempo. É quando você cria um recurso inacabado, mas ele pode retornar algum valor: seja como uma função ou como uma API Rest. Você executa o código novo e o código antigo e compara a diferença entre eles. E se houver alguma diferença, você registra esse evento. Dessa forma, você sabe que tem um novo recurso pronto para ser implementado em cima do antigo, caso não tenha havido discrepância entre os dois por um determinado período.

Existem centenas dessas práticas. Eu sugeriria começar com o desenvolvimento do transbase. Ela não está 100% na Integração Contínua, mas as práticas são as mesmas, uma não vive bem sem a outra.

Você deu o desenvolvimento transbase como um exemplo onde você pode ver as práticas ou sugeriu que as pessoas começassem a usar o debelopment transbase?

Dê uma olhada, porque eles não poderão usá-lo. Para utilizá-los é preciso ler muito. E quando uma pessoa pergunta: “O que fazer com um recurso que leva um mês, significa que ela não leu sobre desenvolvimento transbase”. Eu não recomendaria isso ainda. Eu aconselharia focar apenas no tópico de como dividir corretamente, arquitetonicamente, grandes tarefas em tarefas menores. Esta é a essência da decomposição.

A decomposição é uma das ferramentas do arquiteto. Primeiro fazemos a análise, depois a decomposição, depois a síntese e depois a integração. E é assim que tudo funciona para nós. E ainda precisamos crescer para a Integração Contínua através da decomposição. As dúvidas surgem na primeira etapa, e já estamos falando da quarta etapa, ou seja, quanto mais fizermos integração, melhor. Ainda é muito cedo para fazer isso; seria bom cortar primeiro o seu monólito.

Você precisa desenhar várias setas e quadrados em algum diagrama. Não posso dizer que agora vou mostrar o diagrama arquitetônico de um novo aplicativo e mostrar um quadrado, dentro do qual há um botão verde para o aplicativo. De qualquer forma, haverá mais quadrados e setas. Cada diagrama que vi tinha mais de um. E a decomposição, mesmo ao nível da representação gráfica, já está a ocorrer. Portanto, os quadrados podem ser independentes. Caso contrário, tenho grandes perguntas para o arquiteto.

Há uma pergunta no chat: “Se uma revisão é obrigatória e demora muito, talvez um dia ou mais?”

Você tem problemas com a prática. A revisão não deve durar um dia ou mais. Esta é a mesma história da pergunta anterior, só que um pouco mais suave. Se uma revisão durar um dia, provavelmente essa revisão sofrerá uma grande mudança. Isso significa que ele precisa ser menor. No desenvolvimento transbase, recomendado por Oleg, existe uma história chamada revisão contínua. A ideia dela é que façamos uma solicitação pull tão pequena de propósito, porque nos esforçamos para mesclar constantemente e aos poucos. E assim a solicitação pull altera uma abstração ou 10 linhas. Graças a esta revisão, demoramos alguns minutos.

Se a revisão demorar um dia ou mais, algo está errado. Em primeiro lugar, você pode ter alguns problemas com a arquitetura. Ou este é um grande pedaço de código, 1 linhas, por exemplo. Ou sua arquitetura é tão complexa que uma pessoa não consegue entendê-la. Este é um problema um pouco lateral, mas também terá que ser resolvido. Talvez não haja necessidade alguma de revisão. Precisamos pensar sobre isso também. A revisão é o que te atrasa. Em geral tem suas vantagens, mas você precisa entender por que está fazendo isso. Essa é uma forma de você transmitir informações rapidamente, é uma forma de você definir alguns padrões internamente ou o quê? Por que você precisa disso? Porque a revisão precisa ser feita muito rapidamente ou totalmente cancelada. É como o desenvolvimento transbase - a história é muito bonita, mas só para caras maduros.

Em relação às 4 métricas, eu ainda recomendaria removê-las para entender aonde isso leva. Veja os números, veja a foto, como está tudo ruim.

(Dmitry) Estou pronto para discutir isso com você. Números e métricas são ótimos, as práticas são ótimas. Mas você precisa entender se o negócio precisa disso. Existem empresas que não precisam desse tipo de mudança rápida. Conheço empresas onde não é possível fazer alterações a cada 15 minutos. E não porque eles sejam tão ruins. Este é um ciclo de vida. E para fazer o recurso de ramificação, o recurso de alternância, você precisa de um conhecimento profundo.

É complicado. Se você quiser ler a história sobre o recurso de alternância com mais detalhes, eu recomendo fortemente https://trunkbaseddevelopment.com/. E há um artigo maravilhoso de Martin Fowler sobre recursos de alternância: quais tipos existem, ciclos de vida, etc.

E você ainda não respondeu à pergunta: “O Jenkins é necessário ou não?”

Jenkins não é realmente necessário em nenhum caso. Sério, as ferramentas: Jenkins, Gitlab trarão conveniência para você. Você verá se a montagem está montada ou não. Eles podem ajudá-lo, mas não lhe darão prática. Eles só podem lhe dar um círculo - Ok, não ok. E então, se você também escreve testes, porque se não houver testes, então é quase inútil. Portanto, é necessário porque é mais conveniente, mas em geral você pode viver sem ele, não perderá muito.

Ou seja, se você tem práticas, isso significa que não precisa delas?

Isso mesmo. Eu recomendo o teste Jez Humble. Aí tenho uma atitude ambivalente em relação ao último ponto. Mas, em geral, se você tem três coisas, mescla constantemente, executa testes em commits no master, corrige rapidamente a compilação no master, então talvez não precise de mais nada.

Enquanto aguardamos as perguntas dos participantes, tenho uma pergunta. Estávamos conversando sobre o código do produto. Você o usou para código de infraestrutura? É o mesmo código, tem os mesmos princípios e o mesmo ciclo de vida ou existem ciclos de vida e princípios diferentes? Normalmente, quando todo mundo fala em Integração e Desenvolvimento Contínuo, todo mundo esquece que também existe código de infraestrutura. E ultimamente tem havido cada vez mais disso. E todas essas regras deveriam ser trazidas para lá?

Nem que deveria ser, seria ótimo porque facilitaria a vida da mesma forma. Assim que trabalhamos com código, não com scripts bash, mas temos código normal.

Pare, pare, um script bash também é um código. Não toque no meu antigo amor.

Ok, não vou pisotear suas memórias. Eu não gosto pessoalmente de bash. Fica feio e assustador o tempo todo. E muitas vezes quebra de forma imprevisível, e é por isso que não gosto disso. Mas tudo bem, digamos que você tenha um código bash. Talvez eu realmente não entenda e existam estruturas de teste normais por aí. Eu simplesmente não sei. E obtemos os mesmos benefícios.

Assim que trabalhamos com infraestrutura como código, temos os mesmos problemas que os desenvolvedores. Há alguns meses, encontrei uma situação em que um colega me enviou uma solicitação pull de 1 linhas no bash. E você fica na avaliação por 000 horas. Os mesmos problemas surgem. Ainda é código. E ainda é uma colaboração. Ficamos presos à solicitação pull e ao fato de estarmos resolvendo os mesmos conflitos de mesclagem no mesmo bash, por exemplo.

Agora estou olhando muito ativamente para tudo isso na mais bela infra-programação. Agora trouxe Pulumi para a infraestrutura. Isso é programação em sua forma mais pura. Aí é ainda melhor, porque tenho todos os recursos de uma linguagem de programação, ou seja, fiz uma linda alternância do nada com os mesmos ifs e está tudo bem. Ou seja, meu troco já está no master. Todos já podem vê-lo. Outros engenheiros sabem disso. Já influenciou alguma coisa lá. No entanto, não foi habilitado para todas as infraestruturas. Ele foi ativado em meus bancos de teste, por exemplo. Portanto, para responder novamente à sua pergunta, é necessário. Facilita a vida para nós, como engenheiros que trabalham com código, da mesma forma.

Se mais alguém tiver dúvidas?

Eu tenho uma pergunta. Quero continuar a discussão com Oleg. Em geral, acho que você tem razão, que se uma tarefa leva um mês para ser concluída, então você tem um problema de arquitetura, tem um problema de análise, decomposição, planejamento, etc. tentando viver de acordo com a Integração Contínua, então você começará a corrigir a dor com o planejamento, porque não vai fugir disso em nenhum outro lugar.

(Oleg) Sim, está certo. Esta prática é comparável em esforço a qualquer outra prática séria de mudança cultural. A coisa mais difícil de superar são os hábitos, especialmente os maus hábitos. E se para implementar esta prática é necessária uma mudança séria nos hábitos de quem está ao seu redor: desenvolvedores, gestão, gerente de produção, então surpresas o aguardam.

Que surpresas poderia haver? Digamos que você decida que irá se integrar com mais frequência. E você tem outras coisas ligadas à integração, por exemplo, artefatos. E na sua empresa, por exemplo, existe uma política de que todo artefato deve ser contabilizado de alguma forma em algum tipo de sistema de armazenamento de artefatos. E isso leva algum tempo. Uma pessoa precisa marcar a caixa de que ele, como gerente de lançamento, testou esse artefato para garantir que ele esteja pronto para lançamento em produção. Se leva de 5 a 10 a 15 minutos, mas você faz o layout uma vez por semana, gastar meia hora uma vez por semana é um pequeno imposto.

Se você fizer Integração Contínua 10 vezes por dia, então 10 vezes precisarão ser multiplicados por 30 minutos. E isso excede a quantidade de tempo de trabalho deste gerenciador de lançamento. Ele simplesmente se cansa de fazer isso. Existem custos fixos para algumas práticas. Isso é tudo.

E você precisa cancelar essa regra para não fazer mais esse lixo, ou seja, não atribuir manualmente um grau para corresponder a algo. Você está confiando inteiramente em algum conjunto automatizado de testes de prontidão.

E se você precisar de uma prova de alguém, para que o chefe assine, e você não entre em produção sem que Vasya diga que ele permite, etc. - toda essa bobagem atrapalha o praticante. Porque se houver alguma atividade associada a um imposto, tudo aumenta 100 vezes. Portanto, muitas vezes a mudança não será saudada com alegria por todos. Porque os hábitos das pessoas são difíceis de mudar.

Quando uma pessoa faz seu trabalho habitual, ela o faz quase sem pensar. Sua carga cognitiva é zero. Ele só brinca, já tem um checklist na cabeça, já fez mil vezes. E assim que você chega e diz a ele: “Vamos cancelar essa prática e introduzir uma nova a partir de segunda-feira”, para ele isso se torna uma carga cognitiva poderosa. E isso acontece com todos ao mesmo tempo.

Portanto, o mais simples, embora nem todos possam se dar ao luxo desse luxo, mas é o que eu sempre faço, é o seguinte. Se um novo projeto for iniciado, geralmente todas as práticas não testadas serão imediatamente incluídas neste projeto. Embora o projeto seja jovem, não arriscamos nada. Ainda não há Prod, não há nada para destruir. Portanto, pode ser usado como treinamento. Essa abordagem funciona. Mas nem todas as empresas têm a oportunidade de iniciar tais projetos com frequência. Embora isso também seja um pouco estranho, porque agora há uma transformação digital completa, todos devem lançar experimentos para acompanhar os concorrentes.

Aqui você chega à conclusão de que primeiro deve entender o que precisa fazer. O mundo não é ideal e a produção também não é ideal.

Sim, essas coisas estão interligadas.

As empresas também nem sempre entendem que precisam seguir esse caminho.

Existe uma situação em que nenhuma mudança é possível. Esta é uma situação em que há mais pressão sobre a equipe. A equipe já está bastante esgotada. Ela não tem tempo livre para nenhum experimento. Eles trabalham em recursos de manhã à noite. E o gerenciamento tem cada vez menos recursos. Cada vez mais são necessários. Em tal situação, nenhuma mudança é possível. Só podemos dizer à equipe que amanhã faremos o mesmo que ontem, só precisamos fazer um pouco mais de funcionalidades. Neste sentido, não são possíveis transições para quaisquer práticas. Essa é uma situação clássica quando não dá tempo de afiar o machado, as árvores precisam ser derrubadas, então cortam com machado cego. Não há dicas simples aqui.

(Dmitry) Vou ler um esclarecimento do chat: “Mas precisamos de muita cobertura de testes em diferentes níveis. Quanto tempo é alocado para testes? É um pouco caro e leva muito tempo.”

(Oleg) Este é um equívoco clássico. Deve haver testes suficientes para você estar confiante. Integração Contínua não é uma coisa onde 100% dos testes são feitos primeiro e só depois você começa a aplicar essa prática. A Integração Contínua reduz sua carga cognitiva porque cada uma das mudanças que você vê com os olhos é tão óbvia que você entende se vai quebrar alguma coisa ou não, mesmo sem testes. Você pode testar isso rapidamente em sua cabeça porque as mudanças são pequenas. Mesmo se você tiver apenas testadores manuais, será mais fácil para eles também. Você rolou e disse: “Olha, tem alguma coisa quebrada?” Eles verificaram e disseram: “Não, nada está quebrado”. Porque o testador sabe onde procurar. Você tem um commit associado a um trecho de código. E isso é explorado por comportamentos específicos.

Aqui você, claro, embelezou.

(Dmitry) Eu não concordo aqui. Existe uma prática - desenvolvimento orientado a testes, que o salvará disso.

(Oleg) Bem, ainda não cheguei a esse ponto. A primeira ilusão é que você precisa escrever 100% dos testes ou não precisa fazer Integração Contínua. Não é verdade. Estas são duas práticas paralelas. E eles não são diretamente dependentes. A cobertura do seu teste deve ser ideal. Ideal - isso significa que você mesmo está confiante de que a qualidade do mestre em que seu mestre permaneceu após o commit permite que você pressione com segurança o botão “Implantar” em uma noite de sexta-feira bêbada. Como você consegue isso? Através da revisão, através da cobertura, através de uma boa monitorização.

Um bom monitoramento é indistinguível de testes. Se você executar testes uma vez no pré-produção, eles verificarão todos os scripts do usuário uma vez e pronto. E se você executá-los em um loop infinito, então este é o seu sistema de monitoramento implantado, que testa tudo indefinidamente - quer tenha travado ou não. Nesse caso, a única diferença é se isso é feito uma ou duas vezes. Um conjunto de testes muito bom... rodando sem parar, isso é monitoramento. E o monitoramento adequado deveria ser assim.

E, portanto, como exatamente você alcançará esse estado quando se preparar na noite de sexta-feira e for para casa é outra questão. Talvez você seja apenas um canalha ousado.

Voltemos um pouco à Integração Contínua. Fugimos para uma prática complexa ligeiramente diferente.

E a segunda ilusão é que o MVP, dizem eles, precisa ser feito rapidamente, então os testes não são necessários. Certamente não dessa forma. O fato é que quando você escreve uma história de usuário em um MVP, você pode desenvolvê-la na bola, ou seja, você ouviu que havia algum tipo de história de usuário e imediatamente correu para codificá-la, ou pode trabalhar usando TDD. E de acordo com o TDD, como mostra a prática, não demora mais, ou seja, os testes são um efeito colateral. A prática do TDD não envolve testes. Apesar do que é chamado de Desenvolvimento Orientado a Testes, não se trata de testes. Esta também é uma abordagem arquitetônica. Esta é uma abordagem para escrever exatamente o que é necessário e não escrever o que não é necessário. Esta é uma prática de focar na próxima iteração do seu pensamento em termos de criação de uma arquitetura de aplicativo.

Portanto, não é tão fácil livrar-se dessas ilusões. MVP e testes não se contradizem. Pelo contrário, ao contrário, se você fizer MVP usando a prática de TDD, você o fará melhor e mais rápido do que se o fizesse sem prática, mas com a bola.

Esta é uma ideia muito pouco óbvia e complexa. Quando você ouve que agora escreverei mais testes e ao mesmo tempo farei algo mais rápido, parece absolutamente inadequado.

(Dmitry) Muitas pessoas aqui, quando ligam para MVP, têm preguiça de escrever algo normal. E essas ainda são coisas diferentes. Não há necessidade de transformar o MVP em algo ruim que não funciona.

Sim, sim, você está certo.

E então, de repente, MVP em produção.

Para sempre.

E o TDD parece muito incomum quando você ouve que escreve testes e parece trabalhar mais. Parece muito estranho, mas na verdade fica mais rápido e bonito assim. Quando você escreve um teste, você já pensa muito sobre qual código será chamado e como, bem como qual comportamento esperamos dele. Você não diz apenas que escrevi alguma função e ela faz alguma coisa. A princípio você pensou que ela tinha tal ou qual condição, ela seria chamada de tal ou tal forma. Você cobre isso com testes e a partir disso você entende como suas interfaces ficarão dentro do seu código. Isto tem um enorme impacto na arquitetura. Seu código automaticamente se torna mais modular, pois primeiro você tenta entender como irá testá-lo, para só depois escrevê-lo.

O que aconteceu comigo com o TDD foi que em algum momento contratei um mentor Ruby quando ainda era programador Ruby. E ele diz: “Vamos fazer de acordo com o TDD”. Pensei: “Caramba, agora tenho que escrever algo extra”. E concordamos que dentro de duas semanas eu escreveria todo o código funcional em Python usando TDD. Depois de duas semanas, percebi que não queria voltar. Depois de duas semanas tentando aplicar isso em todos os lugares, você percebe como se tornou muito mais fácil apenas pensar. Mas isso não é óbvio, então recomendo a todos que se vocês têm a sensação de que o TDD é difícil, demorado e desnecessário, tentem continuar com ele por apenas duas semanas. Dois foram suficientes para mim.

(Dmitry) Podemos ampliar essa ideia do ponto de vista da operação de infraestrutura. Antes de lançarmos algo novo, fazemos o monitoramento e depois lançamos. Neste caso, o monitoramento torna-se um teste normal para nós. E há desenvolvimento através do monitoramento. Mas quase todo mundo fala que é longo, sou preguiçoso, fiz um rascunho temporário. Se tivermos feito o monitoramento normal, entendemos o estado do sistema de CI. E o sistema CI tem muito monitoramento. Entendemos o estado do sistema, entendemos o que está dentro dele. E durante o desenvolvimento, estamos apenas fazendo o sistema para que ele atinja o estado desejado.

Essas práticas são conhecidas há muito tempo. Discutimos isso há cerca de 4 anos. Mas em 4 anos praticamente nada mudou.

Mas com esta nota, proponho encerrar a discussão oficial.

Vídeo (inserido como elemento de mídia, mas por algum motivo não funciona):

https://youtu.be/zZ3qXVN3Oic

Fonte: habr.com

Adicionar um comentário