Ferramentas para automação de pipelines de desenvolvimento e entregas: Jenkins, GitHub Actions, GitLab CI, CircleCI ou Travis CI
Ferramentas para automação de pipelines de desenvolvimento e entregas: Jenkins, GitHub Actions, GitLab CI, CircleCI ou Travis CI
[editar | editar código]Introdução a Integração Contínua e automação
[editar | editar código]Nos processos modernos de desenvolvimento de software, tornou-se comum a prática da Integração Contínua (CI), que determina um modo de desenvolver software em que desenvolvedores são encorajados a integrar o código desenvolvido à versão principal com maior frequência e o processo de integração do código deve ser elaborado de forma automatizada e eficiente. A fim de contemplar o segundo ponto, existem diversos serviços de CI consolidados no mercado, sendo os principais: Jenkins, GitHub Actions, GitLab CI, CircleCI e Travis CI. Este tutorial abordará a implantação de um servidor Jenkins para ilustrar o workflow básico de configuração de pipelines de CI.
Configuração Inicial do Jenkins
[editar | editar código]O Jenkins, diferente de outros serviços populares de CI, é oferecido exclusivamente como um servidor a ser inteiramente configurado e gerenciado pelo usuário.
O Jenkins pode ser localmente instalado na máquina, mas é recomendável utilizá-lo como container Docker. Rode o container oficial com docker run -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:lts-jdk17 e acesse sua interface web pelo localhost:8080.
Ao inicializar pela primeira vez, haverá um instalador para a inserção de configurações básicas e download de plugins iniciais. No Jenkins, grande parte das funcionalidades são implementados em plugins desenvolvidos pela comunidade, que devem ser instalados separadamente.
No final do processo, a dashboard do Jenkins será apresentada.
Configuração de agentes
[editar | editar código]O Jenkins segue uma arquitetura distribuída para computação das pipelines de CI. Isso significa que o servidor que roda no device controlador (servidor) delega a execução das pipelines de CI a outros devices da rede e previamente configurados como agentes.
A configuração de um agente é relativamente complexa, pois vários tipos de agentes podem ser configurados, geralmente divididos em duas categorias:
- Cloud: Uma cloud no Jenkins é um serviço externo que provê agentes para execução de pipelines dinamicamente conforme a demanda. Exemplos incluem:
- Cluster Kubernetes que fornece pods como agentes
- Serviço de Cloud (AWS, Azure, GCP) que fornece recursos de cloud para execução de automações do Jenkins
- Daemon do Docker que provê containers específicos para cada pipeline a ser executada
- Node: Um node é uma instância de agente fixa. Geralmente representam máquinas físicas, containers e VMs estáticos conectados à rede e que executam as pipelines a partir da conexão SSH entre o controlador e o agente (mas outros tipos de conexões podem ser usados)
A maior dificuldade de configurar um agente no Jenkins consiste no fato de que cada tipo de agente diferente tem sua implementação em um plugin específico, que deve ser acoplado ao Jenkins e configurado de acordo com a documentação própria do plugin.
Para facilitar o tutorial, configuraremos nosso agente usando um plugin simples do Jenkins, que permite a definição do agente como container Docker, pela própria definição da pipeline a ser executada. Note que esse plugin não é igual ao plugin que permite configurar uma Docker Cloud, pois este requer a configuração fora da pipeline, mas pelo próprio Jenkins.
A única exigência para usar o plugin de Docker Pipeline é garantir que o controlador possui acesso ao Docker local. Para o nosso contexto em que o Jenkins já está em um container docker, é necessário montar o socket do docker no container. Isso é feito pela flag -v no comando de execução do container previamente fornecido.
Configurando uma pipeline simples
[editar | editar código]Crie um freestyle job para o Jenkins. Esse tipo de job é o mais simples e sua definição pode ser escrita pela própria interface web do Jenkins, ao invés de um arquivo Jenkinsfile.
A pipeline usa a sintaxe da linguagem Groovy e o job e um template básico do job pode ser visto abaixo:
================================================================================
[editar | editar código]pipeline {
agent {
docker {
image 'ubuntu:latest'
}
}
stages {
stage('Install dependencies'){
steps {
sh 'apt update -y'
sh 'apt install -y b4 git bc binutils bison dwarves flex gcc git gnupg2 gzip libelf-dev libncurses5-dev libssl-dev make openssl pahole perl-base rsync tar xz-utils'
}
}
stage('Setup git configs'){
steps{
sh 'git config --global user.email "jenkins@ci.com"'
sh 'git config --global user.name "jenkins"'
}
}
stage('Test tinyconfig Compilation'){
steps {
sh 'rm -rf linux'
sh 'git clone --depth 1 "https://gitlab.freedesktop.org/agd5f/linux.git" linux'
dir("linux"){
sh "b4 shazam https://lore.kernel.org/amd-gfx/20241121131055.535-1-shashank.sharma@amd.com/T/#t"
sh 'make tinyconfig'
sh 'make'
}
}
}
stage('Cleanup'){
steps {
sh 'rm -rf linux'
}
}
}
}
================================================================================
[editar | editar código]Percebe-se que a pipeline define, primeiramente o agente. Como o plugin da Docker Pipeline está sendo utilizado, basta definir a imagem do container. Para agentes estáticos (nodes), seria necessário definir a tag do job que poderia rodar a pipeline.
O segundo passo é a definição dos estágios da pipeline. Cada estágio é definido em passos sequenciais. No exemplo acima, cada passo é uma execução de comando shell (Usando o comando sh '<comando a ser utilizado>'). Existem outros tipos de comandos de pipeline, como o echo que imprime um valor ou outros comandos exclusivos implementados por plugins. O Jenkins contém um Snippet Generator que auxilia a encontrar a sequência desejada de comandos. Também é possível ver toda a documentação de sintaxe, que contém tópicos mais avançados não citados aqui, como paralelismo, pipelines parametrizadas, etc.
A pipeline de exemplo acima é simples:
- Instala dependências para compilação do kernel
- Configura o git
- Clona o repositório do Kernel Linux para o subsistema amd-gfx.
- Aplica um patch do kernel ao repositório
- Configura uma compilação minimal do kernel (tinyconfig)
- Compila o kernel
- Faz a limpeza do ambiente pós-validação, removendo artefatos gerados
A pipeline pode ser manualmente ativada pela dashboard. Certifique-se de que esteja logado na interface web com o usuário com privilégios necessários (configurado na primeira vez que o Jenkins foi acessado).
Essa pipeline acima representa uma pipeline automatizada de build de uma imagem de kernel. Uma pipeline de testes automatizada, analogamente, utilizaria do programa compilado pela build e rodaria uma sequência de outros comandos para a execução de testes unitários, de integração, etc.
Próximos passos para entender Jenkins
[editar | editar código]Esse tutorial cobriu os passos básicos e necessários para rodar uma pipeline Jenkins. A seguir estão algumas sugestões de coisas a serem feitas a seguir para um uso mais avançado da ferramenta:
- Integrar o Jenkins a um repositório no GitHub. Isso pode ser feito com o GitHub Branch Source plugin. Acesse a documentação oficial para configurá-lo corretamente.
- Configurar o Jenkins como código. No tutorial, configuramos manualmente a instalação dos Jobs e servidor Jenkins, mas isso pode ser completamente definido em texto e carregado automaticamente ao implantar o servidor Jenkins. Veja a documentação dos plugins Jenkins Configuration as Code e Job DSL.
Sobre outros serviços de CI
[editar | editar código]Outros serviços de CI possuem finalidade semelhante ao Jenkins, mas podem diferir em certos detalhes. GitHub Actions e GitLab CI possuem a configuração de pipelines com YAML e maior integração com repositórios caso estes estejam sendo hospedados no respectivo serviço.
A lógica principal da automação de pipelines de CI, entretanto, segue a mesma para qualquer serviço de CI a ser utilizado.