Um pouco sobre GitHub Actions

Ingryd Moura
hurb.labs
Published in
5 min readAug 24, 2021

Como o próprio título deste artigo propõe, irei falar um pouco sobre alguns conceitos e pontos de atenção na utilização do GitHub Actions durante o seu processo de automatização dos fluxos de trabalho.

Tá… mas o que é esse tal de GitHub Actions ?

É uma plataforma de CI/CD (Continuous Integration e Continuous Delivery) do GitHub, ou seja, vai te ajudar nos processos para tornar o desenvolvimento, teste e entrega de “peças” de software de forma mais rápida e eficiente.

Agora vamos ao que interessa…

Quando temos um repositório no GitHub, qualquer usuário que tenha acesso poderá enviar um push, pull e etc. Essas ações podem ser usadas para iniciar o que chamamos de workflow no GitHub Actions.

Um workflow é um conjunto de tarefas a serem executadas simultaneamente ou sequencialmente. Ele possui um job, podendo existir mais de um. E estes jobs possuem steps. E estes steps possuem actions.

No exemplo acima temos um workflow que será acionado em um evento de push. Ele possui dois jobs e em cada job possui as steps. Essas steps estão divididas em duas com uma action em cada.

Explicando de forma mais detalhada (mas fique de boas que você verá exemplos sobre cada um):

  • Workflow
    O workflow tem um campo name, ele não é obrigatório, mas é legal incluir um nome referente ao fluxo que você está criando. Caso você não coloque ele vai definir seu name como o caminho do seu workflow relativo a raiz do seu repositório.
name: My First Workflow
  • on
    É obrigatório e é onde colocamos os eventos que farão aquele workflow rodar, pode ser um único evento ou um array de eventos. Você também consegue especificar a branch para qual cada evento irá rodar.
on: [push, pull_request]--------------------------------------------------------------------on: 
push:
branches:
- main
pull_request:
branches:
- main
  • Job
    Como mencionei anteriormente um workflow pode ter um ou mais jobs, podendo ser executados em paralelo (por padrão) ou sequencialmente utilizando o parâmetro needs.
    Cada job é executado obrigatoriamente por um runner (hospedado pelo GitHub ou auto-hospedado), basta você adicionar runs-on.
jobs:
my-first-job:
name: My First Job
runs-on: ubuntu-latest
--------------------------------------------------------------------jobs:
my-first-job:
name: My First Job
runs-on: ubuntu-latest
my-second-job:
name: My Second Job
runs-on: ubuntu-latest
needs: my-first-job
  • Steps
    Um job pode conter uma step ou uma sequência de steps. As steps podem executar comandos, configurações e actions.
    Nem todas as steps executam actions, mas todas as actions são executadas dentro de uma step.

No exemplo abaixo há duas steps, na primeira ocorre a action de checkout e na segunda utilizando ENVs irá informar uma mensagem ‘Hello World’.

jobs:
my-first-job:
name: My First Job
runs-on: ubuntu-latest
steps:
- name: checkout repo
uses: actions/checkout@v2
- name: print Hello, World
env:
VAR1: Hello,
VAR2: World!
run: echo $VAR1 $VAR2

Você também pode usar um if para executar uma step de acordo com aquela condição.
Neste exemplo a step é executada apenas quando o tipo do evento é um pull_request.

steps:
- name: My First Step
if: ${{ github.event_name == 'pull_request' }}
run: echo event is a pull request
  • Actions
    Vimos agora há pouco sobre as steps e que elas possuem o método uses. Esse método que você vai utilizar para setar suas actions.
    É super recomendado que você inclua as versões das actions. Isso porque quando o proprietário de uma dessas actions publicar uma atualização pode acabar interrompendo seu workflow ou causar algum comportamento ‘surpresinha’.

No exemplo abaixo é uma action com controle de versão.

steps:
- name: Step with specific version
uses: actions/checkout@v2.0

Após fazer uma breve explicação desses conceitos mais básicos e como utilizá-los, acho mega útil você saber sobre dois pontos legais do GitHub Actions:

Cache e artifacts!

Diferente dos steps, cada job é executado em uma nova instância do runner, logo, eles não conseguem compartilhar dados entre si.

Ai que entra o cache e artifacts em ação!

Os artifacts permitem que você compartilhe os dados entre os jobs de um workflow através de download/upload e salva os arquivos quando o workflow é concluído. Normalmente, os artifacts mais comuns são arquivos de log, resultados de teste, screenshots, coverage, resultados de desempenho de teste e entre outros.
Por padrão, o GitHub armazena os artifacts por 90 dias mas é possível personalizar esse tempo.
Outro ponto importante é os artifacts utilizam espaço de armazenamento no GitHub, então cuidado com o tamanho dos arquivos que você está dispondo pra download/upload.

Abaixo é um exemplo de upload de um artifact de coverage.

jobs:
my-artifacts-job:
name: My Artifacts Job
runs-on: ubuntu-latest
steps:
- name: Archive code coverage results
uses: actions/upload-artifact@v2
with:
name: code-coverage-report
path: output/test/code-coverage.html

O cache é usado para reutilização de dados/arquivos que não mudam com tanta frequência entre os jobs ou workflows. Normalmente utilizado em ferramentas de gerenciamento de pacotes como o npm, yarn e outros.
A ação de cache tenta restaurar um cache de acordo com a key fornecida. Quando a ação encontra o cache, restaura os arquivos em cache pro path configurado, se não existir uma key, é criado uma nova entrada se o job for executado com sucesso.
Uma vez que o cache é criado, ele fica disponível para todos os workflows no mesmo repositório.

Neste caso é um exemplo de job com um cache do node_modules, onde a key do seu cache é npm-deps-${{ hashFiles(‘**/package-lock.json’) }} e que pode ser utilizada em outros jobs para condicionais. A restore-keys é utilizada quando ocorre a perda de cache, então a action procura por caches alternativos que correspondam a npm-deps- .

jobs:
my-cache-job:
name: My Cache Job
runs-on: ubuntu-latest
steps:
- name: cache node modules
uses: actions/cache@v2
with:
path: ~/.npm
key: npm-deps-${{ hashFiles('**/package-lock.json') }}
restore-keys: npm-deps-

Agora que você já está mais por dentro do assunto, irei colocar aqui alguns pontos importantes:

  • No seu projeto poderá existir mais de um workflow, porém todos deverão estar em uma pasta .github/workflows.
  • Separamos em mais de um workflow quando precisamos definir configurações diferentes nos steps/jobs a partir de um evento (push, pull request, etc). Você pode querer fazer determinado job/step pro seu evento de push mas outras configurações pro seu evento de pull request, por exemplo.
  • Mantenha as suas actions mais leves possíveis, pois quanto mais tempo ela levar pra ser configurada e executada, mais tempo você vai gastar esperando. Lembre-se que existe um limite de tempo para o plano gratuito que suporta até 2000 minutos.
  • Relacionado ao ponto exatamente acima deste, não instale depêndencias desnecessariamente. Você pode utilizar o mecanismo de cache pra te auxiliar nisso.
  • Não code os secrets! Você consegue pela plataforma do GitHub configurá-los no seu repositório e fornecer como entradas ou variáveis de ambiente.

Fica aqui o meu “até logo”.

Espero ter clareado “um pouco” sobre as funcionalidades e opções que o GitHub Actions proporciona no âmbito de desenvolvimento de software. Há MUITO além do que mencionei aqui, existem diversas funcionalidades e opções diferentes de novas actions que a todo momento são implementadas. Vale dar um olhada na documentação oficial, ela é bem ampla mas acredito que com o que você leu aqui não ficará tão perdido.

--

--