O cenário apresentado ao lado é um exemplo de como uma pipeline CI/CD pode ser definida. Todo o processo se inicia com os commits e merge/pull requests realizados do lado de um repositório Git. Esse repositório pode ser um ambiente on-premises como Gitlab, Gogs, Gitea ou até mesmo um ambiente git bare próprio. Para soluções em cloud podemos ter o Github, Gitlab Cloud ou BitBucket. Independente de qual solução esteja utilizando, o fluxo acaba sendo o mesmo, onde cada alteração submetida ao repositório pode disparar um WebHook, que funciona como um gatilho, iniciando uma chamada de API do Jenkins, informando que novas alterações existem dentro do repositório.
O Jenkins, por sua vez, clona o repositório e busca um arquivo em especial, o Jenkinsfile, esse arquivo descreve todos os passos necessários para as etapas de compilação, testes unitário (unit test), testes automáticos de aceitação (Automated Acceptence Test), testes de aceitação do usuário (User Acceptence Test), testes funcionais (Functional Test) e por fim, os não funcionais (Non-Functional Test).
Para garantir que o Jenkins consiga realizar todos os builds de diversos processos, utilizamos um ambiente Master-Slave, ou Master-Nodes, onde o Jenkins Master distribui os projetos entre os Jenkins Nodes que irão processar a pipeline para cada projeto de forma individual, para que não soframos com a falta de recursos no ambiente eles ainda podem ser configurado como um autoscaling group na AWS ou GCP. Desta maneira garantimos que sempre teremos recursos para processar novos projetos.
Durante todo o processamento do Jenkinsfile realizaremos testes para validar o funcionamento do código. É sempre recomendado que se faça uso de uma solução de Code Quality/Code Analysis, neste exemplo utilizamos o SonarQube que irá realizar a validação dos testes e da segurança da aplicação, onde é utilizado o Quality Gate do SonarQube, responsável por garantir que somente quando a qualidade do código for satisfatória teremos uma aprovação para seguir para as próximas etapas. No aspectos de segurança utilizamos ferramentas do mundo DevSecOps para análises SAST e DAST do ambiente.
Quando a qualidade do código é satisfeita, chegamos à etapa de rDeploy, que pode ser em um ambiente de homologação, desenvolvimento ou staging. Para tal, fazemos uso do Nexus, um repositório de artefatos que armazenará o resultado da compilação, que pode ser: uma imagem do Docker, Chart/Helm do Kubernetes, Arquivo Tar, Ruby Gems, pacotes Mavem para Java entre muitos outros formatos. Ao utilizar um repositório de artefatos se torna possível retornar a versões de release com muito mais facilidade, podendo inclusive utilizar técnicas como o Self-Service Deployment, onde usamos ferramentas de IaC ou gerenciadores de tarefa como RunDeck ou Control-M para fornecer um ponto central de deploy das aplicações.
Ao final chegamos ao grandioso momento de realizar o Deploy da aplicação em ambiente produtivo, esse por fim pode ser feito utilizando diversas ferramentas e técnicas de deploy como Rollout, Canary, e Blue/Green (Red/Black) para assim colocar seu novo software em Produção, podendo ainda ser hospedado na Cloud como AWS, GCP, OpenStack, ambientes de Container com Rancher, Kubernetes, Mesos, Docker Swarm ou até mesmo on-premises.
Todo esse fluxo possui um elemento de feedback, que deve sempre retornar o status de cada processo da pipeline em um canal de comunicação comum para os times envolvidos como o Slack, Rocket.chat, MS Teams, entre outros.