Todo workflow do GitHub Actions que você já escreveu é um arquivo YAML. Tudo — os gatilhos, os jobs, as etapas, as variáveis de ambiente, a estratégia de matrix — é expresso em YAML. O que significa que entender YAML profundamente não é apenas acadêmico: é a diferença entre uma CI que funciona de forma confiável e uma CI que quebra misteriosamente às 16h de uma sexta-feira quando você está tentando lançar uma release.
O GitHub Actions tem excelentes documentações de sintaxe de workflow, mas focam nos recursos do Actions em vez da mecânica YAML subjacente. Este artigo cobre os dois — a estrutura do workflow e os padrões específicos de YAML (e armadilhas) que fazem ou destroem configurações de CI.
Estrutura do Workflow: As Chaves de Nível Superior
Um arquivo de workflow do GitHub Actions fica em .github/workflows/ e tem três chaves obrigatórias de nível superior.
A visão geral oficial de workflows
explica onde o arquivo fica no seu repositório e como o GitHub o descobre:
name: CI Pipeline # optional but shown in the Actions UI
on: # triggers
push:
branches: [main]
pull_request:
jobs: # the actual work
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm teston como booleano YAML: No YAML 1.1, a palavra simples on
é interpretada como booleano true. O parser do GitHub lida com isso corretamente, mas se você alguma vez ver
seu arquivo de workflow sinalizado por um linter YAML genérico, é por isso. A forma segura é usar aspas:
"on": — embora o próprio GitHub Actions não exija as aspas.Gatilhos: A Chave on:
A chave on: controla quando seu workflow é executado. A
lista completa de eventos de gatilho
cobre tudo, desde revisões de pull request até despachos de repositório. Aqui estão os padrões mais comuns:
on:
# Push to specific branches
push:
branches:
- main
- "release/**" # glob pattern — quotes needed for /**
paths-ignore:
- "docs/**"
- "*.md"
# PRs targeting main
pull_request:
branches: [main]
types: [opened, synchronize, reopened]
# Scheduled (cron syntax)
schedule:
- cron: "0 2 * * 1" # every Monday at 2am UTC
# Manual trigger with input
workflow_dispatch:
inputs:
environment:
description: "Target environment"
required: true
default: staging
type: choice
options: [staging, production]Comandos run: Multilinha e Escalares de Bloco YAML
A chave run: é onde o escalar de bloco literal do YAML (|) mostra seu valor —
veja a referência yaml-multiline.info para
cada variação de escalares de bloco e dobrados. Sem ele, você estaria encadeando comandos com &&
em uma única linha, o que é ilegível:
steps:
# Single line — works but hard to read
- name: Build
run: npm ci && npm run lint && npm run test && npm run build
# Multi-line with literal block scalar — much better
- name: Build
run: |
npm ci
npm run lint
npm run test -- --coverage
npm run build
# Folded scalar (>) joins lines with spaces — NOT what you want for shell
# This would run as a single command with spaces where the newlines are:
- name: Wrong for shell
run: >
npm ci
npm test| para scripts shell multilinha, nunca >.
O escalar dobrado dobra quebras de linha em espaços, o que significa que seus comandos shell se juntam em uma string longa.
Isso causa erros crípticos. O escalar de bloco literal | preserva quebras de linha exatamente, então cada linha
é executada como um comando shell separado.Variáveis de Ambiente e Secrets
Variáveis de ambiente no GitHub Actions usam YAML em combinação com a sintaxe de contexto e expressão do Actions. Veja como elas se encaixam:
env:
NODE_ENV: production # workflow-level env var
API_VERSION: "2.1" # quoted to force string type
jobs:
deploy:
runs-on: ubuntu-latest
env:
DEPLOY_ENV: staging # job-level env var (overrides workflow-level)
steps:
- name: Deploy to staging
env:
API_KEY: ${{ secrets.STAGING_API_KEY }} # step-level, from secret
DATABASE_URL: ${{ vars.STAGING_DB_URL }} # step-level, from variable
run: |
echo "Deploying to $DEPLOY_ENV"
./scripts/deploy.shA sintaxe de expressão ${{ }} é a linguagem de template própria do GitHub Actions, colocada em camada sobre o YAML.
Ela é avaliada antes do parsing YAML em alguns contextos, o que pode interagir inesperadamente com as próprias regras de aspas do YAML.
Na dúvida, envolva valores que começam com ${{ em aspas duplas.
Estratégia de Matrix: Build em Múltiplas Configurações
A estratégia de matrix é um dos recursos mais poderosos do GitHub Actions — e é expresso inteiramente em YAML. Ela executa seu job uma vez para cada combinação de valores de matrix:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false # don't cancel other matrix jobs on failure
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: ["18", "20", "22"]
exclude:
- os: windows-latest
node: "18" # skip this combination
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm ci && npm testEsta definição de um único job produz até 9 execuções paralelas (3 OS × 3 versões Node, menos 1 excluída).
Os valores de matrix YAML são arrays simples — a única coisa a observar é que números de versão como 18
devem ser citados como "18" para mantê-los como strings. Sem aspas, o YAML os interpreta como inteiros
e algumas Actions podem reclamar.
Etapas Condicionais com if:
A chave if: permite pular etapas com base em condições. Usa a linguagem de expressão do GitHub,
não valores YAML simples:
steps:
- name: Run tests
run: npm test
- name: Upload coverage
if: success() && github.ref == 'refs/heads/main'
uses: codecov/codecov-action@v4
- name: Notify on failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
slack-message: "Build failed on ${{ github.ref }}"
channel-id: "C12345ABC"
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
- name: Deploy (only on tag push)
if: startsWith(github.ref, 'refs/tags/v')
run: ./scripts/deploy.sh productionWorkflows Reutilizáveis
Para eliminar duplicação entre repositórios (não apenas dentro de um arquivo), o GitHub Actions suporta
workflows reutilizáveis.
O workflow chamado usa on: workflow_call: e o chamador usa
uses: no nível do job — não no nível da etapa:
# .github/workflows/reusable-test.yml (the reusable workflow)
on:
workflow_call:
inputs:
node-version:
required: false
type: string
default: "20"
secrets:
NPM_TOKEN:
required: true
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
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}# .github/workflows/ci.yml (the caller)
on: [push, pull_request]
jobs:
run-tests:
uses: my-org/shared-workflows/.github/workflows/reusable-test.yml@main
with:
node-version: "22"
secrets:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}Os Erros YAML Mais Comuns no GitHub Actions
- Indentação errada nas etapas. As etapas devem ser indentadas sob
steps:com espaços consistentes. Um único espaço a mais ou a menos move uma etapa para fora do seu job. - Números de versão sem aspas.
node-version: 20passa um inteiro; algumas actions esperam uma string. Usenode-version: "20"para garantir. - Usando
>em vez de|para scripts shell. Escalares dobrados colapsam quebras de linha. Seu script multilinha se torna uma string longa e falha. - Aspas ausentes em padrões glob. Padrões como
release/**contêm*que o YAML pode interpretar como alias. Sempre use aspas em padrões glob. - Secrets usados em condições if:. O GitHub mascara secrets em logs, mas não os permite em expressões
if:. Use uma variável de ambiente em vez disso. - Esquecer
fail-fast: falseem jobs de matrix. Por padrão, se um job de matrix falha, todos os outros são cancelados. Geralmente não é o que você quer durante a depuração.
Conclusão
Workflows do GitHub Actions são fundamentalmente arquivos YAML — entender os escalares de bloco literal do YAML, as regras de aspas e a coerção de tipos se traduz diretamente em escrever uma CI mais confiável. As falhas mais comuns vêm de erros de indentação, valores sem aspas que coagem para o tipo errado e usar o operador de string multilinha errado para scripts shell. Acerte essas três coisas e a maior parte da depuração de workflow se torna direta. Use o Validador YAML para capturar erros de sintaxe antes de fazer push, e o Formatador YAML para impor indentação consistente em seus arquivos de workflow.