Alternar tema

GitHub Actions para iniciantes: fundamentos de workflows YAML e configuração de gatilhos

Easton editorial illustration: one large YAML workflow card driving three job stages

O erro vermelho na tela é tão chamativo que dá vontade de jogar o teclado longe.

O código funciona perfeitamente na máquina local, mas quebra assim que vai para o GitHub. Você já alterou aquele arquivo YAML seis vezes, e o problema sempre está na indentação. Como isso consegue ser mais difícil do que escrever o próprio código?

Na verdade, o GitHub Actions não é complicado. O difícil são as documentações que começam despejando centenas de páginas de configuração e deixam qualquer pessoa perdida. Este artigo explica, da maneira mais simples possível, a estrutura central de um workflow YAML.

Você vai aprender:

  • os quatro campos essenciais de um arquivo YAML e a função prática de cada um;
  • como configurar oito gatilhos comuns e quando usar cada um;
  • um modelo completo de workflow pronto para copiar;
  • os erros em que já tropecei e como evitá-los.

Vamos começar.

Arquivo de workflow YAML: quatro campos essenciais

Quando comecei a usar o GitHub Actions, o arquivo YAML dentro de .github/workflows parecia escrito em outro idioma. Era uma sequência de indentações e dois-pontos em que um único espaço errado derrubava tudo.

Depois percebi que ele tem apenas quatro partes essenciais. Quando você entende essas quatro, o restante são recursos adicionais.

name: dê um nome ao workflow

Este é o campo mais simples, mas muita gente — inclusive eu, no começo — acaba ignorando.

name: CI for Node.js App

name é o nome exibido para o workflow na aba Actions do GitHub. Depois de enviar o código e abrir a página Actions do repositório, é esse texto que você verá.

Uma boa prática é usar nome do projeto + descrição da função, como MyApp CI ou Backend Deploy. Quando houver vários workflows, você localizará o que precisa de imediato.

Esse campo pode ser omitido. Nesse caso, o GitHub usa o nome do arquivo. Ainda assim, não recomendo removê-lo: nomes de arquivo costumam ser abreviações menos claras.

on: quando executar

8 tipos
Gatilhos comuns
O GitHub Actions aceita dezenas de gatilhos, mas push, pull_request, schedule e workflow_dispatch são os mais usados em projetos reais

on funciona como o “interruptor” do workflow. É nele que você informa ao GitHub em quais situações o workflow deve rodar.

A forma mais simples é:

on: push

Isso significa que qualquer envio de código dispara o workflow.

Em projetos reais, porém, normalmente é preciso ter um controle mais preciso. Por exemplo, para rodar apenas quando houver um push na branch main:

on:
  push:
    branches: [main]

Ou, se você também quiser dispará-lo ao criar um Pull Request:

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

Os gatilhos são a essência do GitHub Actions. Mais adiante, há uma seção inteira sobre oito cenários comuns. Por enquanto, basta lembrar que on determina quando o workflow é disparado.

jobs: defina o que deve ser feito

jobs é o corpo do workflow e define quais tarefas serão executadas.

Um workflow pode conter vários jobs, que rodam em paralelo por padrão. Cada job precisa indicar o ambiente de execução por meio do campo runs-on:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # ...lista de etapas

Esse trecho define um job chamado build, executado na versão mais recente do Ubuntu fornecida pelo GitHub.

Quando há vários jobs, você pode usar o campo needs para definir dependências:

jobs:
  test:
    runs-on: ubuntu-latest
    # ... etapas de teste

  deploy:
    needs: test  # só executa depois que test terminar
    runs-on: ubuntu-latest
    # ... etapas de implantação

Assim, deploy só começa quando test termina. Se test falhar, deploy não será executado.

steps: as etapas executadas

steps são as menores unidades de execução dentro de um job. Cada comando ou Action é executado na ordem em que aparece.

Há duas formas de escrever um step:

1. Use run para executar um comando:

