Engenharia é um pouco como basquete
Anton Drukh
4 de agosto de 2016
0 minutos de leituraHoje quero falar sobre o objetivo da equipe de engenharia de colocar as coisas no ar e mostrar o que nos ajuda a fazer isso na Snyk. Seguimos várias práticas ao longo do nosso ciclo de desenvolvimento que funcionam bem em conjunto e nos ajudam a entregar continuamente. Vou explicar a filosofia por trás da nossa abordagem e mostrar as práticas de entrega contínua que adotamos.
Esteja sempre entregando
Entregar significa causar impacto para seus usuários, e boas organizações de engenharia estão sempre entregando. Você pode chamar isso de implantar, lançar ou colocar em produção: no fim, tudo significa a mesma coisa. Tecnologias interessantes, processos eficientes e trabalho em equipe com autonomia ajudam a alcançar esse objetivo.
Lançar uma versão a cada poucos meses é comum em organizações maiores. Isso me faz pensar em partidas de futebol: há poucos gols, com muito vai e vem pelo campo. Cada jogada exige bastante energia, e poucas dão certo.
Uma boa analogia para a entrega contínua é o basquete: quando a bola está nas mãos da sua equipe, vocês têm 24 segundos para arremessar e marcar pontos. Isso se repete tantas vezes durante o jogo que se torna a norma. Você está sempre tentando acertar a cesta e planejando apenas a jogada atual, que simplesmente não pode demorar muito. O limite de tempo é fundamental e influencia bastante a dinâmica do jogo.
Coloque tudo no ar!
Então, como transformar a entrega em um hábito? Será que funcionaria se você chegasse hoje ao escritório e anunciasse: “Vamos colocar tudo no ar em até 2 horas!”? Duvido.
A filosofia pode ser resumida em poucos princípios:
1. Enfrente os obstáculos - deixar as partes difíceis para depois nunca é uma boa escolha. Isso só incentiva a entregar mais tarde, em vez de mais cedo. Traga para o início do processo tudo o que for difícil em um lançamento. Na linguagem do basquete, ao dar de cara com um marcador, não recue para lidar com o bloqueio mais tarde.
2. Olho na cesta - um recurso é apenas o meio de entregar mais valor aos usuários, não o objetivo. Entenda o requisito e encontre a melhor relação entre valor e custo para o recurso. Na linguagem do basquete, quando a bola estiver nas suas mãos, olhe para a cesta e faça o que é mais simples.
3. Falhe rápido - todo recurso tem riscos: não tente elaborar um plano à prova de falhas. Se algo não vai funcionar, descubra logo e recomece. Na linguagem do basquete, é melhor arremessar e errar do que ouvir o apito do árbitro depois de 24 segundos.
Bons merges são merges que não acontecem
Quais são as partes difíceis de uma entrega que ficam ainda mais difíceis quando não são enfrentadas o quanto antes?
Um desses pontos críticos é juntar suas alterações às de outras pessoas. Fazer merges pode ser um inferno. Tudo aquilo de que gostamos de falar quando dizemos “responsabilidade compartilhada pelo código” vai por água abaixo quando me deparo com 10 arquivos, cada um com dezenas de conflitos. Pense naquela jogadora de basquete: correndo pela quadra em direção à cesta, ela precisa deixar a bola de lado, pegar uma pá e cavar um monte de... terra. A energia do jogo se esvai e, na próxima vez que receber a bola, ela vai procurar a pá, não a cesta.
Uma forma de evitar isso é dividir as responsabilidades de maneira rígida, para que, durante uma sprint, as pessoas não trabalhem no mesmo código que seus colegas. Embora essa técnica possa funcionar em um ambiente controlado, esse não é o ambiente em que trabalhamos. Divisões rígidas como essa vão contra a responsabilidade compartilhada e incentivam uma abordagem de engenharia em silos. Isso não dá autonomia à equipe e prejudica o crescimento pessoal. É melhor evitar.
Nossa abordagem é dar passos menores. Lembre-se da última vez que você teve um merge enorme, cheio de conflitos para resolver: quanto tempo ficou programando antes dele? Semanas? Dias? Não deveria surpreender que o código tenha mudado nesse período: as pessoas estão trabalhando ao seu redor. Ao escrever a primeira linha de código do seu próximo recurso, pense adiante. Visualize a cesta que você quer acertar: quando vai enviar isso para a branch do recurso? Melhor ainda, quando vai para produção? Se a resposta for mais de meio dia de trabalho, repense seu plano. Você não quer ouvir o apito do árbitro depois de 24 segundos.
Avance mais rápido com feature flags
Na Snyk, trabalhamos em branches individuais, que são abertas, enviadas, revisadas, integradas e implantadas em questão de horas. Para recursos maiores, cujo desenvolvimento avança aos poucos ao longo de alguns dias, usamos feature flags para colocar as mudanças em produção no mesmo ritmo, mesmo que o recurso ainda não esteja totalmente pronto. A premissa é que o próprio código é a melhor documentação, e não algum documento de design de arquitetura. Se você guardar seus planos em uma branch privada, além de não estar mirando em uma entrega rápida, também não estará ajudando as pessoas ao seu redor a avançar mais rápido. Lembre-se dos 24 segundos.
Bons testes são testes antecipados
Outro ponto crítico na hora de lançar é fazer testes. Testes são ótimos, mas o momento em que são feitos pode fazer toda a diferença. Descobrir, minutos antes da implantação, que algo não funciona como você imaginava é muito mais desafiador do que fazer a mesma descoberta minutos depois de escrever aquele código imperfeito. Pense em toda a mudança de contexto: procurar a causa do bug, interromper a partida de basquete no meio do jogo etc. Nada bom.
Embora não sejamos estritamente orientados a TDD, ter uma suíte de testes abrangente que roda localmente e em cada pull request nos mantém no caminho certo. Nosso foco é facilitar a escrita dos testes e executá-los rapidamente. Parece simples, mas exige muita atenção e, acima de tudo, responsabilidade. É como amarrar os cadarços antes do jogo: se você entende que isso ajuda a marcar pontos, vai se dedicar.
Agora, vamos às medidas práticas: adicionamos testes aos novos recursos, especialmente ao corrigir bugs incômodos que chegaram à produção. Nossos repositórios no GitHub estão integrados ao Travis CI, que executa a suíte de testes em cada pull request e após os merges para develop e master. Quando os testes passam em develop e master, uma implantação automatizada é iniciada, respectivamente, nos nossos ambientes de desenvolvimento e produção, completando nosso ciclo de entrega contínua. Temos uma opção manual para cancelar a implantação após um merge, usando uma string secreta na mensagem do commit. Fico muito feliz que seja uma opção de cancelamento, e não de adesão. Não me lembro da última vez que a usamos.
Trabalho em equipe é fundamental
O que faz tudo isso funcionar é o acordo entre as pessoas da equipe para entregar rápido. Merges simples dependem do esforço de todos, assim como uma suíte de testes confiável. Isso exige tempo, dedicação e responsabilidade. Converse sobre os pontos críticos do processo de lançamento da sua equipe e faça mudanças incrementais. Prefira pequenas vitórias rápidas a grandes reformulações.
Tem uma analogia melhor que a minha sobre basquete? Quer compartilhar dicas que fazem sua equipe funcionar? Conte para a gente no Twitter.
Comece a participar de desafios de Capture the Flag
Aprenda a resolver desafios de Capture the Flag assistindo sob demanda ao nosso workshop virtual introdutório.