MÓDULO 18 · CI/CD + MONITORING EN PRODUCCIÓN · 30 MIN

La jerarquía de un workflow

Hay una sola regla que explica casi toda la sintaxis de GitHub Actions: cada job arranca en una máquina limpia. Por eso todos los jobs repiten el checkout, por eso needs ordena pero no comparte ficheros, y por eso existen los artifacts. Si entiendes dónde está la frontera del sistema de archivos, el YAML deja de ser algo que se copia y pasa a ser algo que se deduce.
01 — El vocabulario
Seis palabras y dónde vive cada una
PalabraQué esDónde aparece
WorkflowUn fichero YAML con una automatización completa.github/workflows/*.yml
EventLo que dispara el workflowLa clave on:
JobUn conjunto de steps que corren en una máquinaBajo jobs:
StepUna tarea individual, secuencial dentro del jobBajo steps:
ActionUn paquete reutilizable de terceros o propiouses:
RunnerLa máquina virtual donde corre el jobruns-on:

La frontera que importa no está entre workflow y job: está entre job y job. Los steps de un mismo job comparten disco, variables exportadas y directorio de trabajo. Dos jobs distintos no comparten nada — ni siquiera cuando uno espera al otro.

02 — Los dos tipos de step
run frente a uses
steps:
  - uses: actions/checkout@v4        # ejecuta código empaquetado por otro
  - uses: actions/setup-node@v4
    with:
      node-version: '20'
      cache: 'npm'
  - run: npm ci                      # ejecuta un comando de shell
  - run: |
      echo "varias líneas"
      npm run build

uses trae comportamiento; with son sus parámetros. run es literalmente una shell. Casi todos los fallos de principiante en un workflow son uno de estos dos: poner with colgando de un run, o inventarse el nombre de una action que no existe.

03 — La frontera
Paralelo por defecto, secuencial con needs

Sin needs — paralelo

lint
test
build
tres máquinas a la vez

Con needs — ordenado

lint
test
▼ needs: [lint, test]
build  ·  máquina nueva
espera, pero no hereda

Sin needs, los tres jobs arrancan a la vez. Con needs, build espera — pero espera, no hereda: sigue arrancando en una máquina limpia y tiene que volver a hacer checkout y volver a instalar dependencias. Lo único que cruza esa frontera son los artifacts (upload-artifact / download-artifact) y los outputs que el job declare explícitamente.

// "needs" es una relación de orden, no de herencia — el disco no viaja
04 — Cuándo arranca
Los cinco triggers que se usan de verdad
TriggerCuándo disparaPara qué se usa
pushAl subir commits a una ramaValidar main y develop
pull_requestAl abrir o actualizar un PRLos checks del PR
scheduleCron, siempre en UTCAuditorías nocturnas, backups
workflow_dispatchUn botón en la pestaña ActionsDespliegues y rollbacks manuales
workflow_runCuando termina otro workflowEncadenar CD detrás de CI

push y pull_request declarados los dos sobre main disparan dos ejecuciones del mismo commit en un PR contra main. No es un error de configuración, es cómo funciona el modelo de eventos — y es una de las razones de que exista concurrency.

05 — Los datos del entorno
Contextos y secretos
run: |
  echo "Rama:   ${{ github.ref_name }}"
  echo "Commit: ${{ github.sha }}"
env:
  API_KEY: ${{ secrets.API_KEY }}   # se pasa, no se imprime
ContextoQué trae
githubEvento, repositorio, rama, SHA, quién lo lanzó
envVariables definidas a nivel de workflow, job o step
secretsValores cifrados del repositorio o del environment
runnerSistema operativo, arquitectura, directorio temporal
needsLos outputs y el resultado de los jobs de los que dependes

Un secreto se pasa como variable de entorno y no se imprime nunca. GitHub enmascara en los logs los valores que conoce, pero esa red se rompe en cuanto el valor se transforma: si lo trocean, lo codifican en base64 o lo concatenan con otra cosa, lo que sale por el log ya no coincide con el patrón que el enmascarado busca, y aparece en claro.

Auditoría La tabla de runners de la guía afirma que ubuntu-latest es Ubuntu 22.04, que macos-latest es macOS 14, y asigna «2000 min/mes (free)» por igual a las cuatro filas. Dos preguntas antes de fiarse. ¿A qué fecha corresponde ese mapeo de latest, si la etiqueta se mueve sola cada vez que GitHub promociona una imagen nueva — es decir, si el dato caduca solo? Y sobre los minutos: ¿consumen igual los cuatro runners, o hay un multiplicador que hace que un minuto de Windows o de macOS descuente más que uno de Ubuntu? Si lo hay, una tabla con la misma cifra repetida cuatro veces induce a error justo en la decisión que más dinero cuesta.
Para hacer
Provocar el error que enseña la regla

Escribe un workflow con dos jobs. El primero hace echo hola > prueba.txt. El segundo lleva needs: [primero] y hace cat prueba.txt. Empújalo y mira cómo falla.

Ese No such file or directory es la lección entera en una línea. Ahora arréglalo subiendo el fichero con actions/upload-artifact y descargándolo en el segundo job: la frontera entre jobs deja de ser algo que has leído y pasa a ser algo con lo que te has chocado.