steps:
  - name: Install dependencies
    run: npm ci

  - name: Run tests
    run: npm test

Depois de run, você coloca o comando que seria executado no terminal, da mesma forma que faria localmente.

2. Use uses para chamar uma Action:

steps:
  - name: Checkout code
    uses: actions/checkout@v4

  - name: Setup Node.js
    uses: actions/setup-node@v4
    with:
      node-version: '20'

uses é um dos grandes recursos do GitHub Actions: você aproveita uma Action já criada por outra pessoa. Por exemplo, actions/checkout@v4 baixa o código, enquanto actions/setup-node@v4 configura o ambiente Node.js.

with passa parâmetros para a Action. No exemplo, node-version: '20' informa ao setup-node que você quer usar o Node.js 20.

Esses são os quatro campos. Mais simples do que parecia, certo?

Gatilhos em detalhes: oito cenários comuns

Como vimos, o campo on define quando o workflow é disparado. O GitHub Actions aceita dezenas de gatilhos, mas, na prática, apenas alguns aparecem com frequência.

A tabela a seguir mostra rapidamente quando usar cada um:

GatilhoCenário típicoExemplo de configuração
pushEnvio de código para uma branchon: push: branches: [main]
pull_requestCriação ou atualização de PRon: pull_request: types: [opened, synchronize]
scheduleTarefa agendada (Cron)on: schedule: - cron: '0 0 * * *'
workflow_dispatchDisparo manualon: workflow_dispatch: inputs: env: ...
workflow_callWorkflow reutilizávelon: workflow_call: inputs: ...
releaseEvento de lançamentoon: release: types: [published]
issuesEvento de Issueon: issues: types: [opened, labeled]
repository_dispatchEvento externoon: repository_dispatch: types: [deploy]

A seguir, vamos detalhar os mais comuns.

push: o gatilho mais básico

push costuma ser o primeiro gatilho que você encontra. Ele é disparado quando o código é enviado para uma branch.

Configuração simples:

on: push

O problema dessa configuração é que um push em qualquer branch executará o workflow. Se o repositório tiver 20 branches, cada envio feito por qualquer pessoa consumirá minutos da franquia rapidamente.

Uma configuração mais adequada limita as branches:

on:
  push:
    branches: [main, develop]

Também é possível usar curingas:

on:
  push:
    branches:
      - 'main'
      - 'release/**'  # corresponde a release/v1.0, release/v2.0 etc.

pull_request: a proteção antes do merge

pull_request é disparado quando um PR é criado ou atualizado. Normalmente, ele é usado para executar testes e verificar o estilo do código.

on:
  pull_request:
    branches: [main]

O campo types permite controlar com mais precisão quando o gatilho deve rodar:

on:
  pull_request:
    types: [opened, synchronize, reopened]
  • opened: o PR acabou de ser criado;
  • synchronize: há novos commits no PR;
  • reopened: o PR foi reaberto.

Com essa configuração, o workflow só roda nessas três situações, evitando desperdício de recursos.

schedule: tarefas agendadas

schedule usa uma expressão Cron para definir execuções periódicas. Por exemplo, para rodar testes uma vez por dia, à meia-noite:

on:
  schedule:
    - cron: '0 0 * * *'  # todos os dias à 0h UTC

Uma expressão Cron tem cinco campos: minuto, hora, dia, mês e dia da semana.

Alguns horários comuns:

  • 0 0 * * *: todos os dias à 0h UTC (8h no horário de Pequim);
  • 0 */6 * * *: a cada 6 horas;
  • 30 2 * * 1: toda segunda-feira às 2h30 UTC.

Há uma armadilha importante: o GitHub usa UTC. Se você quiser executar uma tarefa às 9h no horário de Pequim, deverá configurá-la para 1h UTC (0 1 * * *).

workflow_dispatch: disparo manual

Às vezes, você não quer um disparo automático, mas sim clicar em um botão para iniciar o workflow. É para isso que serve workflow_dispatch.

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Ambiente de implantação'
        required: true
        default: 'staging'
        type: choice
        options:
          - staging
          - production

