Durante el último año, Driftrock ha recorrido un camino bastante habitual —quizá ya lo hayas oído antes—: hemos pasado de las implementaciones manuales y una cierta apatía a la hora de lanzar software a implementaciones automatizadas y repetibles, centrándonos en aportar valor.
En lugar de aburriros con otra entrada más sobre las ventajas de la entrega continua —aunque me gustaría hacerlo—, intentaré centrarme en cómo logramos este cambio. Inspirándome en el libro *More Fearless Change*, de Mary Lynn Manns y Linda Rising, haré todo lo posible por recordar los pasos que dimos y, más concretamente, los patrones que seguimos utilizando para intentar cambiar los comportamientos del equipo.
Retrocediendo en el tiempo
Para empezar, un poco de contexto: allá por junio de 2016, cualquier cambio en nuestras aplicaciones acababa llegando a producción tras un largo y tortuoso proceso. Apenas sabíamos si un cambio se había implementado o no; existía un modelo de ramificación muy extendido —y frustrante— que aumentaba drásticamente la carga cognitiva, y las implementaciones se activaban manualmente desde el ordenador de un desarrollador a través de la CLI de Heroku.
Un nuevo cambio de desarrollo a producción se veía más o menos así:

Verde: paso automatizado.
Naranja: paso manual inevitable o un paso manual que (todavía) no tenemos previsto modificar.
Rojo: paso manual evitable.
Además, ese proceso de implementación presentaba una serie de inconsistencias que variaban según la aplicación. Algunas no contaban con un entorno de prueba; las que sí lo tenían, a veces se implementaban automáticamente en dicho entorno y otras no; y no todas las aplicaciones contaban con pruebas automatizadas que se ejecutaran en la rama principal o en cualquier otra rama. En resumen, era innecesariamente complejo, tremendamente inconsistente y con poca o ninguna automatización. Por lo tanto, no es de extrañar que el equipo mostrara una falta de interés a la hora de implementar software.
Todo lo anterior hacía que las implementaciones fueran irregulares y arriesgadas. En la mayoría de los casos, se lanzaban al entorno de producción grandes lotes de cambios, lo que, como era de esperar, aumentaba la probabilidad de que algo saliera mal y, en ocasiones, impedía revertir los cambios de forma segura.
Pequeños pasos
Intentaré explicar los pasos que seguimos y los patrones pertinentes que utilizamos para mejorar el escenario descrito anteriormente. Al final de esta página hay una referencia a los patrones mencionados a lo largo de estos pasos. Además, aquí puedes encontrar todos los patrones convenientemente enumerados y descritos.
Paso 1: Involucrar a todo el mundo
De forma poco convencional, todo empezó mejorando nuestras retrospectivas. El equipo necesitaba una plataforma para debatir los problemas y sugerir mejoras (Involucrar a todos). Aunque teníamos una charla semanal llamada «retrospectiva», esta se parecía muy poco a las retrospectivas que había visto en otras empresas. En un principio, esta reunión se parecía mucho más a una reunión semanal de actualización del estado de las tareas; se centraba en las tareas diarias y su progreso, en lugar de analizar cómo podíamos mejorar nuestra forma de trabajar. Sugerir y luego demostrar un enfoque más estructurado para las retrospectivas (facilitando las primeras) tuvo un impacto significativo en el equipo más allá de la Entrega Continua, pero uno de los primeros puntos de debate giró en torno a cómo implementamos nuestro software (Sembrar las semillas).
Paso 2: ¡Manos a la obra!
Dado que el equipo tenía algunas dudas sobre cómo les podría beneficiar el paso a la entrega continua, el siguiente paso fue sencillo: mostrarles un ejemplo («Just Do It»). Creé una sencilla aplicación de API HTTP con un único punto final que devolvía «200 OK» y configuré un proceso de implementación en Snap CI. Intenté imitar cómo podríamos tratar nuestras aplicaciones habituales y solo abordé los problemas más inmediatos (elige tus batallas): las implementaciones manuales y la gestión de múltiples ramas en la implementación. Esto último también reducía la distancia entre el desarrollo local y la producción. Demostrando que nuestro proceso de implementación podía empezar a evolucionar hacia esto:

