Sobre NFSe Nacional. O que você já sabe?
A NFSe Nacional representa um significativo avanço, pois padroniza uma...
Ler mais
Publicado em 19 de novembro de 2024
Você tem uma aplicação do tipo Spring Web executada em um contêiner Docker e deseja automatizar o processo da geração de uma nova versão sempre que ocorrer um push na branch master, incluindo o build com Maven, a criação da imagem Docker e o envio da imagem versionada para o Docker Hub.
Em outras palavras, você pretende implementar um fluxo de CI/CD (Continuous Integration / Continuous Deployment) para obter agilidade, confiabilidade e escalabilidade, um processo que reflete as práticas de DevOps.
Se esse é o seu cenário, este artigo lhe mostrará como como montar uma automação deste processo utilizando o GitHub Actions. A seguir, veremos como realizar esse processo de maneira prática. Antes, porém, vamos começar com um exemplo básico, uma espécie de “Hello World”.
Siga os passos: abra o repositório no GitHub, clique em “Actions” e, em seguida, em “set up a workflow yourself”, conforme mostrado na imagem abaixo.
Ao fazer isso, o GitHub abrirá um arquivo YAML (.yml) em branco, onde será configurado o workflow. Insira os comandos mostrados no print abaixo ou, se preferir, copie o código diretamente através do link para o arquivo de exemplo, disponível logo abaixo.
https://github.com/sarquis/blockchain/blob/master/.github/workflows/main.yml
Vamos analisar os comandos. Na primeira seção, estamos nomeando o workflow como “GitHub Actions Demo”; na segunda, definimos o evento que disparará a execução, neste caso, um push na branch master. Por fim, estamos definindo o trabalho (job) a ser realizado, que, neste exemplo, será apenas exibir a mensagem “It works!”, utilizando o ambiente (runner) Ubuntu.
Após finalizar a edição do arquivo de workflow, faça o commit no repositório utilizando a opção “Commit changes”. Com isso, o processo estará concluído. Agora, para realizar um teste, faça um commit na branch master. Em seguida, acesse o seu repositório no GitHub e clique novamente na aba “Actions” para verificar a execução do workflow.
Na página “Actions”, você verá um painel com os workflows do seu repositório. Na seção “workflow runs”, estão listadas todas as execuções dos workflows, com detalhes como a data de execução, o tempo necessário para conclusão, se ocorreu uma falha, etc. Para visualizar mais detalhes da execução clique na última execução do seu workflow. Em seguida, será exibido o job executado, neste caso, “my_job_demo”. Clique no nome do job para visualizar os detalhes da execução.
Pronto! Nesta página temos os detalhes da execução do nosso job confirmando que foi executado com sucesso e que a nossa mensagem “It works!” foi exibida. Agora que adquirimos o conhecimento básico sobre o funcionamento do GitHub Actions, vamos seguir para o workflow do cenário inicial.
Vamos configurar o arquivo de workflow em partes, descrevendo o que cada seção faz. Logo abaixo, você encontrará um link para o arquivo completo de exemplo:
https://github.com/sarquis/bridge/blob/master/.github/workflows/ci-cd.yml
Começaremos definindo o nome do workflow,o evento que disparará a execução do job e o runner. Similar ao exemplo básico anterior, até aqui não há nada de novo.
name: CI/CD Pipeline
on:
push:
branches: [ “master” ]
jobs:
build:
runs-on: ubuntu-latest
Continuando, vamos definir os primeiros passos da execução. Inicialmente, realizamos o checkout do projeto, baixando o código da branch. Em seguida, configuramos a JDK que será utilizada, neste caso, a distribuição OpenJDK 17. Por último, executamos o build com o Maven. O comando “working-directory: ./bridge” indica o diretório onde está localizado o projeto Java que a ser compilado.
steps:
– name: Checkout code
uses: actions/checkout@v4
– name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: ’17’
distribution: ‘temurin’
cache: maven
– name: Build with Maven
run: mvn -B clean package -DskipTests
working-directory: ./bridge
Nos próximos passos, criaremos a imagem Docker versionada, obtendo a versão diretamente do projeto Java. A versão é obtida do pom.xml e salva na variável de ambiente “VERSION”, para ser utilizada na criação da imagem.
– name: Extract project version
id: extract_version
run: echo “VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout)” >> $GITHUB_ENV
working-directory: ./bridge
– name: Build Docker image
run: docker build -t robertosarquis/bridge:${{ env.VERSION }} .
working-directory: ./bridge
Agora vamos fazer o login no Docker Hub e remover a tag “latest” antes de enviar a nova imagem, pois deve existir apenas uma única versão com essa tag. A ideia aqui é a seguinte: sempre que você enviar uma imagem, crie duas tags: uma com a versão e outra com ‘latest’ para indicar qual é a versão mais recente. Isso ajudará na automação da atualização das imagens no servidor. Por exemplo, se você utilizar o ‘Watchtower’ (https://containrrr.dev/watchtower/) para esse fim, poderá configurá-lo para sempre atualizar o contêiner pela tag ‘latest’. Para criar os “secrets”, acesse o repositório, vá em “Settings”, clique em “Secrets and variables” e depois em “Actions”. Você encontrará a seção “Repository secrets”.
– name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
– name: Remove old latest tag if exists
run: |
if docker images –format ‘{{.Repository}}:{{.Tag}}’ | grep -q ‘robertosarquis/bridge:latest’; then
docker rmi robertosarquis/bridge:latest || true
fi
Para finalizar, vamos enviar as imagens para o Docker Hub e criar as tags (uma com a versão e outra com “latest”).
– name: Push Docker image
run: docker push robertosarquis/bridge:${{ env.VERSION }}
– name: Tag and push Docker image as latest
run: |
docker tag robertosarquis/bridge:${{ env.VERSION }} robertosarquis/bridge:latest
docker push robertosarquis/bridge:latest
Com isso, finalizamos a configuração do workflow para o nosso cenário. Espero que isso possa ajudá-lo em seus projetos de automação futuros. Observe que o cenário apresentado é bastante simples, focado em fins didáticos, mas facilmente adaptável para cenários mais complexos. Por exemplo, se você utiliza o modelo Gitflow, pode configurar workflows diferentes, como realizar um disparo quando uma nova release for criada ou uma nova tag de versão. Abaixo segue o link para o documento completo com toda a sintaxe para a montagem de workflows.
https://docs.github.com/pt/actions/writing-workflows/workflow-syntax-for-github-actions#about-yaml-syntax-for-workflows
Autores
Roberto Sarquis é Analista de Sistemas e PO NFe Master na HMIT Tecnologia
Diego Mello é Chief Technology Officer na HMIT Tecnologia | CTO