Depois dessa configuração, aparece um botão “Run workflow” na página Actions. Ao clicar nele, você escolhe o ambiente e inicia a execução.

Esse gatilho é especialmente útil em implantações: testes automáticos, implantação manual.

workflow_call: reutilize workflows

Se a lógica do workflow for complexa, ou se vários repositórios precisarem do mesmo processo, workflow_call permite transformar o workflow em um componente reutilizável.

Defina um workflow reutilizável:

# .github/workflows/ci.yml
on:
  workflow_call:
    inputs:
      node-version:
        required: true
        type: string

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node-version }}
      - run: npm ci && npm test

Chame-o a partir de outro workflow:

# .github/workflows/main.yml
on: push

jobs:
  call-ci:
    uses: ./.github/workflows/ci.yml
    with:
      node-version: '20'

Assim, você pode reutilizar a mesma lógica de CI em diferentes repositórios: altere em um lugar e a mudança valerá para todos.

Os outros gatilhos (release, issues e repository_dispatch) são menos usados, por isso não vamos detalhá-los aqui. Se quiser saber mais, consulte a documentação oficial do GitHub.

Na prática: seu primeiro modelo de workflow

Depois de tantos conceitos, é melhor experimentar diretamente.

Veja um workflow de CI completo para um projeto Node.js. Você pode copiá-lo e usá-lo no seu projeto:

name: CI

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

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # 1. Baixar o código
      - name: Checkout code
        uses: actions/checkout@v4

      # 2. Configurar o ambiente Node.js
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      # 3. Instalar as dependências
      - name: Install dependencies
        run: npm ci

      # 4. Executar os testes
      - name: Run tests
        run: npm test

Como usar?

Primeiro passo: crie a pasta .github/workflows na raiz do projeto, caso ela ainda não exista.

Segundo passo: crie o arquivo ci.yml nessa pasta e cole o código acima.

Terceiro passo: faça commit e push para o GitHub.

Depois do push, abra a aba Actions do repositório. O workflow já deverá estar em execução.

Explicação linha por linha

  • name: CI: nome do workflow, exibido na página Actions;
  • on: push: branches: [main]: dispara ao enviar código para a branch main;
  • on: pull_request: branches: [main]: também dispara quando alguém abre um PR para a branch main;
  • jobs: build:: define um job chamado build;
  • runs-on: ubuntu-latest: executa na versão mais recente do Ubuntu fornecida pelo GitHub;
  • actions/checkout@v4: Action oficial que baixa o código para a máquina virtual;
  • actions/setup-node@v4: Action oficial que configura o ambiente Node.js;
  • npm ci: instala as dependências de forma mais rápida e limpa do que npm install;
  • npm test: executa os testes.

Se o projeto não for Node.js, basta trocar as etapas intermediárias. Por exemplo, para um projeto Python:

steps:
  - uses: actions/checkout@v4
  - uses: actions/setup-python@v5
    with:
      python-version: '3.11'
  - run: pip install -r requirements.txt
  - run: pytest

O padrão básico é sempre o mesmo: baixar o código → configurar o ambiente → instalar dependências → executar testes.

Solução de erros comuns de configuração

Já passei pelos problemas a seguir; espero que você não precise repetir o caminho.

Use esta lista ao investigar uma falha:

SintomaCausa possívelSolução
O workflow não disparaFiltro de branch incorretoConfira branches e verifique as letras maiúsculas e minúsculas do nome da branch
Falha ao interpretar o YAMLTab usado na indentaçãoTroque tudo por espaços; YAML não aceita Tab na indentação
Secrets não funcionamEscopo incorretoConfirme que secrets estão no nível certo, job ou step
Falha na dependência entre jobsReferência incorreta em needsConfira a grafia do job-id, incluindo maiúsculas e minúsculas
O workflow demora demaisO cache não está sendo usadoAdicione actions/cache para armazenar dependências em cache
Erro de permissão insuficientePermissões do GITHUB_TOKEN insuficientesAdicione uma configuração permissions ao job

