Poner fin al dolor: Repensando CI para Monorepos Grandes

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Escalar bases de código grandes, especialmente monorepos, puede ser una pesadilla en los sistemas de Integración Continua (CI). El panorama actual de las herramientas de CI tiende a ser orientado a máquinas, de bajo nivel y exigente en términos de mantenimiento. Lo peor es que a menudo están desconectadas de las necesidades y el flujo de trabajo real del desarrollador.

¿Por qué es un obstáculo el CI? Porque los sistemas de CI actuales son comodines, sin una comprensión específica de tu base de código. No pueden aprovechar el contexto en el que operan para ofrecer optimizaciones.

En esta charla, exploraremos el futuro del CI, diseñado específicamente para bases de código grandes y monorepos. Imagina un sistema de CI que comprenda la estructura de tu espacio de trabajo, paralelice dinámicamente las tareas en máquinas utilizando datos históricos, y haga todo esto con una configuración mínima y de alto nivel. Repensemos el CI, haciéndolo más inteligente, eficiente y alineado con las necesidades del desarrollador.

This talk has been presented at DevOps.js Conf 2024, check out the latest edition of this JavaScript Conference.

FAQ

Un monorepo es un repositorio que contiene múltiples proyectos o productos, que pueden tener interdependencias entre sí. La estructura de un proyecto en un monorepo debe garantizar consistencia en la configuración y versiones utilizadas, y permitir movilidad entre proyectos para facilitar su mantenimiento y automatización.

Los principales desafíos incluyen la optimización de la configuración de CI para manejar múltiples proyectos simultáneamente, la necesidad de ejecutar tareas en paralelo para evitar tiempos de espera largos en cada PR, y la complejidad de mantener y ajustar la configuración de CI conforme el monorepo crece y cambia.

NX es una herramienta de gestión de monorepos que ofrece funciones como la ejecución paralela de tareas y la capacidad de ejecutar solo nodos afectados por cambios recientes. Esto ayuda a optimizar el tiempo de CI y a manejar las dependencias dentro del monorepo de manera eficiente.

NX Replay es una característica de NX que actúa como una caché de cálculos distribuida. Calcula una clave hash basada en diversas fuentes, como código fuente y variables de entorno, y almacena los resultados de las tareas junto con esta clave. Si un cálculo posterior coincide con la clave hash, NX puede reproducir los resultados sin necesidad de recomputación.

NX permite la distribución de tareas en múltiples máquinas y la generación dinámica de tareas para pruebas de extremo a extremo, lo que ayuda a reducir significativamente los tiempos de ejecución de CI. Además, su capacidad para detectar y reejecutar tareas inestables mejora la confiabilidad de los procesos de CI.

La escalabilidad dinámica de NX permite adaptar el número de máquinas utilizadas en función del volumen de tareas, optimizando los recursos y reduciendo costos. Esto asegura una distribución eficiente y la capacidad de manejar fluctuaciones en la carga de trabajo sin configuración manual continua.

NX facilita la división dinámica de pruebas de extremo a extremo en tareas más pequeñas que pueden distribuirse entre varias máquinas. Esto permite una ejecución más rápida y eficiente de las pruebas, reduciendo los cuellos de botella y mejorando el rendimiento general de CI.

Juri Strumpflohner
Juri Strumpflohner
25 min
15 Nov, 2023

Comments

Sign in or register to post your comment.
Video Summary and Transcription
La charla de hoy analiza la reevaluación del CI en monorepos, con un enfoque en aprovechar el gráfico implícito de dependencias de proyectos para optimizar los tiempos de compilación y gestionar la complejidad. Se destaca el uso de NX Replay y NX Agents como una forma de mejorar la eficiencia del CI mediante el almacenamiento en caché de cálculos anteriores y la distribución de tareas en múltiples máquinas. Se discuten la distribución detallada y la detección de fallas como métodos para mejorar la eficiencia de la distribución y garantizar una configuración limpia. Habilitar la distribución con NX Agents simplifica el proceso de configuración, y NX Cloud ofrece escalabilidad dinámica y reducción de costos. En general, la charla explora estrategias para mejorar la escalabilidad y eficiencia de los flujos de CI en monorepos.

1. Introducción a Repensar CI en Monorepos

Short description:

Hoy, me gustaría hablar sobre cómo podríamos repensar cómo funciona CI en monorepos. Mi nombre es Joris Sturmfloner y he estado utilizando monorepos durante seis años. También soy miembro del equipo principal de NX y un experto desarrollador de Google en tecnologías web y Angular.

