GitHub Actions: Sua Primeira Automação de CI/CD

Até aqui o repositório Git funcionou como um arquivo histórico — um lugar onde mudanças são registradas. O GitHub Actions transforma esse repositório em algo ativo: cada evento que acontece nele pode disparar uma sequência de ações automatizadas.

Um push na branch main pode rodar os testes, construir a aplicação e fazer o deploy em produção — tudo sem intervenção humana. Um Pull Request aberto pode verificar a qualidade do código antes que qualquer revisor humano o leia. Uma tag criada pode gerar um pacote e publicá-lo automaticamente.

Esse é o conceito de CI/CD em sua forma mais concreta, e o GitHub Actions é hoje uma das ferramentas mais acessíveis para implementá-lo.


Conceitos Fundamentais

Antes de escrever o primeiro workflow, é necessário entender quatro conceitos que aparecem em toda configuração do GitHub Actions:

Workflow — o arquivo de automação em si, escrito em YAML e armazenado em .github/workflows/. Um repositório pode ter múltiplos workflows.

Event — o gatilho que dispara o workflow. Pode ser um push, um pull request, um agendamento via cron, ou até um disparo manual.

Job — uma unidade de trabalho dentro do workflow. Cada job roda em uma máquina virtual isolada. Jobs podem rodar em paralelo ou em sequência, com dependências declaradas.

Step — cada passo dentro de um job. Um step pode executar um comando shell ou usar uma action pré-construída.


Estrutura de um Arquivo de Workflow

name: Nome do Workflow

on:                        # evento que dispara o workflow
  push:
    branches: [ main ]

jobs:
  nome-do-job:             # identificador do job
    runs-on: ubuntu-latest # sistema operacional da máquina virtual

    steps:
      - name: Descrição do step
        run: echo "Olá, mundo"

Os arquivos ficam obrigatoriamente em .github/workflows/ na raiz do repositório. O nome do arquivo é livre, mas deve ter extensão .yml ou .yaml.


O Primeiro Workflow: Verificação Básica

Cria-se o diretório e o arquivo:

mkdir -p .github/workflows
touch .github/workflows/ci.yml

Conteúdo do arquivo:

name: CI — Verificação Básica

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  verificar:
    runs-on: ubuntu-latest

    steps:
      - name: Clona o repositório
        uses: actions/checkout@v4

      - name: Exibe informações do ambiente
        run: |
          echo "Branch: ${{ github.ref_name }}"
          echo "Commit: ${{ github.sha }}"
          echo "Autor: ${{ github.actor }}"
          uname -a

      - name: Verifica arquivos presentes
        run: ls -la

Ao fazer o push desse arquivo, o GitHub executa o workflow automaticamente. O resultado pode ser acompanhado na aba Actions do repositório.


Workflows com Múltiplos Jobs

Jobs diferentes podem rodar em paralelo, reduzindo o tempo total do pipeline:

name: CI — Build e Testes

on:
  push:
    branches: [ main ]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Verifica formatação
        run: echo "Rodando linter..."

  testes-unitarios:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Roda testes unitários
        run: echo "Rodando testes..."

  testes-integracao:
    runs-on: ubuntu-latest
    needs: testes-unitarios    # só roda após testes-unitarios concluir
    steps:
      - uses: actions/checkout@v4
      - name: Roda testes de integração
        run: echo "Rodando testes de integração..."

O campo needs declara dependências entre jobs. No exemplo acima, lint e testes-unitarios rodam em paralelo, enquanto testes-integracao aguarda testes-unitarios terminar com sucesso.


Usando Actions Pré-Construídas

O GitHub Actions possui um marketplace com milhares de actions criadas pela comunidade. As mais usadas são oficiais e mantidas pelo próprio GitHub.

Um workflow real para uma aplicação Node.js:

name: CI — Node.js

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-e-teste:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x]   # testa em múltiplas versões

    steps:
      - name: Clona o repositório
        uses: actions/checkout@v4

      - name: Configura Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Instala dependências
        run: npm ci

      - name: Roda os testes
        run: npm test

      - name: Faz o build
        run: npm run build

O bloco strategy.matrix instrui o GitHub Actions a rodar o job múltiplas vezes, uma para cada valor da matriz. No exemplo, o pipeline roda duas vezes — uma com Node 18 e outra com Node 20 — em paralelo.


Variáveis e Secrets

Informações sensíveis — senhas, tokens, chaves de API — nunca devem ser escritas diretamente no arquivo de workflow. O GitHub oferece Secrets: variáveis criptografadas configuradas nas configurações do repositório (Settings → Secrets and variables → Actions).

Usando secrets no workflow:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Deploy no servidor
        env:
          SERVIDOR: ${{ secrets.SERVIDOR_HOST }}
          USUARIO: ${{ secrets.SERVIDOR_USUARIO }}
          CHAVE_SSH: ${{ secrets.CHAVE_SSH_PRIVADA }}
        run: |
          echo "$CHAVE_SSH" > chave.pem
          chmod 600 chave.pem
          ssh -i chave.pem -o StrictHostKeyChecking=no \
            $USUARIO@$SERVIDOR "cd /app && git pull && npm install"

O valor de um secret nunca aparece nos logs — o GitHub Actions o mascara automaticamente.


Disparo Manual e Agendado

Além de eventos de push e pull request, workflows podem ser disparados manualmente ou em horários programados:

on:
  # Disparo manual pela interface do GitHub
  workflow_dispatch:
    inputs:
      ambiente:
        description: 'Ambiente de destino'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - producao

  # Agendamento via cron — roda todo dia às 2h da manhã
  schedule:
    - cron: '0 2 * * *'

O workflow_dispatch é especialmente útil para deploys controlados — o responsável escolhe o ambiente e confirma o disparo manualmente pela interface do GitHub.


Um Pipeline Completo e Realista

Reunindo tudo em um pipeline que faz sentido para um projeto real:

name: Pipeline Completo

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  qualidade:
    name: Qualidade de Código
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20.x'
          cache: 'npm'
      - run: npm ci
      - run: npm run lint
      - run: npm test -- --coverage

  build:
    name: Build da Aplicação
    runs-on: ubuntu-latest
    needs: qualidade
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20.x'
          cache: 'npm'
      - run: npm ci
      - run: npm run build
      - name: Salva artefato do build
        uses: actions/upload-artifact@v4
        with:
          name: build-output
          path: dist/

  deploy-staging:
    name: Deploy em Staging
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Baixa artefato do build
        uses: actions/download-artifact@v4
        with:
          name: build-output
          path: dist/
      - name: Deploy
        env:
          DEPLOY_KEY: ${{ secrets.STAGING_DEPLOY_KEY }}
        run: echo "Fazendo deploy em staging..."

O campo if garante que o job de deploy só rode quando o evento for um push direto na main — não em Pull Requests.


 

Referências para Aprofundamento

Documentação oficial

  • GitHub Actions Documentation — Documentação completa do GitHub Actions, incluindo referência de sintaxe, eventos disponíveis e guias por linguagem.
  • GitHub Actions Marketplace — Catálogo de actions disponíveis. Vale explorar antes de escrever qualquer automação do zero.

Leitura técnica

Prática