Começo o post com a imagem acima, que descreve bem como era o nosso processo de deploy aqui na Zygo, e abaixo quero contar como mudamos isso separando deploy de release e diminuindo muito os impactos causados aos nossos clientes.
No meio do ano passado(2018), eu estava lendo o livro Accelerate, que é sobre uma pesquisa conduzida por 4 anos por Nicole Forsgren, Jez Humble e Gene Kim para entender as práticas e processos de devops utilizados nas empresas de tecnologia.
O livro usa a pesquisa como pano de fundo para definir comportamentos que levam as empresas a serem high, medium ou low performers em relação a entrega de software, e uma das métricas que ele usa para isso é a frequência de deploy, e a conclusão deles a partir dos dados da pesquisa foi de que as empresas que melhor performam são as empresas que fazem cada vez mais deploy para cada desenvolvedor à medida que mais desenvolvedores entram no time. Ou seja, se o time tem 5 desenvolvedores e faz 5 deploys por semana, com 10 desenvolvedores fariam mais de 10, se antes era um deploy por cada desenvolvedor, passaria a ser mais de um essa relação.
Apesar de muitas vezes parecer óbvia essa conclusão, pois se o objetivo é entregar software, quanto mais deploy fizermos mais software estaremos entregando, certo? Mas nem sempre isso é claro, e o deploy em muitas empresas também tem o lado ruim, de experiências com bugs sendo colocados em produção, etc.
Bom, feita toda essa introdução, vamos para onde quero chegar. No momento em que eu lia esse livro, como líder da área de engenharia da Zygo, eu já estava incomodado com o nosso processo de deploy, mas faltavam dados e uma certeza maior de como resolver, e com os dados da pesquisa do livro eu tive a certeza que estávamos no caminho das empresas de baixa performance avaliadas por eles. O que tínhamos na época era o desenvolvimento sendo feito com a utilização de 3 branches separadas, development , staging e master , os deploys para produção tinham que ser agendados e organizados em conjunto com as outras áreas da empresa para não pegar ninguém de surpresa e tínhamos o caos acontecendo toda vez que tínhamos que passar o código em desenvolvimento para a master para colocar em produção com os problemas de conflitos, de código desatualizado, etc.
A certeza de que a gente precisava mudar isso urgentemente eu já tinha, mas precisava decidir por onde começar. O primeiro passo foi refletir sobre o que tinha feito a gente chegar onde estávamos, e chegamos nesse processo que tínhamos por dois motivos:
- Experiência ruim de deploys passados com muitos bugs : a quebra do desenvolvimento em 3 branches, com a idéia de colocarmos a branch de staging no ambiente de testes 1 semana antes para a empresa testar e encontrarmos os bugs antes de ir para produção foi para tentar melhorar esse ponto
- Falta de alinhamento com o time de CS e de vendas: CS e vendas eram pegos desprevenidos com um deploy que alterava alguma funcionalidade quando eles estavam no meio de uma call com o cliente/lead, e como não havia alinhamento da mudança, eles não sabiam como utilizar a funcionalidade alterada e acabavam gerando insegurança no cliente/lead.
Refletindo e chegando nos motivos, ficou mais claro ainda que o processo que implementamos por causa deles não estava funcionando, pois ele não tinha ajudado a resolver nenhum dos dois problemas que citei acima.
Refletindo novamente sobre os dois problemas, cheguei a conclusão que o que de fato causava isso era que o nosso release estava atrelado ao deploy, ou seja, colocar um código novo em produção significava também disponibilizar as alterações ou nova features para os nossos clientes no mesmo momento. Opa, finalmente chegamos no problema raiz, encontramos o que de fato precisávamos mudar no processo.
Com o problema definido, fomos em busca da solução e o maior desafio era mudar o processo de desenvolvimento dos desenvolvedores do time. Quem é ou já foi desenvolvedor, sabe que o fluxo normal quando é pedido uma alteração em uma funcionalidade é o desenvolvedor começar apagando ou alterando código, mas se o objetivo que queremos é podermos fazer deploy das alterações e novidades sem que elas apareçam para o cliente no momento do deploy, precisamos manter o código antigo e o novo convivendo simultaneamente em produção, ou seja, o desenvolvedor não pode simplesmente alterar o código do projeto, ele precisa desde o início do desenvolvimento pensar em como manter o código atual e adicionar o novo sem causar nenhum bug no funcionamento atual. Para isso ecolhemos uma ferramenta de feature toggle, no nosso caso escolhemos a gem flipper e começamos a criar a cultura e o mindset dentro do time de desenvolvimento de trabalharmos de forma a tornar isso possível.
Depois de alguns meses trabalhando dessa forma, conseguimos de fato colher os resultados, onde as maiores vantagens foram:
- Se tornou possível validar hipóteses e idéias em produção com poucos clientes, escolhendo quem queremos que teste as novidades para nos permitir coletar mais informações antes de lançarmos para a base toda;
- Os bugs e problemas de usabilidade foram descobertos enquanto a novidade estava sendo utilizada por poucos clientes, causando um impacto muito menor do que se tivesse sido descoberto depois de ter sido lançado para todos os clientes;
- Conseguimos diminuir o atrito do release junto às outras áreas da empresa, tendo tempo para gerar materiais de educação tanto para nossos clientes como para a própria empresa sobre as novidades;
- Apesar de todas essas vantagens, conseguimos fazer todos os releases disponibilizando para 100% dos nossos clientes em menos de 2 semanas sempre, as vezes em menos até do que 1 semana;
- O código da master estava sempre atualizado e pronto para ser colocado em produção, sem termos que nos preocupar com o que o deploy poderia causar de impacto nos nossos clientes;
- A quantidade de deploys feitos pelo time de desenvolvimento aumentou, mas isso hoje passa despercebido do restante da empresa, pois a única coisa que impacta eles e nossos clientes é de fato o release.
Bom, colocando dessa forma parece que é a bala de prata para qualquer time de desenvolvimento conseguir entregar com mais qualidade, facilidade e agilidade, mas tudo tem seu preço e lado negativo. Com o uso do feature toggle, o código começou a ter ifs e condições sendo checadas para ver para quem cada alteração e/ou novidade pode ou não aparecer. A longo prazo isso é um débito técnico que tornaria o código mais difícil de ser mantido, corrigido e melhorado, por isso é muito importante que trabalhando dessa forma se crie uma rotina de que após o release estar completo e disponível para 100% da base de clientes, o time volte no código para limpar os ifs e condições que foram colocados para permitir o feature toggle, e também para limpar o código que se tornou antigo e não é mais utilizado, mantendo assim a qualidade do código do projeto em relação a manutenção futura principalmente.
Para quem tiver interesse no livro que citei, nesse post tem um bom review falando mais sobre o livro.
Seguem alguns links sobre a prática de feature toggle para quem quiser ler mais sobre isso também:
- https://martinfowler.com/articles/feature-toggles.html
- https://www.infoq.com/br/presentations/feature-toggles-os-2-lados-do-poder
- http://featureflags.io/
- https://stackoverflow.com/questions/7707383/what-is-a-feature-flag
- https://medium.com/jettech/feature-toggles-give-you-superpowers-78fdeb7ab5e8
Top comments (0)