[Prova de conceito] CI com um script Python, Github Actions e Docker HUB
Tags: py, githubactions, docker, ci
Published: 2024-02-14 17:41:51

> Este script Python é um exemplo de um script que poderia ser utilizado em um processo de CI. Nosso objetivo é explorar como escrever um software e automatizar uma solução pra um processo de CI otimizando a esteira de desenvolvimento e implantação.

Nosso objetivo é ter um único ponto de fácil acesso via Docker HUB pra implantar em diversos ambientes com uma fácil configuração e atualização/obtenção do mesmo.

## Sumário

- [Links úteis](#links-úteis)
- [Pré-requisitos](#pré-requisitos)
- [Configurações](#configurações)
- [O que fizemos até aqui](#o-que-fizemos-até-aqui)
- [Conclusão](#conclusão)

## Links úteis

- [repositório do Docker Hub](https://hub.docker.com/r/mugarate12/ci_python_script)
- [repositório do Github](https://github.com/mugarate12/ci_python_script)

## Pré-requisitos

- [Acesso aos recursos de git hub actions](https://docs.github.com/pt/actions)
- [Acesso aos recursos do Docker HUB](https://docs.docker.com/docker-hub/)

## Configurações

Primeiro, além dos acessos ao github actions nós precisamos criar arquivos e configurações para nosso processo. Nosso objetivo é simples: automatizar o processo de buildar e mandar nossa imagem docker ao Docker HUB (o que inclui o overview lá no Docker HUB) e manter este sempre atualizado a cada _push que dermos a nossa branch main._

### Docker Hub

Você irá precisar de uma conta no Docker Hub, e dito isso, crie um repositório nele. Inclusive, já deixe o nome dele anotado, iremos logo menos.

Crie seu [token de acesso](https://docs.docker.com/security/for-developers/access-tokens/), e com ele e seu username vamos a parte mais interessante!

### Git hub Actions

Pra isso, precisaremos de um arquivo _.yml_ criado dentro da pasta _.github/workflows_ que vamos chamar de _ci.yml._

```
name: ci-python-script

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Docker Hub Description
        uses: peter-evans/dockerhub-description@v4
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
          repository: ${{ secrets.IMAGE_NAME }}
          short-description: A Python script example for Docker Hub with github actions
          readme-filepath: ./OVERVIEW_DOCKER_HUB.md

      - name: Login to DockerHub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push Docker image
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: ${{ secrets.IMAGE_NAME }}:latest
```

Vamos destacar algumas coisas desse processo:

- lá no "on" colocamos quando esse processo deve ser acionado, e evidentemente, as configurações seguintes como "push" e "branches" especificam nosso objetivo para sempre ser acionado ao dar push na main
- já adicionar "workflow_dispatch" permite que caso desejarmos acionemos nosso processo manualmente [link da documentação](https://docs.github.com/en/actions/using-workflows/manually-running-a-workflow)
- o próprio github disponibiliza n's actions [dentro de seu marketplace](https://github.com/marketplace?type=actions) pra diversos fins, aqui vamos usar os principais pra docker presentes nesse cara: [Build and Push Docker Images](https://github.com/marketplace/actions/build-and-push-docker-images)
- E por fim um cara muito especial [neste repositório](https://github.com/peter-evans/dockerhub-description?tab=readme-ov-file) que proporciona automatizar a overview que irá pro Docker Hub por meio de uma action! Note que inclusive fizemos um arquivo somente pra overview(OVERVIEW_DOCKER_HUB.md) diferente do readme.

Dado isso, vamos configurar nossas variáveis no Github, onde no seu repositório basta ir em Settings > Security > Secrets and variables > Actions e configure as variáveis
- DOCKERHUB_TOKEN
- DOCKERHUB_USERNAME
- IMAGE_NAME

![Imagem das variáveis de ambiente para Github actions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4w8u264r5tpvrg1hwel.png)

Com isso, no nosso processo push na branch main nossa action deve conseguir buildar e adicionar nossa imagem ao repositório no docker hub.

## O que fizemos até aqui

Após todo nosso processo até então visto, devemos ter algo semelhante a isso lá no nosso repositório informado na variável IMAGE_NAME:

![Imagem do docker hub pós publicação da imagem](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2b1sc2p20d1u1hvyzzv5.png)

E dado isso, poderíamos usar nossa imagem da seguinte forma:

```
docker run --rm --name ci_python_example_2 --env-file=.env mugarate12/ci_python_script:latest
```

Onde eu uso "run" pra rodar nossa image, "--rm" pra excluir o container depois do finalizar o processo realizado, "--name" adicionando um nome ao container gerado, "--env-file" pra indicar o .env que irei usar(você também pode passar as variáveis de ambiente com -e [NOME DA VARIÁVEL]:[CONTEÚDO DA VARIÁVEL]), e por fim o repositório do docker hub (que é o mesmo que informamos no IMAGE_NAME lá nas actions). Você deverá ter um resultado como esse:

![Exemplo de execução da imagem via docker hub](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t7jqymjh6cd0kutym2iy.png)

O que com isso abstrai toda a configuração de ambiente e utilitários para o funcionamento da solução.

## Conclusão

O que vimos aqui tende a ser um facilitador para implantações de soluções pequenas ou mesmo grandes, onde conseguimos usar as automações das actions do Github e o Docker + Docker Hub pra fazer um processo contínuo de integração sem a necessidade de ocupar tempo das equipes em verificar e atualizar as versões. Claro, com um bom processo de CD (Continuous Delivery) poderíamos ainda disponibilizar essa nova versão ao cliente de forma mais rápida e automatizada.

Ainda há várias incrementos que poderíamos fazer, como fazer testes automatizados via actions e somente permitir um commit ou um merge/pull request na main (pensando que estaríamos usando gitflow) caso os testes passem.

As possibilidades são muitas e tudo isso só gera mais valor e segurança pro produto que estivermos atuando.