Despliegue selectivo con Nx Affected y GitHub Actions

Despliegue selectivo con Nx Affected y GitHub Actions

Miguel Camargo
Miguel Camargo

Despliegue selectivo con Nx Affected y GitHub Actions

En este artículo veremos cómo automatizar CI/CD en un monorepo Nx usando nx affected y GitHub Actions, para construir y desplegar solo los proyectos afectados por los últimos cambios.

👉 Este ejercicio busca ser una guía práctica y educativa que demuestre cómo Nx puede optimizar el tiempo y costo en procesos de integración y despliegue, especialmente en entornos con múltiples proyectos o apps.

🔍 Ver repositorio en GitHub – miguelfercamargo/nx-gha-affected-deploy


🎯 Objetivo del ejercicio

El objetivo principal es:

  • Implementar una estrategia de CI/CD eficiente en un monorepo.
  • Usar nx affected para detectar proyectos modificados.
  • Ejecutar solo los jobs necesarios en GitHub Actions.
  • Simular el despliegue condicional según la app afectada.

🧠 ¿Qué es Nx affected?

nx affected es una de las funcionalidades más poderosas de Nx, ya que permite detectar qué proyectos se ven realmente impactados por los cambios en el código fuente. En lugar de ejecutar tareas como build, test o lint en todo el monorepo, nx affected limita la ejecución solo a los proyectos que fueron modificados o dependen de los que cambiaron.

🔍 ¿Por qué es importante esto?

Muchos proyectos usan monorepos con Nx pero siguen ejecutando comandos de forma manual o global, por ejemplo:

"scripts": {
  "lint": "nx run-many --target=lint --all",
  "test": "nx run-many --target=test --all",
  "build:app-a": "nx build app-a",
  "build:app-b": "nx build app-b"
}

Esto funciona, pero es menos eficiente: estás corriendo tareas innecesarias en proyectos que no se vieron afectados por el cambio.

🧠 ¿Qué hace nx affected diferente?

Sin Nx AffectedCon Nx Affected (nx affected -t ...)
🔁 Ejecuta tareas en todos los proyectos🎯 Ejecuta tareas solo en los proyectos modificados
🐢 Puede ser lento en monorepos grandes⚡ Más rápido y eficiente
🤷 No aprovecha el grafo de dependencias🧠 Usa el grafo para saber qué depende de qué
💥 Riesgo de errores por tareas innecesarias✅ Minimiza errores, foca en lo importante

✅ ¿Cuándo usar nx affected?

  • Cuando tienes un monorepo con múltiples aplicaciones o librerías.
  • Cuando quieres optimizar tus pipelines de CI/CD.
  • Cuando quieres evitar correr builds o tests innecesarios.
  • Cuando deseas paralelizar tareas y acelerar los tiempos de ejecución.

En resumen, nx affected ayuda a que tu monorepo escale y tu CI/CD no se vuelva lento e ineficiente.

📚 Documentación recomendada


⚙️ ¿Y qué pasa cuando combinamos nx affected con GitHub Actions Matrix?

Usar nx affected por sí solo ya mejora mucho tu flujo de CI, pero aún puedes dar un paso más: ejecutar los builds y despliegues de cada app afectada en paralelo, gracias a la funcionalidad de matrix strategy de GitHub Actions.

Esto permite lanzar múltiples jobs independientes —uno por cada proyecto afectado— de forma simultánea, reduciendo drásticamente los tiempos de ejecución y permitiendo además personalizar la lógica según cada proyecto.

🚀 ¿Qué ventajas tiene esto?

  • Cada app afectada se construye o despliega en su propio job.
  • Puedes simular despliegues condicionales a diferentes ambientes.
  • El log de cada app queda separado, facilitando el análisis de errores.
  • Aumenta la escalabilidad y claridad en entornos con muchas apps.

🔬 Comparación: Nx Affected secuencial vs con Matrix (GitHub Actions)

EstrategiaVentajasDesventajas¿Cuándo usarla?
Nx Affected (secuencial)✅ Configuración sencilla
✅ Ideal para equipos pequeños
✅ Menos complejidad de CI/CD
🐢 Ejecución más lenta (todo en un solo job)
🔍 Logs mezclados por app
🔹 Monorepos con pocas apps o librerías
🔹 Equipos que no requieren paralelismo
🔹 Fase inicial de un proyecto donde el overhead no es justificado
Nx Affected + Matrix⚡ Jobs en paralelo (uno por app)
🧠 Personalización por app (ambientes, comandos)
📈 Escalabilidad y claridad en grandes flujos
🧩 Curva de aprendizaje
🔧 Configuración inicial más compleja
🔹 Monorepos medianos o grandes con múltiples apps/librerías
🔹 Necesidad de reducir tiempos de CI/CD
🔹 Equipos con múltiples flujos y ambientes por app
Nx run-many sin affected🔧 Control explícito sobre qué apps ejecutar.
Ejemplo: Ejecuta el build en ambas apps, aunque no hayan sido modificadas o Ejecuta los tests en todos los proyectos, afecten o no al cambio.
🧰 Fácil de entender para scripts locales
❌ No detecta cambios automáticamente
💥 Riesgo de correr tareas innecesarias
🔹 Casos donde se ejecutan tareas manuales fuera de CI
🔹 Migraciones desde proyectos multi-repo hacia monorepo
Sin Nx (build/test global)😐 Solución genérica y compatible con cualquier estructura🔴 Ineficiente
🌀 Escala mal en monorepos
🔹 Proyectos heredados
🔹 Cuando no se ha adoptado Nx por completo

📌 Recomendación general: si estás en un monorepo y ya usas Nx, deberías empezar por nx affected secuencial, y cuando tu equipo y CI/CD lo permitan, migrar gradualmente a usar matrix para maximizar eficiencia y escalabilidad.


🚀 ¿Y qué pasa con la paralelización de Nx?

Nx ya soporta paralelización y distribución de tareas dentro de su propia CLI, así como a través de Nx Cloud para entornos más avanzados.

🔧 Opciones disponibles

  • --parallel: Ejecuta tareas en paralelo en tu máquina local.
  • --max-parallel: Define cuántas tareas se ejecutan al mismo tiempo.
  • npx nx-cloud start-ci-run: Distribuye tareas entre múltiples agentes (runners) conectados con Nx Cloud.
  • --exclude, --only-failed, --skip-nx-cache: Personaliza qué tareas ejecutar y cómo.

📘 Puedes leer más en la documentación oficial:
Paralelización y distribución con Nx


📁 Estructura del proyecto

apps/
├── app-a/
   └── src/main.ts
├── app-b/
   └── src/main.ts
└── shared/
    └── src/lib/shared.ts

🔁 Funcionamiento del flujo CI/CD

El flujo definido en GitHub Actions se divide en 4 jobs:

  1. Install: Instala dependencias.
  2. Detect Affected: Usa nx show projects --affected para determinar los cambios.
  3. Build: Construye solo las apps afectadas (con matrix).
  4. Deploy: Simula despliegue de apps afectadas, con lógica de ambiente.

🧪 Evidencias del comportamiento

  1. ✅ Si se modifica solo app-b, se ejecuta únicamente app-b en la matriz.
  1. ✅ Si se modifica shared, se ejecutan app-a, app-b (porque dependen).
  1. ✅ Si no hay cambios en apps, el deploy se salta automáticamente.