Actions avanzado

Por: Artiko
githubgithub-actionsmatrixcomposite-actionsdevops

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:

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.


AnteriorCapítulo 3: Triggers y eventos · SiguienteCapítulo 5: Reusable workflows