Agile

CI/CD el modelo de ramas Agile

Continuous Integration / Continuous Delivery no va sólo sobre cómo crear pipelines ó automatizar si no es un cambio muy profundo en cómo desarrollar. Vamos a intentar ver qué es y el problema que intenta solventar.

Continuous Integration

Recuerdo cuando estudiaba en la Universidad y tenía que hacer prácticas de programación, simplemente guardando el código en un disquete me bastaba para compartirlo con el profesor o un compañero. Cuando estás en un equipo de desarrollo con varios compañeros, y cada uno de ellos trabaja en diferentes features, incluso en remoto, este modelo no escala. 

Este problema tiene múltiples vertientes:

  • Varias personas trabajando de manera independiente en la misma base de código sin bloquearse.
  • Integrar las partes que se realicen y que todo funcione. Vamos, evitar la famosa frase «en mi ordenador funcionaba»

Pues esto es lo que pretendes arreglar haciendo CI (integración continua). Para ayudar a tener un repositorio común de código y que no lo pierdas todo.  Si pierdes tu disquete, necesitarás un sistema de control de versiones que también te ayudará si hay conflictos al mergear el código a master (dos personas cambian por ejemplo el mismo fichero a la vez). Para integrar las partes se suele necesitar un servidor independiente y que cada vez que alguien suba código al control de versiones este servidor compile todo el producto, pase todos los tests y lance una alarma si fallan (los tests o la build). Un problema en la integración debe ser la prioridad del equipo, no se puede dejar la build rota o que no pasen los tests porque entonces trabajamos sobre algo inestable (bloqueamos a todo el equipo). 

Pero nos falta la parte más importante de CI, hemos hablado de la integración…¿qué pasa con la palabra contínua? Debemos integrar al menos una vez al día nuestro trabajo con el trabajo del resto del equipo en master (la rama principal de nuestro control de versiones). La mayor parte de la gente se queda solo con tener control de versiones y un servidor de CI pero no integra continuamente con lo que pierde el potencial de CI. 

Imaginemos que uno de los desarrolladores borra un fichero porque hace una refactorización y otro ha hecho cambios en ese fichero, ese problema de coordinación se convierte en un conflicto al subir el código. Ese problema empeora cuanto más tiempo llevemos divergiendo ambas copias. Si integramos continuamente esos problemas serán más pequeños, tendremos menos bugs y tardaremos menos tiempo en resolverlos. 

O dicho de otra manera, queremos tener un feedback rápido e independiente de cómo está la salud de nuestro código base en cada cambio que hagamos y responder lo antes posible si es necesario.

Continuous Delivery/Deployment

Hemos hablado de cómo resolver el problema de integrar código pero subir a producción una nueva release de tu aplicación es un proceso diferente. 

Agile se basa en reducir el tamaño de lo que subimos para reducir riesgos e iterar sobre esos pequeños cambios. ¡Si nos estamos equivocando queremos saberlo cuánto antes! Cuando subes a producción cada tres meses, la cantidad de código que acumulas es descomunal y el riesgo de introducir bugs es similar. Si lo haces cada dos semanas, bajas el riesgo y también tamaño de la subida. Así que, el tamaño de lo que subimos es inversamente proporcional a la frecuencia con lo que lo hacemos, entonces a menor tamaño subimos más veces y el lead time (cycle time) será el más pequeño posible. 

¿Cuál es el tamño más pequeño que podamos subir a producción?

Parece que el tamaño de feature sea suficiente, ya que podemos medir y está terminada. 

Para una empresa que suba a producción cada dos semanas, cambiar a subir por feature puede ser un gran paso. Sin embargo, podemos ser aún más granulares.  Para conseguirlo y ser capaces de  subir algo menor a una feature, necesitamos desacoplar dos conceptos:

  • Desplegar a producción
  • Activar una feature

 

Las features están compuestas por commits. No puedes subir un commit si rompe la build o no hace pasar los tests porque podría introducir bugs, cada commit debe testear el cambio que contiene (otra vez feedback rápido). Esto es Continuous Delivery, desarrollar de tal manera que puedas subir a producción después de haber subido cualquier commit. 

La diferencia con continuous deployment es que en continuous deployment cada commit subido significará una nueva release que desplegará a producción automáticamente. En continuous delivery habrá un paso manual realizado por el desarrollador para subir a producción (un botón en un pipeline o un script que al ejecutarse despliegue a producción) pero nuestro branch principal siempre estará listo para ser desplegado.

Entonces estoy subiendo features inacabadas, eso nos plantea el problema de no enseñarlas a los usuarios pero sí a los stakeholders para poder recibir feedback mientras desarrollamos. 

Cómo conseguir que funcione Continuous Delivery

Para que funcione, necesitaremos utilizar técnicas como:

Si hablamos de reducir el tamaño de lo que subes,  entonces el tamaño del commit importa, debemos subir commits pequeños y frecuentemente. Trunk based development es la mejor manera de conseguir hacer CI/CD, es decir, solo tendremos una rama en remoto master. En local los desarrolladores subirán commits pequeños y frecuentemente a master.

Hacer CD en cualquiera de sus formas permite eliminar bloqueos para subir a producción, no necesitaremos esperar a una aprobación para subir. Esa aprobación nos servirá para activar una feature, hacer un experimento u otra cosa, pero no bloqueará al equipo, no provocará subir el WIP. En definitiva, nos hará ir más rápido con más calidad en lo que hacemos.

Al subir tan frecuentemente, si encontramos un bug tras una subida, hacer rollback significará eliminar un commit no una feature entera o varias. En este modelo es importante enterarnos cuando las cosas van mal cuanto antes, con lo que tenemos que mejorar nuestros sistemas de monitorización. Recuerdo tener un monitor gigante para el equipo enfrente de nosotros con tiempos de respuesta y métricas. Si algo se ponía rojo Batman investigaba y en el peor caso eliminaba commits hasta arreglar el problema. Una vez identificados los commits, la gente que los había subido debía arreglar el problema (los commits están en su local). En definitiva, buscamos reducir el MTTR (mean time to restore) básicamente.

Otra gran ventaja es recibir feedback de lo que hemos hecho o estamos haciendo en el entorno más parecido a producción que es producción limitando el impacto a usuarios:

Para hacer continuous deployment debes hacer continuous delivery y para hacer continuous delivery debes hacer continuous integration. 

Para profundizar más en el tema:

 

Deja un comentario