Actions são tarefas individuais que podem ser combinadas para criar jobs (trabalhos) e personalizar workflows (fluxos de trabalho), ajudando a diminuir a quantidade repetitiva de código. Você pode utilizar as actions publicadas no GitHub Marketplace ou criar e customizar suas próprias actions.
O GitHub Actions permite criar 3 tipos de actions customizadas: Javascript, Composite e Docker Container. Nesse artigo, vamos entender sobre Docker Container Actions (DCA), como implementar sua primeira Docker action e testá-la em um GitHub workflow.
Docker container permite que você crie actions customizadas empacotando o ambiente com o código da action. Dessa forma, quem consumir sua action não precisa se preocupar com as dependências necessárias para executá-la, basta referenciar a action em seu workflow e executar, pois ela já conterá todos os componentes necessários para execução.
DCA é a opção ideal para actions que precisam ser executadas em ambientes com configurações específicas, já que permite personalizar o sistema operacional, as ferramentas, código e dependências sem necessitar adicionar ao runner (executor), basta apenas o runner possuir o Docker e é possível executar no mesmo runner diversas Docker actions e cada uma com sua personalização.
Você também pode utilizar DCA quando Javascript actions não for uma opção, seja por querer utilizar uma versão específica do Node, já que Javascript actions utilizam Node(16) ou até mesmo por familiaridade com outras linguagens, já que com Docker container é possível construir actions utilizando suas linguagens favoritas, seja Python, Go, Bash, Ruby e entre outras.
Agora vamos entender e executar os passos necessários para criar DCA, e teremos então uma Docker container action desenvolvida em Python que faz uma chamada a API do GitHub para listar branches de um repositório público.
SO Linux e Docker: Para rodar DCA, os runners auto-hospedados precisam utilizar o sistema operacional Linux e ter o Docker instalado, mas você pode utilizar os runners hospedados no GitHub, que são gerenciados pelo GitHub e já possuem o Docker, como por exemplo ubuntu-latest
.
Repositório: Antes de iniciar, é necessário criar um repositório GitHub.
Crie um novo repositório GitHub: Vamos utilizar list-branches-docker-action
como nome do repositório, mas você pode criar com o nome que preferir. Para informações de criação de repositórios, consulte: Criando um novo repositório.
Clone o repositório: Após criar o repositório, clone em sua máquina. Saiba mais em: Clonando repositório.
Mude o diretório: Em seu terminal, execute o comando a seguir para mudar o diretório para o novo repositório:
cd list-branches-docker-action
No diretório raiz list-branches-docker-action
, vamos criar o arquivo main.py
que conterá o código escrito em Python que a action irá executar:
# Código da action
import requests
import json
import sys
r=requests.get("https://api.github.com/repos/"+sys.argv[1]+"/"+sys.argv[2]+"/branches", headers={"Accept": "application/vnd.github+json" ,"X-GitHub-Api-Version":"2022-11-28"})
objeto = json.loads(r.text)
print("\nLista de branches do repositório "+sys.argv[2]+ " :")
for v in objeto:
print(v['name'])
Esse script faz uma chamada a API do GitHub https://api.github.com/repos/OWNER/REPO/branches
, que recebe dois parâmetros: OWNER
, representando o proprietário do repositório e REPO
, que representa o nome do repositório do qual iremos listar as branches.
Para fazer essa chamada, inicialmente importamos os módulos necessários. Sendo requests
, que possibilita realizarmos chamadas http, json
para trabalharmos com os dados JSON e sys
para manipularmos os parâmetros que são passados na execução do programa.
Onde fazemos a chamada da API, substituímos os argumentos OWNER
e REPO
por sys.argv[1]
e sys.argv[2]
correspondente, pois esses parâmetros serão atualizados com os valores passados como argumento para o contêiner.
Por fim, convertemos o json da resposta da API em um objeto Python Dictionary para conseguirmos percorrer esse objeto e trazer apenas o nome das branches.
Com o código da action definido, seguindo a sintaxe e os padrões descritos em Suporte do arquivo Docker para GitHub Actions criamos o arquivo Dockerfile
que será utilizado para criar a imagem que conterá o código da action.
#Imagem de contêiner que executa o código da action
FROM python:3.8-alpine
RUN pip install requests
COPY main.py /main.py
ENTRYPOINT ["python", "/main.py"]
Estamos utilizando python:3.8-alpine
como base para nossa imagem, pois já inclui o Python. Com o comando RUN pip install requests
Instalamos as bibliotecas necessárias para execução da action que são importadas no arquivo main.py
, depois copiamos o arquivo que contém o código da action (main.py)
para dentro do contêiner e ao final em ENTRYPOINT ["python", "/main.py"]
adicionamos uma instrução para que o Docker execute o arquivo main.py
assim que iniciar o contêiner. Dessa forma, estamos adicionando as dependências da action diretamente na imagem do contêiner juntamente com o código da action. Então, ao executar a imagem ela iniciará um contêiner com a action e suas dependências.
Note que estamos apenas instalando a biblioteca requests, pois json e sys são pacotes que já vêm integrado com o Python.
No diretório list-branches-docker-action
, criamos um arquivo action.yml
que contém toda a definição da action, como descrição, inputs (entradas) e outputs (saídas).
#action.yml
name: 'List Branches Docker Action'
description: 'Lista branches de um repositório público'
branding:
icon: 'git-branch'
color: 'blue'
inputs:
owner: # id do input
description: 'Sua organização ou usuário github'
required: true
repo: # id do input
description: 'Nome do repositório' # que possui as branches a serem listadas
required: true
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.owner }}
- ${{ inputs.repo }}
No action.yml
acima, definimos o nome, descrição da action e o ícone e a cor que representará a action, caso deseje publicar no GitHub Marketplace.
Para passar os argumentos para o Docker container, precisamos declarar os inputs
e então passá-los como argumento usando args
. Em nosso arquivo, temos os inputs obrigatórios owner
e repo
, que são passados como argumentos inputs.owner
e inputs.repo
, pois serão utilizados para atualizar os parâmetros sys.args[1]
e sys.argv[2]
definidos em nosso arquivo main.py
.
inputs:
owner: # id do input
description: 'sua organização ou usuário GitHub'
required: true
repo: # id do input
description: 'nome do repositório' # que possui as branches a serem listadas
required: true
runs:
args:
- ${{ inputs.owner }}
- ${{ inputs.repo }}
Precisamos especificar a imagem que será utilizada para iniciar o contêiner que contém o código da action. Na sessão run
passamos a propriedade using
como docker
e podemos definir a imagem de 2 formas:
Usando o arquivo Dockerfile presente no repositório da action:
runs:
using: 'docker'
image: 'Dockerfile'
Assim como em nosso action.yml
, quando passamos Dockerfile
em image
, o GitHub runner construirá uma imagem a partir desse Dockerfile e iniciará um contêiner que executará o código definido em main.py.
Usando uma imagem de um Docker registry:
runs:
using: 'docker'
image: 'docker://geovana10/list-branches-docker-action:v1'
Ao utilizar uma imagem de um Docker registry, o GitHub runner não precisa construí-la, basta realizar pull (recuperação) dessa imagem, buscando ela e executando-a para iniciar o contêiner contendo o código da action.
Devido a latência que o runner tem de construir e recuperar a imagem, as Docker actions costumam ser mais lentas que Javascript actions.
Após a criação dos arquivos main.py
, Dockerfile
e action.yml
, podemos fazer o commit (confirmação), realizar o push (envio) para nosso repositório do GitHub e adicionar uma tag , que será utilizada posteriormente para identificar a versão da nossa action. No diretório local list-branches-docker-action
, execute:
git add .
git commit -m "my actions file"
git tag -a v1 -m "Primeira versão list branches tag"
git push --follow-tags
Com a action disponível em nosso repositório, já podemos testá-la em um GitHub workflow. As actions públicas podem ser utilizadas em qualquer repositório, mas podemos ter actions em repositório privado onde podemos controlar o acesso e podemos publicá-las no GitHub Marketplace. Para mais informações, veja Publicar actions no GitHub Marketplace.
Para usarmos a action, precisamos ter um arquivo .yml no diretório .github/workflows
, então nesse diretório criamos o arquivo main.yml
, que é executado sempre que for realizado um push na branch main do repositório.
on:
push:
branches: [ main ]
jobs:
List-Branches:
runs-on: ubuntu-latest
name: Job para listar Branches de repositório GitHub
steps:
- name: Listar Branches action step
id: list
uses: geovanams/list-branches-docker-action@v1
with:
owner: 'geovanams'
repo: 'public-repo'
Esse workflow possui um único job chamado List-Branches
que executará o step (etapa) List Branches action step
. Nesse step em uses
chamamos a action que criamos anteriormente.
Como a action está em um repositório público, estamos definindo a action usando a seguinte sintaxe: geovanams/list-branches-docker-action@v1
, que você pode substituir com as suas informações, onde temos o nome do usuário GitHub ou organização, em seguida o nome do repositório e então @v1
representando a versão da action, que corresponde a tag que criamos anteriormente, mas podemos versionar usando commit ID ou até mesmo o nome da branch. Para mais informações sobre como gerenciar versão de actions com tags e releases, visite: Melhores práticas para gerenciamento de versões
Para passarmos os parâmetros da action, utilizamos o atributo with
. Nesse workflow, passamos os parâmetros owner
e repo
que você pode substituir os valores pelo proprietário e nome do repositório do qual deseja listar as branches.
uses: geovanams/list-branches-docker-action@v1
with:
owner: 'geovanams'
repo: 'public-repo'
Após salvar o arquivo no repositório, o GitHub já iniciará o workflow. Na aba Actions, podemos visualizar os logs de execução do job e steps do workflow.
Lista de steps do workflow que foi executado
Note que temos 2 steps principais:
1- Build geovanams/list-branches-docker-action@v1: Como definimos Dockerfile
em nosso arquivo action.yml
, o GitHub adicionou esse step de build para construir a imagem a partir do arquivo Dockerfile presente no repositório.
Log do step de build construindo a imagem
Como dito anteriormente, se utilizarmos a imagem de um Docker registry, para recuperar a imagem o GitHub adicionaria o step de pull ao invés do de build. Exemplo:
Log do step de pull recuperando a imagem do Docker registry
2 - Listar Branches action: Esse é o step que de fato chamamos a Docker action, ele mostra os parâmetros passados para action e o resultado de sua execução, listando então todas as branches do repositório definido.
Log do step Listar Branches action trazendo os parâmetros e a lista de branches
Criar um README é uma ótima maneira de definir como as pessoas devem utilizar suas actions. No diretório raiz list-branches-docker-action
criamos o arquivo README.md
, que contêm as informações necessárias de como utilizar a action que criamos.
# List Branches Docker Action
Essa action lista as branches de um repositório público.
## Inputs
## `owner`
**Required** Sua organização ou usuário GitHub que possui o repositório do qual deseja listar.
## `repo`
**Required** nome do repositório que possui as branches a ser listadas.
## Example usage
uses: geovanams/list-branches-docker-action@v1
with:
owner: 'geovanams'
repo: 'public-repo'
Ao concluir os passos anteriores, teremos então um repositório estruturado da seguinte forma:
.
├── .github/workflows
│ └── main.yml
├── Dockerfile
├── README.md
├── action.yml
└── main.py
Você pode baixar essa estrutura com o código completo da Docker action do repositório GitHub List-Branches-Docker-Action.
Docker Container Action é uma excelente escolha para a criação de actions personalizadas que requerem linguagens ou configurações específicas. Com ela, você pode criar actions da maneira que preferir e usando as linguagens que desejar. Neste artigo, explicamos o que são Docker container actions, quando devem ser usadas e como criá-las e testá-las em um GitHub workflow.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.