Cada flujo de trabajo de GitHub Actions que has escrito es un archivo YAML. Todo — los disparadores, los jobs, los pasos, las variables de entorno, la estrategia matrix — se expresa en YAML. Lo que significa que entender YAML profundamente no es solo académico: es la diferencia entre una CI que funciona de forma fiable y una CI que falla misteriosamente a las 4pm de un viernes cuando intentas publicar una versión.
GitHub Actions tiene excelente documentación de sintaxis de workflows, pero se centra en las características de Actions en lugar de los mecanismos YAML subyacentes. Este artículo cubre ambos — la estructura del workflow, y los patrones YAML específicos (y las trampas) que hacen o deshacen las configuraciones de CI.
Estructura del workflow: las claves de nivel superior
Un archivo de workflow de GitHub Actions vive en .github/workflows/ y tiene tres claves obligatorias de nivel superior.
La descripción general oficial de workflows
explica dónde reside el archivo en tu repositorio y cómo GitHub lo descubre:
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: En YAML 1.1, la palabra sola on
se interpreta como el booleano true. El parser de GitHub maneja esto correctamente, pero si alguna vez ves tu
archivo de workflow marcado por un linter YAML genérico, es por esto. La forma segura es entrecomillarlo:
"on": — aunque GitHub Actions en sí mismo no requiere las comillas.Disparadores: la clave on:
La clave on: controla cuándo se ejecuta tu workflow. La
lista completa de eventos disparadores
cubre todo, desde revisiones de pull request hasta despachos de repositorio. Aquí están los patrones más comunes:
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: multilínea y bloques escalares YAML
La clave run: es donde el bloque escalar literal de YAML (|) demuestra su valor —
consulta la referencia yaml-multiline.info para
cada variación de bloques y escalares plegados. Sin él, encadenarías comandos con &&
en una sola línea, lo cual es ilegible:
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 multilínea, nunca >.
El escalar plegado colapsa los saltos de línea en espacios, lo que significa que tus comandos shell se unen en una larga cadena.
Eso causa errores crípticos. El bloque escalar literal | preserva exactamente los saltos de línea, por lo que cada línea
se ejecuta como un comando shell separado.Variables de entorno y secretos
Las variables de entorno en GitHub Actions usan YAML en combinación con el contexto de Actions y la sintaxis de expresión. Así es como encajan:
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.shLa sintaxis de expresión ${{ }} es el propio lenguaje de plantilla de GitHub Actions superpuesto sobre YAML.
Se evalúa antes del análisis YAML en algunos contextos, lo que puede interactuar inesperadamente con las propias reglas de comillas de YAML.
En caso de duda, envuelve los valores que comienzan con ${{ entre comillas dobles.
Estrategia matrix: construir con múltiples configuraciones
La estrategia matrix es una de las características más poderosas de GitHub Actions — y se expresa completamente en YAML. Ejecuta tu job una vez por cada combinación de valores 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 única definición de job produce hasta 9 ejecuciones paralelas (3 SO × 3 versiones Node, menos 1 excluida).
Los valores matrix YAML son arreglos simples — lo único que hay que vigilar es que los números de versión como 18
deben estar entrecomillados como "18" para mantenerlos como cadenas. Sin comillas, YAML los analiza como enteros
y algunas Actions pueden quejarse.
Pasos condicionales con if:
La clave if: te permite omitir pasos según condiciones. Usa el lenguaje de expresión de GitHub,
no 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 reutilizables
Para eliminar la duplicación entre repositorios (no solo dentro de un archivo), GitHub Actions soporta
los workflows reutilizables.
El workflow llamado usa on: workflow_call: y el llamante usa
uses: al nivel del job — no al nivel del paso:
# .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 }}Los errores YAML más comunes en GitHub Actions
- Indentación incorrecta en los pasos. Los pasos deben estar indentados bajo
steps:con espacios consistentes. Un espacio de más o de menos saca un paso fuera de su job. - Números de versión sin comillas.
node-version: 20pasa un entero; algunas actions esperan una cadena. Usanode-version: "20"para mayor seguridad. - Usar
>en lugar de|para scripts shell. Los escalares plegados colapsan los saltos de línea. Tu script multilínea se convierte en una larga cadena y falla. - Comillas faltantes en patrones glob. Patrones como
release/**contienen*que YAML puede interpretar como un alias. Siempre pon entre comillas los patrones glob. - Secretos usados en condiciones if:. GitHub enmascara los secretos en los registros pero no los permite en expresiones
if:. Usa una variable de entorno en su lugar. - Olvidar
fail-fast: falseen jobs matrix. Por defecto, si un job matrix falla, todos los demás se cancelan. Generalmente no es lo que quieres durante la depuración.
Conclusión
Los workflows de GitHub Actions son fundamentalmente archivos YAML — entender los bloques escalares literales de YAML, las reglas de comillas y la coerción de tipos se traduce directamente en escribir una CI más fiable. Los fallos más comunes provienen de errores de indentación, valores sin comillas que se coercionan al tipo incorrecto, y usar el operador de cadena multilínea incorrecto para scripts shell. Domina esas tres cosas y la mayoría de la depuración de workflows se vuelve sencilla. Usa el Validador YAML para detectar errores de sintaxis antes de hacer push, y el Formateador YAML para aplicar indentación consistente en tus archivos de workflow.