[♪ música tocando ♪ Muy bien. Hoy me gustaría hablar un poco sobre cómo podríamos repensar cómo funciona CI en comparación con la situación actual de CI que tenemos, con un enfoque particular en monorepos y monorepos grandes potencialmente. Cómo podríamos optimizar eso. Antes de continuar, mi nombre es Joris Sturmfloner. He estado utilizando monorepos durante probablemente seis años. Desde hace unos cuatro años, también soy miembro del equipo principal de NX, que es una herramienta de gestión de monorepos. Y también soy un experto desarrollador de Google en tecnologías web y Angular y también soy instructor en AgHead, donde publico cursos sobre desarrollo web y herramientas para desarrolladores.

2. Consideraciones para CI en Monorepos

Short description:

Al trabajar con monorepos, debemos considerar la experiencia local del desarrollador, la automatización y las reglas, y los pipelines de tareas. Las soluciones de CI actuales no están optimizadas para monorepos y requieren un mantenimiento manual a nivel bajo. Los desarrolladores desean una forma de definir su estructura de CI a alto nivel y necesitan estrategias para garantizar la escalabilidad y la velocidad y el rendimiento manejables.

Entonces, cuando nos adentramos en la dirección de un monorepo, no es gratuito, ¿verdad? Hay algunas consideraciones que deben tenerse en cuenta. Una de las más importantes es, obviamente, la experiencia local del desarrollador. ¿Cómo estructuramos un proyecto en un monorepo? ¿Cómo nos aseguramos de tener consistencia en cómo se configuran estos productos? ¿Qué versión utilizan? ¿Cómo se configuran de manera que también podamos tener cierta movilidad entre proyectos, potencialmente, y también nos ayude a mantenerlos? La automatización y las reglas en torno a esos proyectos también son una parte muy importante, especialmente en lo que respecta al mantenimiento y la longevidad de dicho monorepo.

También cosas como características de los pipelines de tareas, poder ejecutar cosas en paralelo. Porque claramente en un monorepo, ya no ejecutamos solo un proyecto, sino potencialmente una serie de proyectos donde también hay dependencias. Y por lo tanto, necesitamos poder construir productos dependientes primero antes de ejecutar nuestro proyecto. Y esas son cosas que no queremos hacer manualmente, sino que queremos tener soporte de herramientas. Pero hoy me gustaría centrarme específicamente en el elefante en la habitación cuando hablamos de monorepos, que a menudo no se le presta atención de inmediato, lo cual es un error, que es CI. Porque claramente hay algo: la situación actual de CI no está optimizada para monorepos porque está muy orientada a la máquina, por lo que debemos centrarnos en instrucciones exactas que queremos procesar. Necesitamos tener un enfoque muy instructivo. También es muy detallado en ese sentido. Requiere mucho mantenimiento porque, como mencioné, ya no ejecutamos solo un proyecto y ya está. Ejecutamos una serie de proyectos. Ejecutamos múltiples proyectos. Y por lo tanto, necesitamos tener estrategias para ajustar el CI para asegurarnos de que incluso cuando cambia la estructura de nuestro monorepo, cuando se agregan más productos al monorepo, siga funcionando. También diría que está un poco alejado de lo que los desarrolladores desean, porque como desarrollador, me gustaría tener una forma más a alto nivel de definir mi estructura de CI, mi ejecución de CI, mi pipeline de CI, en el sentido de decir, hey, quiero ejecutar todos estos proyectos que se han modificado, por ejemplo, en ese PR, en lugar de tener que ajustar cada aspecto de ese proyecto. Y como dije antes, realmente no funcionan para monorepos, están diseñados para ser mucho más generales y para espacios de trabajo de proyectos individuales en general. Así que hoy me gustaría adentrarme en algunos de estos aspectos, específicamente en lo que respecta a la velocidad y el rendimiento, porque eso es algo importante en lo que debemos prestar atención, porque de lo contrario nuestro monorepo sería un problema. Porque si tenemos una buena colaboración local dentro de los equipos, pero nuestro pipeline tarda más de una hora en cada PR, eso será un problema.

3. Gestión de la Complejidad y Mantenibilidad en CI

Short description:

Para mantener una CI compleja y mantenible en monorepos, es clave aprovechar el grafo implícito de las dependencias del proyecto. Al paralelizar las ejecuciones y utilizar un pipeline de tareas, podemos optimizar los tiempos de construcción y tener en cuenta las dependencias entre proyectos. Además, al ejecutar nodos afectados, podemos probar y construir selectivamente proyectos ascendentes. Estas consideraciones son cruciales para una configuración de CI eficiente y escalable.

Y también, al analizar el aspecto de la complejidad y mantenibilidad, porque claramente, como mencioné antes, no queremos tener que hacer todas las ejecuciones en paralelo, iniciar manualmente máquinas, cosas así. Así que quiero explorar un enfoque potencialmente diferente que podría ayudar con esa complejidad y mantenibilidad. Esto es bastante obvio, ¿verdad? Si tenemos más proyectos en un solo repositorio, este tiempo de CI se sumará, porque ahora no solo necesitamos construir, probar, hacer linting y ejecutar pruebas de extremo a extremo para un proyecto, sino que ahora tenemos cinco, diez, cien, que fácilmente pueden ser un número considerable. He estado trabajando con clientes que tienen más de 600 productos en un solo monorepo. Y por lo tanto, estamos hablando potencialmente de tamaños como esos.

Como mencioné antes, si no prestamos atención al aspecto de CI en un monorepo, podríamos encontrarnos con congestión básicamente. Y obtenemos resultados como estos, que básicamente no son manejables porque los desarrolladores encontrarán soluciones alternativas. Como necesitan enviar, tienen un sprint en marcha donde necesitan entregar ciertas características. Y si cada ejecución de PR lleva más de una hora, comienzan a agrupar PR en uno solo, agrupando características en un solo PR. Y luego tenemos esos cambios masivos de más de 200 archivos, que son imposibles de revisar. Y, por lo tanto, la calidad obviamente se ve afectada en gran medida.

Entonces, lo que queremos tener es algo como esto, obviamente. Queremos mantener eso lo más bajo posible y mantenerlo casi plano, idealmente, y no algo que crezca exponencialmente con más y más productos que tenemos en nuestro monorepo. ¿Cómo lo hacemos? Una de las cosas fundamentales que tiene cada monorepo de alguna manera implícita detrás de escena es un grafo. Los proyectos en un monorepo se referencian entre sí. Eso puede ser a través de un mecanismo de resolución de dependencias, dependiendo de la herramienta que estés utilizando, pero también puede ser simplemente la referencia en un package JSON, donde se referencia la fuente del otro paquete en el que dependes. Por lo tanto, hay un grafo que se construye en un monorepo, que refleja las dependencias.

Y podemos aprovechar esa información del grafo, diciendo cosas como si ejecutas la construcción para este producto, o sirves este producto si es una aplicación, por ejemplo, podemos mirar la configuración de tu monorepo y decir, potencialmente también necesitamos construir primero sus hijos dependientes, porque eso podría ser una dependencia y una entrada para que ese otro producto se ejecute realmente, porque esos deben construirse primero. Y esas son cosas que podemos especificar, generalmente para las cuales necesitamos una herramienta para no tener que configurar manualmente eso y cambiarlo a medida que cambia la estructura. Y por lo tanto, claramente no queremos tener cosas como estas, sino que queremos tener una ejecución paralela tanto como sea posible para ahorrar tiempo. Y nuevamente, como puedes ver aquí, tener en cuenta estas dependencias potenciales que existen entre proyectos, donde esto puede depender de la salida del anterior, como acabas de ver. Y por lo tanto, necesitamos tener un mecanismo lo suficientemente inteligente que, cuando realiza tal paralelización, también tenga en cuenta esas cosas, que generalmente se refiere como un pipeline de tareas, donde podemos definir de manera bastante sencilla cómo se ven estas dependencias, aprovechando también el grafo detrás de escena. Y esto es algo que, por ejemplo, hacemos en NX, porque es algo básico que necesitas tener en un monorepo.

Otra cosa es poder ejecutar solo nodos afectados en CI, pero también localmente. Con nodos afectados, me refiero básicamente a que si cambias un producto aquí en el medio, podemos inferir que potencialmente necesitamos ejecutar las pruebas, construir y ejecutar pruebas de tendencia, también de estos proyectos ascendentes, porque dependen de ese producto que hemos cambiado. Y potencialmente podríamos necesitar volver a ejecutar porque tal vez introducimos algún cambio que rompe y ya no se construyen o las pruebas ya no pasan. Por lo tanto, necesitamos ajustar eso. Y con un mecanismo así, que llamamos afectado, porque es literalmente un comando que puedes ejecutar, NX afectado, y luego le das un objetivo para el cual quieres calcular esos nodos afectados. Eso nos da la capacidad de crear o ejecutar solo un subconjunto de la cantidad total de proyectos que podríamos tener en un monorepo en nuestro sistema de CI. Y por lo tanto, ya puedes ver que estas son consideraciones que deberían tenerse en cuenta en nuestra configuración de CI para asegurarnos de que esa curva que hemos visto antes se mantenga lo más baja posible.

4. Optimización de CI con NX Replay y NX Agents

Short description:

NX Replay es un mecanismo de almacenamiento en caché distribuido y remoto que optimiza los cálculos almacenando y reproduciendo los resultados de cálculos anteriores. Esta función, junto con NX Agents, mejora la eficiencia de los pipelines de CI en monorepos. Al aprovechar los resultados de caché y volver a calcular selectivamente los nodos afectados, podemos acelerar significativamente el proceso de CI. Además, al cambiar un nodo con muchos proyectos dependientes, como un sistema de diseño o bibliotecas de autenticación, el cálculo puede optimizarse aún más.

En general, lo que hemos descubierto, al trabajar mucho con empresas y grandes monorepos, son estos tres aspectos. Como los que acabamos de ver como la paralelización y los afectados. Esos son requisitos previos, pero los que realmente marcan la diferencia son estos tres aproximadamente. Ahora, estos también son términos de marketing. Así que no te distraigas con eso, pero básicamente son esas tres características mientras que NX workflows es algo que vendrá más adelante. Así que nos estamos centrando en NX Replay y NX Agents.

Entonces, lo que es NX Replay, es básicamente una caché de cálculos. Ahora lo llamamos Replay. Dije, como, es un término de marketing si quieres, pero básicamente es un almacenamiento en caché remoto distribuido que puedes agregar a tus proyectos. Y Replay, por lo tanto, porque literalmente reemplaza el cálculo. Es decir, si tienes un proyecto, calculará una clave hash a partir de varias fuentes. Eso incluye el código fuente en sí, variables de entorno, cosas como variablesruntime que también puedes incluir en esa clave. Y luego calcula una clave y almacena el resultado junto con esa clave. Y así, si ejecutamos otro cálculo nuevamente y tenemos una clave coincidente, restauraremos y reproduciremos tanto la salida en la terminal como los artefactos. Porque claramente algunos de los comandos, algunas de las tareas pueden producir archivos JavaScript compilados o archivos CSS u otro tipo de procesamiento que estés realizando. Y esos también se reproducen. Y por eso se llama NX Replay. Y esto es muy valioso porque si volvemos a mirar nuestra situación de afectados, donde cambiamos el nodo en el medio, lo enviamos como PR a nuestro repositorio, nuestro pipeline se ejecuta, identifica estos son los nodos afectados. Pero ¿qué sucede durante el procesamiento, ahora uno de los proyectos ascendentes falla las pruebas porque como dijimos antes, hemos cambiado algo, las pruebas ya no pasan. Necesitamos arreglarlo. Entonces, lo que hacemos nuevamente, descargamos ese PR, lo arreglamos, lo enviamos nuevamente. Ahora, si solo tuviéramos afectados, tendríamos que volver a ejecutar todos estos nodos. Pero si lo piensas, no tiene sentido calcular algunos de ellos porque literalmente no han cambiado. Por lo tanto, eso forma parte del grafo ahora más pequeño, el grafo de los afectados no se ve afectado porque se extraerá de la caché ya que tenemos una clave de caché coincidente que podemos reproducir ahora. Y solo nos quedan otros dos proyectos que están aquí, como puedes ver aquí con el reloj de arena, que deben volver a calcularse. Como puedes ver, podemos limitar aún más ese camino y hacerlo aún más rápido. Y obviamente, a medida que más miembros del equipo trabajen en nuestros proyectos, obtendremos más resultados de caché naturalmente. Y por lo tanto, nuestras PRs podrían ser más rápidas. Ahora, otro punto es, ¿qué sucede si ocurren esos escenarios más extremos, donde cambiamos un nodo que simplemente, tiene muchos proyectos dependientes, porque es una parte central.

5. Distribución de tareas con NX Agents

Short description:

Cuando se trata de proyectos que tienen muchos proyectos dependientes, como sistemas de diseño o bibliotecas de autenticación, distribuir tareas en múltiples máquinas puede mejorar la eficiencia. Sin embargo, la distribución manual puede ser desafiante debido a las diferentes duraciones de las tareas y la necesidad de ajustar el número de máquinas. Los scripts personalizados pueden ayudar a distribuir tareas, pero requieren mantenimiento y no se adaptan bien a las estructuras de proyectos cambiantes. Para abordar estas dificultades, se han desarrollado los NX agents para distribuir tareas de forma dinámica en función de los datos históricos y el grafo del proyecto. Con los NX agents, describes qué tareas ejecutar sin especificar cómo se distribuyen. Además, los NX agents ofrecen escalado dinámico, distribución detallada y rerun automático de tareas inestables. Al activar la distribución con un comando sencillo, las tareas se pueden distribuir en múltiples máquinas, mejorando la eficiencia de los pipelines de CI.

Podría ser, por ejemplo, un design system, que es uno común, pero también algunas bibliotecas de lógica de authentication o cosas así, donde muchos de nuestros proyectos dependen de ello. Y si lo cambiamos, a menudo nos encontramos con un escenario de peor caso donde los proyectos defectuosos son casi todo el grafo, porque todo el proyecto depende de eso. Por lo tanto, lo que se hace generalmente es distribuir. En lugar de simplemente paralelizar las cosas tanto como sea posible en la misma máquina, lo que intentamos hacer es distribuirlos en diferentes máquinas.

Entonces aquí puedes ver, distribuirlos en la máquina uno, máquina dos, máquina tres. Lo que puedes ver aquí, sin embargo, es que es una distribución muy uniforme, ¿verdad? Y eso es lo que generalmente sucede si lo configuras manualmente. Porque la distribución es difícil, porque necesitas codificarla de alguna manera. Y una forma muy directa, potencialmente ingenua de hacerlo es simplemente dividirlo por las diferentes tareas que tienes y luego ejecutarlo en diferentes máquinas.

Entonces aquí puedes ver, los diferentes tiempos de ejecución pueden llevar potencialmente a una baja eficiencia, porque algunas tareas pueden llevar mucho tiempo, y por lo tanto, la ejecución completa lleva más tiempo, pero otras máquinas ya están inactivas, porque su tarea, digamos el linting, fue más rápido, y ya han terminado. También el número de máquinas es estático. Por lo general, defines el número de máquinas, y eso es básicamente el número que está fijo allí. Y necesitas ajustarlo con el tiempo a medida que la estructura de tu monorepo obviamente se vuelve más grande y crece. Y también hay complejidad potencialmente en la puesta en marcha de esas máquinas, dependiendo de tu proyecto o proveedor de CI que estés utilizando.

Muy a menudo veo scripts que se hacen en CI. Por ejemplo, NX tiene una API programática, por lo que puedes calcular esos nodos afectados programáticamente, y luego intentar mezclarlos de alguna forma inteligente, donde los distribuyes en diferentes máquinas e incluso generas pipelines dinámicamente. Este es un ejemplo para GitLab, que te permite crear nodos dinámicamente, y así tener algún tipo de distribución. Pero es algo muy estático como puedes ver, porque está codificado en tu código, y no puede adaptarse realmente a una estructura de monorepo cambiante. Por lo tanto, esto requiere mucho mantenimiento.

Después de ver algunas de estas dificultades que enfrentan los equipos al crear estos scripts personalizados, hemos estado investigando lo que llamamos NX agents, básicamente para ayudar con esa distribución, específicamente para configurar las máquinas, pero también con la dinamicidad de la distribución en sí, para que no necesites ajustarlo continuamente a medida que tu estructura de monorepo crece, sino que la distribución se produciría dinámicamente en función del número de tareas que se ejecutan, pero también en función del tiempo de ejecución de estas tareas basado en datos históricos básicamente.

Por lo tanto, los NX agents intentan aprovechar el grafo del proyecto, porque tienen acceso al grafo NX en segundo plano, y por lo tanto, saben cómo se estructuran los proyectos, qué dependencias hay, lo cual es un punto importante cuando se distribuye, como distribuirlos de manera eficiente. Y describes qué quieres ejecutar, no cómo quieres ejecutarlos, sino que simplemente dices, quiero ejecutar la tarea afectada de construcción y linting, y las tareas de extremo a extremo de una cierta manera, pero no defines cómo se distribuyen.

Y una gran parte que viene con la primera versión de los NX agents es todo el aspecto de escalado dinámico, por lo que se generan más máquinas según el PR, pero también la distribución detallada y también la rerun automática de tareas inestables. Ahora, nos hemos centrado específicamente en las pruebas y las pruebas de extremo a extremo en este momento, pero en teoría, podemos detectar tareas inestables y volver a ejecutarlas automáticamente en CI. Así que echemos un vistazo. ¿Cómo se ve la descripción de lo que se ejecuta? Bueno, todo lo que necesitas hacer básicamente para activar la distribución es esta línea. Específicamente el dash-dash distributes on, donde proporcionas la información, quiero distribuir mis tareas que se ejecutan justo después en 15 máquinas, en este caso, de la nota Linux Medium plus JS. Y esos son nombres de máquinas basados en ciertas características, que obviamente puedes definir según las necesidades que tengas. Es algo así como una configuración de Docker casi. Y luego ejecutas los comandos reales. Y aquí puedes ver cómo describes qué ejecutar y no cómo.

6. Habilitando la distribución con NX Agents

Short description:

Habilitar la distribución con NX Agents aprovecha la información del grafo del proyecto para dividir las tareas en tareas más detalladas, que luego se distribuyen en las máquinas especificadas. La máquina coordinadora en la infraestructura de NX Cloud se encarga de la distribución, permitiendo un equilibrio y escalabilidad automáticos. Esta infraestructura también se puede alojar en las instalaciones. En tu CI, defines la distribución, mientras que la infraestructura en la nube se encarga de la gestión.

Simplemente habilitamos la distribución, tantas máquinas, estos son los comandos. Eso es todo, ¿verdad? Y lo que sucede es que se aprovecha la información del grafo del proyecto, que está disponible en CI. Activas ese script, como acabamos de ver, donde ejecutas la construcción afectada con la distribución activada. Eso se pasa a una máquina coordinadora, que se encuentra en la infraestructura de NX Cloud, y luego divide esas tareas y las distribuye en tareas más detalladas, que luego se distribuyen en el número de máquinas que especificaste.

Y la parte interesante es que si vemos que necesitamos más máquinas, podemos agregar algunas o incluso expandirlas dinámicamente, pero no tenemos que cambiar la configuración real subyacente. Y eso ayuda mucho con la sobrecarga de configuración o la complejidad que mencionamos inicialmente, porque ahora esto se puede equilibrar automáticamente. Es como si el coordinador ahora tuviera cuatro máquinas, mientras que toda la distribución ahora puede ocurrir en un enfoque diferente, en un enfoque potencialmente más eficiente. Y como dije, esto se aloja en la infraestructura de NX Cloud, que también puede estar en las instalaciones. Entonces, si necesitas tenerlo en las instalaciones, obviamente también funciona. Pero la parte principal aquí es que en tu CI, solo defines la distribución y la inicias, pero en la parte de la nube, básicamente se gestiona toda la infraestructura.

7. Distribución Detallada y Detección de Inestabilidad

Short description:

La distribución detallada permite dividir las pruebas de extremo a extremo en ejecuciones de prueba individuales a nivel de archivo, mejorando la eficiencia de la distribución y equilibrando las máquinas. NX puede crear automáticamente objetivos para cada archivo, lo que permite ejecutar pruebas a nivel de archivo. Un ejemplo concreto muestra cómo NX distribuye las pruebas de extremo a extremo en diferentes agentes, reduciendo el tiempo de ejecución de 90 minutos a 10 minutos. La detección de inestabilidad detecta y vuelve a ejecutar tareas inestables en diferentes máquinas para garantizar una configuración limpia.

Entonces, ¿cómo se ve la distribución detallada? Bueno, básicamente una de las grandes preocupaciones que a menudo tenemos es esa máquina en el medio. Así es, esa prueba de extremo a extremo, el bloque rojo que puedes ver, porque muy a menudo lo que sucede, es que tienes esas enormes pruebas de Cypress o Playwright que se ejecutan para una aplicación determinada, y son muy difíciles de dividir porque es solo un gran bloque, y ocupan una máquina completa, lo que puede llevar a que toda la distribución no sea eficiente.

Entonces, investigamos esto con una función que se implementará en NX 18, que nos permite dividir dinámicamente, crear dinámicamente tareas para objetivos, básicamente para una prueba de extremo a extremo a nivel de archivo, porque tanto Cypress como Playwright te permiten ejecutar archivos individuales con un filtro. Y así, NX puede hacerlo automáticamente con el resultado de que podemos dividirlos en ejecuciones de prueba a nivel de archivo individuales. Y así podemos agruparlos de manera inteligente, y ahora tenemos piezas mucho más detalladas que podemos distribuir, y así podemos equilibrar mejor las máquinas, y por lo tanto obtener mejores resultados.

Si observamos un ejemplo concreto, aquí hay un espacio de trabajo, un espacio de trabajo NX, con un par de aplicaciones Next.js con pruebas de extremo a extremo de Cypress, y aquí tengo algunas pruebas que son muy similares, que tienen algunas esperas aquí, algunas esperas para aumentar artificialmente o aumentar su tiempo de ejecución. También tengo instalado NX Console, y eso me permite ver qué objetivos se están definiendo para un proyecto así. Y así, si hago clic en ese enlace aquí, podemos ver que tenemos una prueba de extremo a extremo, pero NX detecta automáticamente que esta es una prueba de extremo a extremo de Cypress, y por archivo nos da básicamente un objetivo que se crea dinámicamente.

Y eso significa que ahora podemos no solo ejecutar toda la prueba de extremo a extremo, sino que también podemos ejecutar cada archivo individual automáticamente. Y esto es lo que NX hará a nivel de CI. Entonces, si hago aquí algunos cambios en esas páginas de la tripulación aquí, digamos que decimos aquí, HideArea3, y hagamos lo mismo aquí para el simulador de vuelo, solo para tener algunos cambios que están sucediendo aquí para que nuestras pruebas cambien. Y ahora, si agrego eso y lo subo a CI nuevamente, una vez que se haya subido, lo que sucederá es que CI ejecutará mi script aquí.

Y si observamos el script, esto ha sido generado automáticamente por NX. Hemos habilitado la distribución aquí con la distribución en cinco máquinas Linux por ahora. Entonces, este es un número estático de máquinas en las que estoy ejecutando la distribución. Y lo que quiero ejecutar es, en primer lugar, todas las pruebas y construcciones, y luego el extremo a extremo-CI, que son las piezas de CI distribuidas de manera detallada que puedo ejecutar en CI. Ahora aquí tengo solo el runMany, así que quiero ejecutar todos ellos. Entonces, si voy a mi repositorio aquí, puedes ver aquí la ejecución que se está iniciando. Así que ahora se está ejecutando la prueba de extremo a extremo.

Y si voy a la página de CI para NX Cloud, vemos que hay una ejecución de pipeline en progreso, que ahora ya distribuye esas pruebas de extremo a extremo en diferentes agentes. Entonces, puedes ver que ahora se está ejecutando una prueba por agente. Y esto depende en gran medida de cuántos agentes tenemos disponibles y cómo se está realizando la distribución aquí. También puedes ver que algunas cosas ya se han completado, y aquí puedes ver cómo se apilaron y cómo se está realizando esa distribución. Pero la parte importante aquí es que con un simple indicador, ahora distribuimos todas estas tareas en estas diferentes máquinas disponibles. Y hemos visto algunos ejemplos donde hemos pasado de una ejecución de extremo a extremo de 90 minutos en CI a 10 minutos solo con una distribución más detallada mediante los agentes de NX. De manera similar, podemos realizar la detección de inestabilidad porque podemos comprender según la caché si hay algunas tareas inestables que tienen, básicamente, si tienes una prueba ejecutándose en CI que se ha ejecutado antes con una determinada clave hash, y encontramos esa clave hash nuevamente en algún momento, pero ahora da un resultado diferente. Sabemos que podemos detectar esto y saber con certeza que son inestables. Y así podemos básicamente iniciarlos y moverlos a una máquina diferente solo para asegurarnos de tener una configuración limpia, una fase de inicio limpia y volver a ejecutarlos nuevamente. Entonces aquí puedes ver, por ejemplo, que hubo un intento en el lado izquierdo donde una prueba falló y sabíamos que era potencialmente una prueba inestable. Y así automáticamente se inició un nuevo intento y el segundo resultó en una ejecución correcta.

8. Repensando CI para Monorepos y NX Cloud

Short description:

Superficiar información y reintentar pipelines fallidos. La escalabilidad dinámica optimiza el uso de las máquinas y reduce los costos. NX Cloud simplifica la configuración de distribución con una sola bandera. La división de tareas y la detección de inestabilidad mejoran la eficiencia. Conéctate con NX Connect y explora nuestros recursos para obtener más información.

Y eso fue marcado. Y así podemos, en primer lugar, superficiar esa información, pero como puedes ver también, podemos reintentar automáticamente. Y así, básicamente, se ejecuta nuevamente todo el pipeline, tiene éxito en lugar de fallar. Como puedes ver aquí, esa ejecución está sucediendo.

Otra parte aquí también es la escalabilidad dinámica, porque claramente algunas de las PR pueden verse muy diferentes. Entonces tienes algunas PR que están ejecutando todas esas pruebas de extremo a extremo porque algunas partes se vieron afectadas y necesitamos ejecutarlas. Algunas como PR2 o PR4 son muy rápidas porque solo cambiamos un proyecto. Solo necesitamos ejecutar una prueba para eso, eso es todo. Y así, si tenemos un número estático de máquinas, eso podría ser subóptimo porque algunas de ellas podrían estar inactivas o la distribución terminará siendo una tarea por máquina lo cual es realmente ineficiente también en términos de costos.

Y así también permitimos no solo dar las máquinas, sino también dar un conjunto de cambios, un archivo de conjunto de cambios dinámico donde puedes definir máquinas para conjuntos de cambios pequeños, medianos y grandes. Entonces, ahora mismo damos este tipo de distribución y automáticamente distribuiremos según las notas afectadas en comparación con el conjunto completo de notas en un gráfico de proyecto, y lanzaremos cuatro, ocho o doce máquinas. Pero en el futuro, podemos comenzar a hacer un enfoque mucho más detallado donde potencialmente puedes definir un porcentaje del gráfico que clasificará para ti como pequeño, mediano o grande. Entonces te brinda aún más flexibilidad allí. Así que esto ha sido solo algunas de las cosas que quería mostrarte de cómo queremos comenzar a repensar cómo funciona CI, especialmente para los monorepos. Lo que realmente intentamos hacer en NX es brindarte la experiencia de extremo a extremo, ¿verdad? Así que tenemos el lado inteligente de los monorepos en la experiencia del desarrollador local donde venimos con herramientas que te ayudan a estructurar los monorepos, facilidades para permitirte automatizar fácilmente dichos monorepos. Pero también queremos asegurarnos de que no te quedes solo en CI con configuraciones complejas y scripts complejos en CI para asegurarnos de que también tengas éxito allí. Porque si CI no funciona, puedes tener la mejor experiencia de desarrollador local, pero eso simplemente será un problema y volverás a alejarte de los monorepos solo por esa razón. Y eso es lo que intentamos cubrir.

Lo hacemos con NX Cloud, que es nuestro producto allí. Puedes conectarte simplemente con NX Connect y eso te guiará a través de la configuración de toda la distribución. Y nuevamente, la parte importante aquí es la simplicidad de definir dicha distribución con una sola bandera. Y así, esa única bandera te brinda la distribución en estas máquinas, la escalabilidad dinámica potencial de estas máquinas, según el tamaño de la PR. Así que ahorras costos en realidad, y no ejecutas máquinas innecesariamente. La división de tareas, que es una combinación de NX que puede dividirlas dinámicamente, pero también ayuda en el lado de CI donde los agentes de NX pueden recoger esas tareas más detalladas y distribuirlas de manera mucho más eficiente. Y finalmente, también la detección de inestabilidad de tareas. Entonces, eso puede ser una tarea de extremo a extremo, pero potencialmente también puede ser cualquier otra tarea que pueda ser inestable. Y definitivamente revisa nuestro canal de YouTube. Hay muchos videos informativos y análisis más profundos que publicamos allí. Y de lo contrario, ponte en contacto, comunícate. Si tienes preguntas, mis mensajes directos también están abiertos en X, o tenemos un Discord, un Discord de comunidad, que es bastante activo. O, obviamente, puedes ir a nx.dev/docs. Tenemos todos los detalles allí. Gracias.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Elevando Monorepos con los Espacios de Trabajo de npm
DevOps.js Conf 2022DevOps.js Conf 2022
33 min
Elevando Monorepos con los Espacios de Trabajo de npm
Top Content
NPM workspaces help manage multiple nested packages within a single top-level package, improving since the release of NPM CLI 7.0. You can easily add dependencies to workspaces and handle duplications. Running scripts and orchestration in a monorepo is made easier with NPM workspaces. The npm pkg command is useful for setting and retrieving keys and values from package.json files. NPM workspaces offer benefits compared to Lerna and future plans include better workspace linking and adding missing features.
¿Por qué es tan lento el CI?
DevOps.js Conf 2022DevOps.js Conf 2022
27 min
¿Por qué es tan lento el CI?
Slow CI has a negative impact on productivity and finances. Debugging CI workflows and tool slowness is even worse. Dependencies impact CI and waiting for NPM or YARN is frustrating. The ideal CI job involves native programs for static jobs and lightweight environments for dynamic jobs. Improving formatter performance and linting is a priority. Performance optimization and fast tools are essential for CI and developers using slower hardware.
Despliegue Atómico para Hipsters de JavaScript
DevOps.js Conf 2024DevOps.js Conf 2024
25 min
Despliegue Atómico para Hipsters de JavaScript
This Talk discusses atomic deployment for JavaScript and TypeScript, focusing on automated deployment processes, Git hooks, and using hard links to copy changes. The speaker demonstrates setting up a bare repository, configuring deployment variables, and using the post-receive hook to push changes to production. They also cover environment setup, branch configuration, and the build process. The Talk concludes with tips on real use cases, webhooks, and wrapping the deployment process.
Cómo construir tuberías de CI/CD para una aplicación de microservicios
DevOps.js Conf 2021DevOps.js Conf 2021
33 min
Cómo construir tuberías de CI/CD para una aplicación de microservicios
Top Content
This Talk discusses the benefits of microservices and containers for building CI-CD pipelines. It explains how container technology enables portability and scalability. The challenges of microservices include network communication and testing in isolation. The Talk introduces Tacton, a cloud-native CICD pipeline for Kubernetes, and highlights the use of GitOps and Argo CD. It also discusses the importance of maintaining referential integrity between microservices and the evolving role of operators in the DevOps world.
Microfrontends Federados a Gran Escala
React Summit 2023React Summit 2023
31 min
Microfrontends Federados a Gran Escala
Top Content
This Talk discusses the transition from a PHP monolith to a federated micro-frontend setup at Personio. They implemented orchestration and federation using Next.js as a module host and router. The use of federated modules and the integration library allowed for a single runtime while building and deploying independently. The Talk also highlights the importance of early adopters and the challenges of building an internal open source system.
Escala tu aplicación de React sin micro-frontends
React Summit 2022React Summit 2022
21 min
Escala tu aplicación de React sin micro-frontends
This Talk discusses scaling a React app without micro-frontend and the challenges of a growing codebase. Annex is introduced as a tool for smart rebuilds and computation caching. The importance of libraries in organizing code and promoting clean architecture is emphasized. The use of caching, NxCloud, and incremental build for optimization is explored. Updating dependencies and utilizing profiling tools are suggested for further performance improvements. Splitting the app into libraries and the benefits of a build system like NX are highlighted.

Workshops on related topic

Monorepos de Node con Nx
Node Congress 2023Node Congress 2023
160 min
Monorepos de Node con Nx
Top Content
WorkshopFree
Isaac Mann
Isaac Mann
Varias apis y varios equipos en el mismo repositorio pueden causar muchos dolores de cabeza, pero Nx te tiene cubierto. Aprende a compartir código, mantener archivos de configuración y coordinar cambios en un monorepo que puede escalar tanto como tu organización. Nx te permite dar estructura a un repositorio con cientos de colaboradores y elimina las desaceleraciones de CI que normalmente ocurren a medida que crece la base de código.
Índice de contenidos:- Laboratorio 1 - Generar un espacio de trabajo vacío- Laboratorio 2 - Generar una api de node- Laboratorio 3 - Ejecutores- Laboratorio 4 - Migraciones- Laboratorio 5 - Generar una biblioteca de autenticación- Laboratorio 6 - Generar una biblioteca de base de datos- Laboratorio 7 - Añadir un cli de node- Laboratorio 8 - Limites de módulo- Laboratorio 9 - Plugins y Generadores - Introducción- Laboratorio 10 - Plugins y Generadores - Modificación de archivos- Laboratorio 11 - Configuración de CI- Laboratorio 12 - Caché distribuida
React a Escala con Nx
React Summit 2023React Summit 2023
145 min
React a Escala con Nx
Top Content
WorkshopFree
Isaac Mann
Isaac Mann
Vamos a utilizar Nx y algunos de sus plugins para acelerar el desarrollo de esta aplicación.
Algunas de las cosas que aprenderás:- Generar un espacio de trabajo Nx prístino- Generar aplicaciones frontend React y APIs backend dentro de tu espacio de trabajo, con proxies preconfigurados- Crear librerías compartidas para reutilizar código- Generar nuevos componentes enrutados con todas las rutas preconfiguradas por Nx y listas para usar- Cómo organizar el código en un monorepositorio- Mover fácilmente las librerías alrededor de tu estructura de carpetas- Crear historias de Storybook y pruebas e2e de Cypress para tus componentes
Tabla de contenidos: - Lab 1 - Generar un espacio de trabajo vacío- Lab 2 - Generar una aplicación React- Lab 3 - Ejecutores- Lab 3.1 - Migraciones- Lab 4 - Generar una librería de componentes- Lab 5 - Generar una librería de utilidades- Lab 6 - Generar una librería de rutas- Lab 7 - Añadir una API de Express- Lab 8 - Mostrar un juego completo en el componente de detalle de juego enrutado- Lab 9 - Generar una librería de tipos que la API y el frontend pueden compartir- Lab 10 - Generar historias de Storybook para el componente de interfaz de usuario compartido- Lab 11 - Prueba E2E del componente compartido
Despliega una aplicación de componentes web y configura un flujo de integración continua
DevOps.js Conf 2022DevOps.js Conf 2022
111 min
Despliega una aplicación de componentes web y configura un flujo de integración continua
Workshop
Philippe Ozil
Philippe Ozil
Únete a nosotros en un masterclass en el que desplegarás una aplicación Node.js simple construida con componentes web y configurarás un flujo de integración continua (CI). Aprenderás sobre el poder del Lightning Web Runtime (LWR) y las GitHub Actions.
Aporta Calidad y Seguridad al pipeline de CI/CD
DevOps.js Conf 2022DevOps.js Conf 2022
76 min
Aporta Calidad y Seguridad al pipeline de CI/CD
Workshop
Elena Vilchik
Elena Vilchik
En esta masterclass repasaremos todos los aspectos y etapas al integrar tu proyecto en el ecosistema de Calidad y Seguridad del Código. Tomaremos una aplicación web simple como punto de partida y crearemos un pipeline de CI que active el monitoreo de calidad del código. Realizaremos un ciclo completo de desarrollo, comenzando desde la codificación en el IDE y abriendo una Pull Request, y te mostraré cómo puedes controlar la calidad en esas etapas. Al final de la masterclass, estarás listo para habilitar esta integración en tus propios proyectos.
Potenciando tu CI/CD con GitHub Actions
DevOps.js Conf 2022DevOps.js Conf 2022
155 min
Potenciando tu CI/CD con GitHub Actions
Workshop
David Rubio Vidal
David Rubio Vidal
Obtendrás conocimiento sobre los conceptos de GitHub Actions, como:- El concepto de secretos de repositorio.- Cómo agrupar pasos en trabajos con un propósito determinado.- Dependencias y orden de ejecución de trabajos: ejecutar trabajos en secuencia y en paralelo, y el concepto de matriz.- Cómo dividir la lógica de los eventos de Git en diferentes archivos de flujo de trabajo (en empuje de rama, en empuje a master/principal, en etiqueta, en implementación).- Para respetar el concepto de DRY (No te repitas), también exploraremos el uso de acciones comunes, tanto dentro del mismo repositorio como desde un repositorio externo.