needs e if en GitHub Actions: deploy no corre si test falló
Resumen
jobs.<id>.needs ordena jobs. if: success() es el default; if: always() corre aunque el previo falle (logs). Un agente que pone deploy sin needs o con always() en prod publica basura. Distinct de matrix. Docs GitHub workflow syntax needs + if.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
Jobs en paralelo no esperan. needs: [lint, test] hace que deploy arranque después y, por default, solo si lint y test pasaron (success()).
if: always() en deploy es el bug clásico: el agent “quiere el artifact aunque falle” y publica a prod. always() es para upload de logs.
No es strategy.matrix (expande celdas). El curso instalar un agente no cubre needs. gh pr no ordena jobs.
Receta
test:
runs-on: ubuntu-latest
steps:
- run: pnpm test
deploy:
needs: test
if: success()
runs-on: ubuntu-latest
steps:
- run: echo deploy
logs:
needs: test
if: always()
runs-on: ubuntu-latest
steps:
- uses: actions/upload-artifact@v4
with:
name: logs
path: logs/
if: cancelled() y failure() existen. No inventes if: failed.

Qué no hacer
- Tres jobs sin
needsy un “espero que GitHub los serialice”. needscircular. YAML inválido.if: always()+ Environment production.
needs de una matrix espera todas las celdas.
Receta AGENTS.md
Deploy jobs: needs: test and if: success() (or omit if — default).
if: always() only for logs/artifacts, never production deploy.
Do not skip needs to "save minutes".

FAQ
¿outputs? needs.test.outputs.foo solo si el job test definió outputs.
¿skipped? Un job skipped no es success. Encadena con cuidado (!cancelled()).
¿dos needs? Lista: needs: [a, b]. Ambos deben pasar.
Verificado 2026-09-03 contra GitHub workflow syntax jobs.<job_id>.needs y status check functions (success, always, failure).
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git status para coding agents: porcelain, XY, no el long

Reusable workflows: workflow_call, no copies el YAML entre repos

schedule (cron) en GitHub Actions: UTC, no cada minuto
