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

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
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:
| Gatilho | Cenário típico | Exemplo de configuração |
|---|---|---|
push | Envio de código para uma branch | on: push: branches: [main] |
pull_request | Criação ou atualização de PR | on: pull_request: types: [opened, synchronize] |
schedule | Tarefa agendada (Cron) | on: schedule: - cron: '0 0 * * *' |
workflow_dispatch | Disparo manual | on: workflow_dispatch: inputs: env: ... |
workflow_call | Workflow reutilizável | on: workflow_call: inputs: ... |
release | Evento de lançamento | on: release: types: [published] |
issues | Evento de Issue | on: issues: types: [opened, labeled] |
repository_dispatch | Evento externo | on: 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 quenpm 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:
| Sintoma | Causa possível | Solução |
|---|---|---|
| O workflow não dispara | Filtro de branch incorreto | Confira branches e verifique as letras maiúsculas e minúsculas do nome da branch |
| Falha ao interpretar o YAML | Tab usado na indentação | Troque tudo por espaços; YAML não aceita Tab na indentação |
| Secrets não funcionam | Escopo incorreto | Confirme que secrets estão no nível certo, job ou step |
| Falha na dependência entre jobs | Referência incorreta em needs | Confira a grafia do job-id, incluindo maiúsculas e minúsculas |
| O workflow demora demais | O cache não está sendo usado | Adicione actions/cache para armazenar dependências em cache |
| Erro de permissão insuficiente | Permissões do GITHUB_TOKEN insuficientes | Adicione 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ério | GitHub Actions | GitLab CI | Jenkins | CircleCI |
|---|---|---|---|---|
| Linguagem de configuração | YAML | YAML | Groovy | YAML |
| Hospedagem | Nativa na nuvem | Nuvem/autogerenciada | Autogerenciada | Nativa na nuvem |
| Integração | Nativa do GitHub | Nativa do GitLab | Exige configuração | Exige configuração |
| Curva de aprendizado | Baixa | Baixa | Alta | Média |
| Franquia gratuita | 2.000 minutos/mês em repositórios privados | 400 minutos/mês | Sem limite, se autogerenciado | 6.000 minutos/mês |
| Repositórios públicos | Sem limite | Sem limite | Sem limite | Sem 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:
namenomeia,ondispara,jobsdefine tarefas estepsexecuta etapas; - oito gatilhos comuns, com destaque para
push,pull_requesteschedule; - 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:
- Crie seu primeiro workflow no próprio projeto — copie o modelo deste artigo e adapte a configuração.
- 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.
- 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?
Qual é a diferença entre os gatilhos push e pull_request?
A indentação do YAML usa Tab ou espaços?
Qual é a franquia gratuita e o que fazer quando ela acabar?
13 min de leitura · Publicado em: 10 abr 2026 · Atualizado em: 8 set 2026
Guia completo GitHub Actions
Você está lendo o primeiro post desta série. Continue para o próximo ou abra o hub da série para ver toda a trilha.



Comentários
Entre com GitHub para comentar