Actions avanzado
Actions avanzado
Con los fundamentos claros, subimos un nivel: correr un job contra muchas combinaciones a la vez, encadenar jobs pasándose datos, empaquetar secuencias repetidas y acelerar builds con cache y artifacts.
Matrix builds
strategy.matrix corre el mismo job contra todas las combinaciones de las variables que definas. Ideal para probar tu código en varias versiones de un runtime y varios sistemas operativos:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
max-parallel: 4
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci && npm test
Esto genera 6 jobs (2 OS × 3 versiones), corriendo en paralelo. Dos controles clave:
fail-fast(defaulttrue): si una combinación falla, cancela automáticamente el resto. Ponelo enfalsesi querés ver el resultado de todas.max-parallel: limita cuántos jobs de la matriz corren a la vez (útil si tenés cuota de runners acotada).
Encadenar jobs con needs
Por defecto los jobs corren en paralelo. needs fuerza un orden: un job espera a que terminen los que lista antes de arrancar.
jobs:
build:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.meta.outputs.version }}
steps:
- id: meta
run: echo "version=1.4.2" >> "$GITHUB_OUTPUT"
deploy:
needs: [build]
runs-on: ubuntu-latest
steps:
- run: echo "Desplegando ${{ needs.build.outputs.version }}"
Para pasar datos entre jobs se declaran outputs a nivel de job (alimentados por el $GITHUB_OUTPUT de un step) y el job dependiente los lee con needs.<job_id>.outputs.<nombre>.
Composite actions
Cuando repetís la misma secuencia de steps en varios workflows, la empaquetás en una composite action. Se define en .github/actions/<nombre>/action.yml con runs.using: "composite":
# .github/actions/setup-proyecto/action.yml
name: "Setup proyecto"
description: "Instala Node y dependencias"
runs:
using: "composite"
steps:
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
shell: bash
Se invoca desde cualquier workflow del mismo repo con una ruta relativa:
- uses: ./.github/actions/setup-proyecto
Así centralizás la secuencia en un solo lugar en vez de copiarla en cada workflow.
Caching de dependencias
actions/cache guarda directorios entre runs para no reinstalar todo cada vez. Se identifica el cache con una key (normalmente basada en el hash del lockfile) y restore-keys como fallback parcial:
- uses: actions/cache@v4
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: |
npm-
Sirve para node_modules, ~/.cargo, ~/.m2 y cualquier carpeta de dependencias. Si el key coincide, restaura el cache; si cambió el lockfile, se genera uno nuevo.
Artifacts entre jobs
Los artifacts transfieren archivos entre jobs de un mismo workflow run o conservan outputs de build para descargarlos después. Un job sube con upload-artifact y otro descarga con download-artifact:
build:
runs-on: ubuntu-latest
steps:
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
retention-days: 7
publish:
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: dist
retention-days controla cuánto se conservan antes de que GitHub los borre.
Cache vs artifacts
flowchart LR
subgraph Cache
C["Acelera runs futuros<br/>reutilizando dependencias"]
end
subgraph Artifacts
A["Comparte outputs de build<br/>entre jobs y descargas"]
end
Aunque ambos guardan archivos, tienen propósitos distintos: el cache optimiza builds reutilizando dependencias entre runs; los artifacts transportan los resultados del build (binarios, reportes, dist/) entre jobs o para descargar.
Anterior → Capítulo 3: Triggers y eventos · Siguiente → Capítulo 5: Reusable workflows