Erro 1: indentação incorreta

Esse é, de longe, o erro mais comum.

YAML é extremamente sensível à indentação. Use espaços, nunca Tab. Além disso, cada nível deve usar 2 espaços — ou outro número adotado de forma consistente, embora 2 seja o padrão no GitHub Actions.

# Exemplo incorreto: indentação desalinhada
jobs:
  build:
  runs-on: ubuntu-latest  # esta linha deveria ter 4 espaços de indentação
# Forma correta
jobs:
  build:
    runs-on: ubuntu-latest  # 4 espaços de indentação

A maioria dos editores, como VS Code e WebStorm, pode ser configurada para inserir espaços automaticamente ao pressionar Tab. Vale a pena ativar essa opção para não contar espaços manualmente.

Erro 2: nome da branch incorreto

Os nomes de branch no GitHub diferenciam maiúsculas de minúsculas. main e Main são branches diferentes.

# Se a sua branch se chama main
on:
  push:
    branches: [Main]  # incorreto, não será disparado

# Forma correta
on:
  push:
    branches: [main]  # minúsculas

Se não souber o nome da branch, confira a página do repositório no GitHub ou execute git branch localmente.

Erro 3: erro de grafia no job-id

Quando o workflow tem vários jobs com dependências entre si, o campo needs deve apontar exatamente para o id de outro job.

jobs:
  test:
    runs-on: ubuntu-latest
    # ...

  deploy:
    needs: Test  # incorreto, as maiúsculas não correspondem
    runs-on: ubuntu-latest
# Forma correta
jobs:
  test:
    runs-on: ubuntu-latest

  deploy:
    needs: test  # minúsculas, igual ao id do job acima
    runs-on: ubuntu-latest

Erro 4: Secrets no nível errado

Os Secrets do GitHub têm dois escopos: repositório e ambiente. Para referenciá-los, use ${{ secrets.XXX }}.

# Exemplo incorreto: secrets no lugar errado
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      API_KEY: secrets.MY_KEY  # incorreto, faltou ${{ }}
# Forma correta
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      API_KEY: ${{ secrets.MY_KEY }}  # envolva com ${{ }}

Além disso, Secrets são criptografados, por isso o valor real não aparece nos logs. Para confirmar no log se o valor foi transmitido, mostre apenas uma verificação substituta:

- name: Debug
  run: echo "API_KEY is set: ${{ secrets.MY_KEY != '' }}"

Assim, você confirma se o valor está vazio sem expor a chave real.

GitHub Actions versus outras ferramentas de CI/CD

Talvez você já tenha usado Jenkins, GitLab CI ou CircleCI. Quais são as vantagens e desvantagens do GitHub Actions em comparação com essas ferramentas?

Esta tabela resume as diferenças:

CritérioGitHub ActionsGitLab CIJenkinsCircleCI
Linguagem de configuraçãoYAMLYAMLGroovyYAML
HospedagemNativa na nuvemNuvem/autogerenciadaAutogerenciadaNativa na nuvem
IntegraçãoNativa do GitHubNativa do GitLabExige configuraçãoExige configuração
Curva de aprendizadoBaixaBaixaAltaMédia
Franquia gratuita2.000 minutos/mês em repositórios privados400 minutos/mêsSem limite, se autogerenciado6.000 minutos/mês
Repositórios públicosSem limiteSem limiteSem limiteSem limite

Vantagens do GitHub Actions

1. Integração sem configuração adicional

Se o código já está hospedado no GitHub, o GitHub Actions é a escolha mais direta. Não é preciso configurar webhooks, manter servidores nem instalar plugins. Crie um arquivo YAML, faça push e ele já pode rodar.

2. Ecossistema do Marketplace

