A esteira, a máquina e o carimbo: CI/CD explicado com um jogo
Toda vez que a gente escuta CI/CD parece aquele assunto complicado, cheio de YAML, configuração e termo técnico. Mas no fundo a ideia é bem simples e dá pra entender sem escrever uma linha de código.
Nesse post eu quero explicar o que é CI/CD em alto nível, usando analogias do dia a dia (e até de um jogo que andei jogando) pra mostrar que, no fim das contas, é só automatizar aquilo que você já faz na mão.
Comparação trabalho manual x com CI/CD
Imagine que precisamos publicar um componente. Angular, React ou Vue, tanto faz. Se você trabalha com essas tecnologias provavelmente deve seguir esses passos: buildar o componente, rodar os testes para garantir que tudo está como deveria e, para publicar no npm, rodar um simples publish. Legal, você publicou seu componente. Porém imagine que são 60 componentes, imagine que você ajustou um bug que envolveu dois deles. Será necessário publicar na mão e, enquanto isso, os outros desenvolvedores do time também precisam fazer suas publicações na mão.
O CI/CD resolve essa dor, e não somente a de publicação. Algo que é feito manualmente pode ser automatizado por uma pipeline, se isso fizer sentido no seu contexto. Buildar o componente para garantir integridade, rodar os testes, publicar, subir um ambiente de staging, pq não? Ferramentas de segurança, SonarQube? Publicar imagens Docker e outros.
Analogia com Parcel Simulator
Recentemente joguei e vi um jogo muito interessante que é o Parcel Simulator. Basicamente você é um funcionário que precisa validar pacotes (imagine que são entregas dos correios) e fazer uma série de verificações para ganhar dinheiro e evoluir essa empresa.
O interessante é que podemos fazer uma série de comparações com a programação, como: o dia no jogo inicia com uma esteira trazendo esses pacotes até você, depois você precisa validar (peso, país, número de série, tipo de entrega), e essas validações aumentam com o tempo. Chega um momento em que você precisa olhar tantas coisas e ser tão rápido para não atrasar que acaba ficando fácil de errar.
Então, depois de algumas entregas e com um dinheiro guardado, você consegue adicionar máquinas que fazem esse serviço para você e, se elas deixarem passar, adivinha? Você consegue "carimbar com aprovado e reprovado". Para mim isso é CI/CD puro:
Mas antes de tudo, quem liga a esteira? No jogo o dia começa e os pacotes chegam sozinhos, já na nossa pipeline quem dá o start é você. Um push no código ou um merge naquela branch é o que acende a esteira e começa o expediente.
A esteira do jogo é a nossa pipeline, ela irá levar nosso código adiante, fazendo ele passar pelos diversos passos.
No jogo, existe a máquina que verifica se o peso do pacote é correto. Na nossa pipeline CI/CD podemos rodar os testes para ver se não teve regressão 🤷🏽♂️.
E vamos além: no jogo compramos a máquina diretamente, a máquina que vai validar o peso, o país, etc... mas podemos imaginar que cada máquina tem um software instalado, igual no CI/CD. Precisamos instalar o Node para rodar JS, não? E para instalar, npm install!
Depois de instalar e rodar todos os processos, vem o quê?
Claro, a aprovação ou rejeição, passou ou não passou!
E aqui vem a parte que eu acho mais importante: o que acontece quando reprova? No jogo, se você deixa um pacote errado passar, adivinha? Toma penalidade. Na pipeline é parecido, só que a favor: quando algo reprova, a esteira trava ali mesmo e o componente quebrado não segue pra frente.
Reprovou, a esteira para. Aquele componente com bug não é publicado no npm, não chega nos outros devs do time e não vai quebrar as telas das aplicações que consomem ele. E de brinde, a pipeline ainda te mostra em qual passo quebrou, se foi no build ou num teste.
No fim das contas é esse "segurar antes de estragar" que faz o CI/CD valer tanto a pena.
Na prática
No fim das contas, o CI/CD só é uma outra máquina rodando os mesmos passos que você faria para chegar em um ponto final. Ou seja, você está no ponto A, com o bug corrigido, e quer chegar no ponto B, entregar essa correção em produção ou o que quer que seja esse "entregável" no seu contexto.
Essa máquina pode ser uma action do GitHub, pode ser uma máquina na nuvem (que é engraçado, uma máquina na nuvem só é uma máquina que não está no mesmo espaço físico que o seu). Pode ser uma máquina no mesmo espaço físico, a sua própria máquina, um server particular, um homelab e etc... Existe documentação para rodar esses runners e não depender da nuvem, tendo mais controle, porém, lembre que o CI/CD são os mesmos passos da sua máquina. Logo, deve ter Node instalado, npm, dotnet, Java, dependendo da funcionalidade. Você precisa conseguir se autenticar em alguma plataforma para pegar dados, tem que passar variáveis de ambiente para configurar algo, etc...
Quis passar a ideia de como funciona sem entrar em código, e eu particularmente gosto de fazer analogias e comparações no estudo pois acredito que facilita bastante.
E você, já implementou uma pipeline CI/CD no seu trabalho, utiliza nos projetos pessoais ou está na fila?
E claro, tem ferramentas mais avançadas para trabalhar com entrega e integração contínua.
No meu trabalho eu uso bastante a Azure e ela tem uns recursos bem interessantes pra usar nas pipelines. Dá pra publicar seus pacotes num feed privado com o Azure Artifacts (lembra da dor de publicar os componentes no npm?), rodar seus próprios agentes self-hosted quando você quer mais controle e não depender só da nuvem, guardar variáveis e segredos com segurança e por aí vai. Deixei alguns links oficiais abaixo pra quem quiser se aprofundar.