Como era de esperar (al igual que con el software operativo), esto se convirtió en un excelente punto de referencia para mostrar y explicar el valor del desarrollo continuo (CD) y cómo se compara con lo que veníamos haciendo.
Paso 3: Prueba de funcionamiento
Una vez sentadas las bases, con un ejemplo práctico y los problemas habituales a la hora de lanzar software de calidad (destacando únicamente la gravedad —una llamada de atención—), la aceptación por parte del resto del equipo fue aumentando progresivamente. El siguiente paso fue comprometer al equipo a migrar una o dos aplicaciones reales al nuevo sistema (prueba piloto). Elegimos dos aplicaciones problemáticas para validar nuestras hipótesis lo antes posible, creamos procesos de implementación para ellas, logramos implementarlas con éxito y dejamos que el cambio se asentara. En ese momento, afortunadamente conté con algo de ayuda (pedir ayuda), lo que aceleró mucho el progreso y facilitó la gestión de posibles reacciones negativas.
Paso 4: Relaciones públicas continuadas
Hay un patrón mencionado en el libro que me llamó especialmente la atención a lo largo de todo este proceso: las relaciones públicas persistentes. Al reflexionar sobre ello, me di cuenta de que aparecía sutilmente en varios momentos, a veces de forma intencionada, pero a menudo sin querer. A continuación, detallo en qué partes se menciona:
- Modificamos nuestra reunión diaria habitual para que se centrara primero en lo que se había implementado en producción, luego en el entorno de prueba y, por último, en el desarrollo activo —lo que se conoce habitualmente como «Walk the Board». Aunque de forma indirecta, esto sirve para recordar periódicamente al equipo que debe centrarse ante todo en lanzar el software y en cómo podemos hacer avanzar las tareas hacia la fase de producción.
- En una reunión semanal de la empresa, hicimos una breve demostración de cómo habíamos cambiado nuestro enfoque a la hora de implementar software. Por cierto, esto surgió por casualidad, pero era una oportunidad que merecía la pena aprovechar (Seis sentidos del éxito).
- Empezamos a recopilar y comunicar datos sobre el número de implementaciones en producción.
- Hemos introducido algunos mecanismos de retroalimentación para facilitar el flujo de información en torno a las implementaciones:
- Notificaciones de Slack: envío de información sobre compilaciones fallidas o implementaciones correctas. Esto significaba que los desarrolladores no tenían que ir a buscar el estado de sus cambios, sino que este les llegaba directamente.
- Notas de la versión: empezamos a anunciar internamente los cambios destinados a los clientes a medida que se iban implementando. Esto contribuyó a generar interés y debate en torno a las nuevas funciones entre el personal de toda la empresa.
- Supervisión: es algo que aún no hemos perfeccionado del todo, pero seguimos probando diferentes métodos de supervisión y buscando mejores formas de recabar información de nuestros sistemas de producción.
Entonces, ¿en qué punto estamos ahora?
Actualmente realizamos implementaciones en producción unas 15 veces a la semana, un buen ritmo sostenible para un equipo de nuestro tamaño. Al final, trasladamos aproximadamente 30 proyectos a Snap CI. Creamos flujos de trabajo de entrega continua (CD) para una gran variedad de aplicaciones: gemas de Ruby, paquetes de Elixir, sitios web estáticos alojados en AWS, aplicaciones web en Heroku y otras alojadas en Kubernetes. Todos los miembros del equipo se responsabilizan de garantizar que los cambios en los que trabajan se implementen en producción y colaboran estrechamente con el resto del equipo para probar las funcionalidades pertinentes. Cada vez dependemos más de las pruebas automatizadas, los conmutadores de funciones y la compatibilidad con versiones anteriores, temas que han ocupado un lugar destacado en nuestras retrospectivas.
Por cierto, Snap CI no estuvo realmente a la altura de las expectativas, pero incluso eso tuvo algunos aspectos positivos. Tras sufrir varios problemas, empezamos a apostar por el uso de Docker para la integración continua (CI), con el fin de aislar y tomar el control del entorno de compilación. Esto tuvo muchas repercusiones, como el uso de Docker en el desarrollo y la transición hacia Kubernetes. También redujo nuestra dependencia de la herramienta de CI/CD elegida, lo que pronto cobró gran importancia cuando Snap CI anunció que iba a dejar de funcionar. Afortunadamente, ahora estamos en una posición mucho mejor para entender lo que necesitamos, así que estamos en proceso de migrar a Buildkite(¡otro artículo para otra ocasión!).
Esperamos que esto os dé una idea de cómo seguimos avanzando hacia la entrega continua y de los patrones que nos han ayudado. Nuestro enfoque sigue evolucionando a medida que aprendemos y somos conscientes de que aún nos queda camino por recorrer. Resumir todo ese esfuerzo en cuatro pasos es, sin duda, una simplificación excesiva; llegar hasta donde estamos ahora nos llevó muchos meses, incluso a nuestro pequeño equipo. Este viaje nos ha recordado que un cambio como este no se produce de la noche a la mañana y que requiere muchos pequeños pasos, a menudo insignificantes, en la dirección correcta.
Otros recursos útiles
Linda Rising: Mitos y patrones del cambio organizativo
Entrega continua - Jez Humble y Dave Farley
Entrega continua: de la pobreza a la riqueza - Hibri Marzook
Desarrollo basado en el tronco
Referencia de patrones de cambio
Parafraseando ligeramente el libro, aquí tienes una selección de los patrones que he mencionado anteriormente:
Pasos de bebé: da un pequeño paso cada vez hacia tu objetivo.
Involucra a todo el mundo: todos deberían tener la oportunidad de aportar su granito de arena.
Siembra las semillas: aprovecha cualquier oportunidad para despertar el interés por una idea.
Hazlo sin más: no esperes al momento perfecto; da ese primer paso de bebé y empieza a aprender.
Elige tus batallas: centra tus esfuerzos en los asuntos más urgentes.
Prueba piloto: cuando haya reticencia a comprometerse con una idea, sugiere un experimento durante un breve periodo de tiempo.
Llamada de atención: señala los problemas que hacen necesario el cambio.
Pide ayuda: busca personas y recursos que te ayuden en tus esfuerzos y fomenta la participación.
Relaciones públicas persistentes: mantén la nueva idea a la vista de todos y promociónala de forma constante y variada.
El aroma del éxito: cuando tus esfuerzos produzcan un resultado positivo visible, aprovecha ese momento para enseñar.