O GitHub Marketplace oferece milhares de Actions, inclusive Actions oficiais da AWS, Azure e Google Cloud. Para quase qualquer função, provavelmente alguém já criou uma opção que você pode chamar diretamente com uses.

3. Franquia gratuita adequada para desenvolvedores individuais

Repositórios públicos têm uso sem limite; repositórios privados recebem 2.000 minutos por mês. Para projetos pessoais ou equipes pequenas, costuma ser suficiente.

Quando não escolher o GitHub Actions?

1. Seu código não está no GitHub

Se você usa GitLab ou Bitbucket, prefira o CI/CD integrado à própria plataforma. É possível disparar o GitHub Actions por webhook, mas configurar tudo isso dá mais trabalho do que usar a solução nativa.

2. Você precisa de controle total sobre o ambiente de execução

Os ambientes dos runners do GitHub Actions são predefinidos — Ubuntu, Windows ou macOS — e você não consegue instalar software próprio nem configurar um ambiente especial. Nesse caso, Jenkins com runner autogerenciado oferece mais flexibilidade.

3. Você tem exigências extremas de segurança

Os runners do GitHub Actions são máquinas virtuais hospedadas pelo GitHub. Se o código envolver informações altamente confidenciais, talvez seja necessário manter um sistema de CI próprio. O GitHub também aceita self-hosted runners, que podem servir como meio-termo.

Minha recomendação

Para a maioria dos desenvolvedores individuais e das equipes pequenas:

  • código no GitHub → escolha GitHub Actions;
  • código no GitLab → escolha GitLab CI;
  • necessidade de muita personalização → Jenkins ou self-hosted runner.

Não existe uma opção universalmente melhor. A escolha certa é a que atende ao seu contexto.

Resumo

Neste ponto, você já deve entender como funciona um workflow YAML do GitHub Actions.

Pontos principais:

  • quatro campos essenciais: name nomeia, on dispara, jobs define tarefas e steps executa etapas;
  • oito gatilhos comuns, com destaque para push, pull_request e schedule;
  • um modelo pronto para copiar: baixar o código → configurar o ambiente → instalar dependências → executar testes;
  • quatro erros comuns: indentação, nome da branch, job-id e Secrets.

Próximos passos:

  1. Crie seu primeiro workflow no próprio projeto — copie o modelo deste artigo e adapte a configuração.
  2. Leia o artigo avançado da série, “Estratégias de cache no GitHub Actions: acelere seu pipeline de CI/CD em cinco vezes”, para deixar o workflow mais rápido.
  3. Explore o GitHub Marketplace e veja quais Actions podem ser usadas diretamente.

Depois que você experimenta a automação, é difícil querer voltar atrás.

FAQ

Quais campos são obrigatórios em um workflow do GitHub Actions?
A configuração mínima precisa apenas de `on` (gatilho) e `jobs` (definição das tarefas). `name` e `steps` são opcionais, mas não convém omiti-los, pois tornam o workflow mais fácil de ler.
Qual é a diferença entre os gatilhos push e pull_request?
`push` dispara quando o código é enviado para uma branch e é adequado para processos de implantação; `pull_request` dispara quando um PR é criado ou atualizado e serve para verificações de código e testes. Em geral, os dois são usados juntos: os testes rodam no PR e a implantação roda após o merge.
A indentação do YAML usa Tab ou espaços?
É obrigatório usar espaços. YAML não aceita Tab na indentação. No VS Code, ative a opção de inserir espaços ao pressionar Tab para evitar esse problema. Em geral, cada nível usa 2 espaços.
Qual é a franquia gratuita e o que fazer quando ela acabar?
Repositórios privados têm 2.000 minutos por mês, enquanto repositórios públicos não têm limite. Ao ultrapassar a franquia, você pode comprar minutos adicionais ou usar um self-hosted runner, que não entra nessa contagem.

13 min de leitura · Publicado em: 10 abr 2026 · Atualizado em: 8 set 2026

Comentários

Entre com GitHub para comentar

Easton BlogEaston Blog