Prácticas de Desarrollo Continuo: CI, CD, CDE y DevOps
No hay comentarios

El desarrollo continuo tiene como finalidad agilizar tiempos de entrega del equipo de desarrollo desde la codificación hasta el usuario final. Este artículo tiene el objetivo de revisar cuáles son las prácticas que están siendo utilizadas para tal fin, como se caracterizan y cuáles son los desafíos de su aplicación.
Introducción: el desarrollo continuo
El desarrollo ágil se ha dado con prácticas como la programación extrema, test-driven development (desarrollo guiado por pruebas), la programación en parejas, prácticas de Scrum y Lean, pero hay un tema que ha estado emergiendo en el ámbito del desarrollo de software que requiere un enfoque especial, el desarrollo continuo, y sus enriquecidas “entregas continuas de valor” las cuales se basan en tendencias de entregas útiles y frecuentes en base al desarrollo iterativo e implementación continua de nuevas características.
Como bases fundamentales para dicha tendencia, nos podemos fijar en el manifiesto ágil, el cual se centra en la colaboración del cliente y el equipo de desarrollo de software, haciendo énfasis a uno de los principios detrás del manifiesto; satisfacer al cliente a través de la entrega temprana. Esto se debe a que dicha relación es uno de los principales desafíos, tanto así, que el cliente se vuelve uno de los efectos principales de adoptar métodos de desarrollo cada vez más ágiles.
Encuestas tomadas reflejan que son muchos los que están implementando prácticas de desarrollo continuo teniendo como principales razones, la adopción de métodos más ágiles para aumentar la productividad, la calidad de los productos y servicios, así como a su vez, reducir los tiempos del ciclo de desarrollo y el tiempo de comercialización. (Dingsøyr y Lassenius, 2016).
Igualmente Claps, Svensson, y Aurum (2015) exponen que el software se está desarrollando de una manera mucho más rápida en mercados que siguen evolucionando y se tornan impredecibles como no se había visto antes, cada vez hay requisitos más complejos y cambiantes según la decisión de los clientes, además de una presión continua de un tiempo de comercialización más corto.
Las soluciones por parte de las empresas se han estado presentando con la mejora de la capacidad de las prácticas ágiles que permitan abordar dichos requisitos cada vez más complicados. Haciendo que los profesionales del desarrollo de software ágil están mostrando un interés creciente por comprender el principio del «Desarrollo continuo de software«.
Si bien la adopción de prácticas para el desarrollo continuo puede crear nuevas oportunidades de negocio, su implementación también presenta desafíos y factores a tener en cuenta para así beneficiarse de las bondades que estas ofrecen.
Este artículo tiene como objetivo revizar las prácticas que actualmente se están ejerciendo para el desarrollo continuo, para ello se realizó la revisión de múltiples artículos científicos y libros, teniendo como fuentes principales de literatura, las bases de datos Elsevier, IEEE xplore y Springer.
Continuous Integration
La integración continua o continuous integration (CI) según Riti (2018) es una práctica con un enfoque para el desarrollo de software que requiere que los desarrolladores integren con frecuencia, el código realizado en un repositorio compartido central.
Cada vez que un desarrollador envía código, este se integra y se verifica mediante la ejecución de pruebas automatizadas. El paso anterior pertenece al ciclo de compilación o build y se resume en tres fases; desarrollo, pruebas e implementación. Una build se compone de todas las operaciones necesarias para lanzar el software y es esencialmente un proceso que reúne todo el código y verifica que todo funcione bien, este comienza cada vez que se realiza algún cambio, por ejemplo, la creación de un archivo o el cambio en una etiqueta HTML. Cuando se crea una compilación con éxito, esta queda disponible para que los miembros del equipo la usen. La esencia de CI es aportar al ciclo de vida del software cada vez que se envía código, verificando, testeando, integrando las nuevas características y retornando feedbacks.
Se pueden incluir pruebas en el ciclo de compilación, el sistema de un servidor CI prueba la solución completa, y solo continuará con el build si se pasan las pruebas. Los test que fallan se dan cuando un cambio presenta algún error, esto hace que la compilación se rompa justo después de que el cambio fue enviado al repositorio, y por lo general se envían notificaciones vía email a los miembros del equipo de desarrollo alertando del fallo.
Continuous Delivery
El concepto de entrega continua o continuous delivery (CDE) fue acuñada por Jeff Humble y David Farley en su libro “Continuous Delivery” publicado en 2010. Se define como una disciplina del desarrollo de software en la que el producto o desarrollo es mandado a producción en cualquier momento. La disciplina se logra mediante la optimización, la automatización del proceso de build, la implementación, prueba y lanzamiento, en este aspecto, se resuelve que CDE contiene a CI y tiene como ampliación el probar continuamente que las iteraciones de software recientes son de calidad de producción e implementables, para que en cualquier momento sea mandado a despliegue de manera manual.
Lo que hace especial el uso de CDE son sus beneficios al entregar software al usuario final de manera más frecuente, confiable y predecible, i.e., mayor visibilidad, entregas más rápidas, reducción de costos, reducción de los riesgos de implementación y retroalimentaciones más rápidas que a su vez, conduce a la minimización de errores y direcciones incorrectas tomadas en el desarrollo.
El personal de ventas puede decirle al cliente que el software está listo para implementarse cuando él lo solicite, si es su deseo ver los últimos resultados en acción, sin necesidad de esperar mucho tiempo por demoras en la implementación (Halki, 2016).
Continuous Deployment
La implementación continua o continuous deployment (CD) es una técnica que extiende al CI, esta toma características validadas de la CI haciendo que cada cambio se implemente automáticamente por todo el ciclo de vida del proyecto hasta su entrega en un entorno de producción donde se prueban y preparan para su lanzamiento. Su propósito se centra en minimizar el tiempo entre el desarrollo del producto y el uso del mismo por parte de los usuarios finales, ofreciendo soluciones incrementales y valiosas con la mayor frecuencia posible.
La entrega continua (CDE) y la implementación continua (CD) son dos técnicas distintas que a menudo se confunden entre sí. Por ejemplo, en CDE a veces, es posible que desee tener una revisión manual por parte de un operario, como pruebas de usabilidad antes de una versión final, pero muchos equipos de desarrollo no necesariamente implementa pasos manuales y eligen automatizar todo el proceso, aquí es donde la implementación continua entra a apoyar a la entrega continua, porque CD propone la automatización completa de una implementación y se manifiesta sin pasos manuales para implementar la última versión de una aplicación en un entorno de producción (Northwood, 2018).
Las prácticas CI, CDE y CD, están permitiendo integraciones, entregas, pruebas, despliegues y retroalimentaciones más rápidas y frecuentes. CI se había adoptado antes de CDE, y CD automatiza a CDE. La figura 1 muestra la relación entre estas prácticas, de la misma se puede entender por ejemplo, que CI garantiza el éxito de la fase de integración y que es una práctica contenida en CDE la cual a su vez, está contenida en CD.
DevOps
Milojicic et al., (2019) definen Devops como una evolución del movimiento ágil, partiendo de las prácticas de desarrollo continuo para proveer iteraciones en donde se den pequeñas liberaciones con reseñas de clientes. DevOps propone un set complementario de prácticas para permitir la entrega iterativa de software en ciclos cortos de manera efectiva, promoviendo así una colaboración cercana entre los desarrolladores y los operadores. Con base en que los departamentos de operaciones y desarrollo habían estado isolados.
El equipo de operaciones es responsable por gestionar las modificaciones del software una vez está en producción, mientras que el development team es responsable del desarrollo continuo de nuevas características para cumplir con los requisitos comerciales. Cada departamento tiene sus propios procesos, herramientas y conocimientos.
La relación entre ellos antes de DevOps generalmente era un sistema de “pases”: los equipos de desarrollo exigen el despliegue de nuevas versiones de software, y el personal de operaciones los gestiona manualmente con los “pases”. Había entonces una lucha continua porque los desarrolladores continuamente están liberando nuevas versiones para producción, pero los operadores las bloquean con el fin de mantener la estabilidad del software. Esto resultaba en retardos entre actualizaciones de código, el despliegue e inconvenientes en la solución de problemas, pues, cada departamento no hacía más que culpar al otro por los fallos.
Dicha relación entre Dev (desarrolladores) y Ops (operadores) conlleva una pérdida de tiempo y una afectación severa los procesos continuos de desarrollo. En este contexto, Devops nació cuando los desarrolladores y operadores comenzaron a colaborar dentro de las empresas para superar esta brecha, volviéndose su base más esencial, la cultura de colaboración. Además de aplicar las prácticas continuas, la iniciativa DevOps también se ha centrado en el uso de la supervisión automática en tiempo de ejecución para mejorar las propiedades runtime del software, como el rendimiento, la escalabilidad, la disponibilidad y la resistencia.
La estrategia Devops se puede descomponer en 4 fundamentos:
- Procesos: los lanzamientos frecuentes y confiables se logran con un proceso de entrega continua que conduce a la calidad del producto, y la satisfacción del cliente debido al corto ciclo de retroalimentación que proporciona. El objetivo de los procesos es lograr resultados comerciales, como reducir el riesgo, costos, y cumplir con las regulaciones.
- Personas: como se mencionó, la idea DevOps es la de reunir al personal de desarrollo y operaciones a través de una cultura de colaboración.
- Entregas continuas: la estrategia principal para lograr un proceso de entrega frecuente y confiable es implementar las técnicas que ya se han mostrado en esta revisión, en especial, la automatización completa del deployment pipeline.
- Runtime: este es el concepto nuevo, no es suficiente con nuevas versiones constantemente si no es estable y confiable. Entonces, el concepto runtime tan necesario en devops se refiere al comportamiento deseado ya en tiempo de ejecución, como buen desempeño, escalabilidad, entre otros, para esto se puede hacer uso por ejemplo, de monitorización y servicios confiables en la nube, lo necesario para mantener la fiabilidad del software y amenizar el rol de los operadores
Ahora con el concepto de DevOps podemos ver el alcance de cada práctica en la figura 2.
Herramientas Populares para desarrollo continuo
El Deployment Pipeline es un concepto que se refiere al proceso automatizado de llevar el software por todo el ciclo de desarrollo, desde el código en el repositorio hasta las manos de los usuarios finales en un entorno de producción. El éxito al usar las prácticas continuas depende mucho del deployment pipeline, una elección apropiada de herramientas para su implementación puede mitigar los diferentes desafíos que pueden surgir al acoger prácticas como CI, CDE, CE y DevOps. Se puede abordar una revisión al ciclo de desarrollo y los elementos que se han estado incorporando para lograr la adopción de las prácticas continuas. Para lo anterior se analizó qué herramientas están siendo utilizadas para dicho propósito. Las mencionadas son de carácter tanto comercial como proyectos open-source, y son usadas para aplicación de las prácticas por separado, reforzamiento y diseño del deployment pipeline completo (Shahin, Babar y Zhu, 2017 : Milojicic et al., 2019 : Doerrfeld, MacVittie y Ohlhorst, 2019). Podemos entonces apreciarlas en la figura 3, se encuentran organizadas en 7 escenarios para una mejor clasificación.
Desafíos al Adoptar las Prácticas de desarrollo continuo
La investigación de Laukkanen, Itkonen, y Lassenius (2017) se enfocó en reconocer los problemas y causas de aplicar las prácticas de desarrollo continuo. Es de notar que en esta no hay una distinción entre CDE y CD, y CI se asume como un prerrequisito para CDE. Ellos clasificaron los problemas detectados en grupos y se muestran a continuación de manera descendente según la cantidad de casos reportados:
- Testing problems: este grupo es el que más problemas reportó, empezando con ambigüedad en los resultados que no comunican mucho a los desarrolladores al no haber claridad de que rompió el build, adicional se informa que estas pruebas a veces fallan al azar, entre algunas se detectó que se requiere demasiado tiempo para su ejecución. También hubo reportes con pruebas específicas, como pruebas de hardware, multiplataforma y las de IU, todas estas requieren aplicaciones concretas haciendo que las pruebas generales sean más complejas y se requiera más esfuerzo para configurar y administrar las pruebas automatizadas en el desarrollo continuo.
- Integration problems: los problemas presentados tienen que ver con grandes commits que contienen una gran cantidad de cambios. Tambien al hacer merge se revelan conflictos entre cambios, esto a su vez causa que la aprobación de integración sea lenta y se den parálisis de trabajo; por esperar la finalización de tareas u otras integraciones, generando una cola que bloquea o impide la finalización del trabajo. Igualmente se observó que las ramas de larga duración se tornan problemáticas porque conducen fácilmente a conflictos de fusión, y el desarrollo de código en múltiples ramas ralentiza la frecuencia de integración.
- Se reportó que regularmente el build se rompe a menudo o dura así durante mucho tiempo, esto necesita un esfuerzo significativo para arreglarse y si dicha compilación no se soluciona inmediatamente, no se podrán detectar otros problemas y estos se pueden extender hacia otras estaciones de trabajo. Igualmente esto conlleva a que el flujo de desarrollo se quiebre y se disminuya la productividad.
- System design problems: para empezar se reportan sobre de la modularización del sistema porque consta de múltiples módulos o servicios, lo que hace que el build sea complejo. La arquitectura inadecuada presentó efectos negativos como retrasos en el desarrollo, los testeos y el proceso de despliegue, limitando la entrega continua. Al darse el proceso continuo e ir liberando algunas funcionalidades, se presentaron problemas con dependencias internas entre partes del sistema de software, lo que requirió cambios en el propio software, lo cual causó a su vez requerir cambios en el esquema de la base de datos.
- Human and organizational problems: estos no están relacionados con actividades de desarrollo específicas, pero son problemas que se relacionan con el comportamiento reacio de los participantes ante la adopción de las prácticas continuas. Para empezar está la falta de disciplina y compromiso en garantizar suficientes pruebas automatizadas, solucionar problemas encontrados durante la integración inmediatamente, y probar los cambios de manera local antes de enviarlos. También está la falta de motivación que se da por el esfuerzo adicional que se requiere para la adopción de las prácticas continuas. Otro problema casi inevitable es la falta de experiencia en dichas prácticas, causando poca comprensión de las técnicas por parte del personal e incluso el retorno a “viejos” hábitos por la incomodidad o la presión, porque el software debe estar siempre en un estado liberable. Entre otros problemas que se listan están el cambio de roles para adaptarse a la colaboración y nueva forma de coordinar al equipo.
- Resource problems: estos son ligados a los recursos disponibles para la adopción de las prácticas. El primero es el esfuerzo que se necesita para configurar el proceso de entregas continuas y, si el sistema no es robusto, se requiere esfuerzo constante para repararlo. Hay más tareas que requieren esfuerzo como el monitoreo, mantenimiento del sistema CI, reparos y la adaptacion propia a las tecnicas. También se reporta sobre los recursos de hardware insuficientes, que son necesarios para un entorno de construcción y prueba continua en especial al hacer pruebas exhaustivas y requerir tolerancia a fallos del hardware. Por último están las latencias de red que dificultan la integración continua.
- Build design problems: en este apartado los problemas reportados son de construcción compleja; el proceso o las secuencias de comandos de compilación son complicados o complejos, y construcción inflexible; el build system no puede modificarse fácilmente.
Conclusión
La revisión realizada nos da a conocer que el desarrollo se ha estado acelerando cada vez más con el fin de responder a un mercado exigente. Las fuentes consultadas en su mayoría, mostraban múltiples desafíos que requiere la concreta adopción de prácticas continuas, pero mostrando a su vez, que los beneficios de su implementación hacen valer la pena el esfuerzo de incursionar en el desarrollo continuo.
Se pudo observar que las disciplinas CI, CDE y CD pueden potenciar la productividad de un equipo de desarrollo, pero hace falta algo más, mantener el producto estable una vez está en producción, algo en lo cual DevOps entra a reforzar con su cultura de la colaboración. Para terminar, se notó que el ritmo con el que estas prácticas cambian no es tan acelerado, siendo DevOps de las últimas tendencias, pero las herramientas y servicios para su aplicación evolucionan constantemente y con el tiempo surgen nuevas cada vez más adecuadas a las necesidades.