Tinselcity

Lo que sigue es la descripción de algo que está “en progreso”, o quizá mejor dicho “en continua evolución”. Debido a esto puede dar la impresión de que el sistema no es sostenible a largo plazo. No lo es. Evidentemente no lo es. Es ridículo pensar por un solo momento que es un proceso sostenible.

Sigh Flow

Trabajar en equipo requiere coordinación. Desarrollar software en equipo suele requerir el uso de alguna herramienta de gestión del código y control de versiones para manejar esa coordinación con éxito. Pero este tipo de herramientas -SCSS, CVS, SVN, Git, Hg, Darcs…- tan solo ayudan a gestionar los cambios. No definen de forma única el flujo de trabajo o el proceso a seguir a la hora de usarlas. Y hacen bien en no hacerlo, claro, porque en primer lugar no es ese su objetivo y en segundo lugar así pueden adaptarse a las muy variadas circunstancias de los proyectos y equipos que las usan. Vamos que no es bueno pensar que un único flujo de trabajo es el mejor para cualquier equipo y proyecto. Cada uno deberá buscar un flujo que encaje con su forma de operar y de organizarse.

Pero como ocurre con tantas y tantas cosas de las que hacen los programadores, a muchos les gusta pretender que su forma de hacer las cosas es “la mejor” siempre1). En consecuencia han surgido diferentes flujos que se han hecho más o menos populares y que mucha gente ha adoptado sin pensar más que ese clásico entre programadores de “pues si estos que son tan chachi-guays lo hacen así, seguro que si yo lo hago así seré también chachi-guay”. Flujos como Git Flow, Github Flow, Trunk-Based Development, One Flow… No sé, hay unos cuantos. En general son más o menos complejos según tratan de gestionar de formas más independientes o más estrechas las colaboraciones de más o menos grupos diferentes dentro de un equipo. Dependiendo del tamaño del proyecto/equipo, pueden involucrar -además de la rama principal, “trunk” o “master”- otras con diferentes duraciones en el tiempo.

No voy a hablar aquí de ninguno de estos modelos de proceso. Mucho hay ya escrito sobre ellos. Descripciones, puntos fuertes y débiles, comparaciones, ventajas, desventajas, problemas, arreglos… solo hay que levantar un par de piedras en cualquier buscador y salen a puñados artículos sobre el asunto.

Lo que voy a describir a continuación es un flujo particular al que he decidido llamar Sigh Flow. Sigh como el lamento que es.

Entorno de uso y descripción básica

Para situarnos un poco es necesario conocer algunos detalles -no muchos- de la organización del proyecto, ya que esto dicta algunas de las acciones realizadas en el proceso.

En general, el proyecto se organiza bajo una variante clásica de la gestión Agile que consiste en que no es ágil en absoluto. Hay 2 entregas/versiones al año. Se dice que se hacen sprints de 3 semanas2). Esto significa que hay más o menos 8 o 9 sprints por entrega.

La aplicación es medianamente grande. Tiene unas 8 secciones diferentes para gestionar diferentes cosas. Hay dos equipos: analistas y programadores. Uno o dos analistas trabajan en cada una de las secciones y son los “dueños” de esa sección. Teóricamente los desarrolladores podrían rotar por diferentes secciones pero en la práctica la mayoría de los desarrolladores trabajan siempre en la misma sección. En algunos casos esto lleva al extremo de que algunos analistas vean a cierto desarrollador como suyo. Esto es un poco distinto para 3 desarrolladores calificados “de front”, que pueden acabar haciendo cualquier cosa en cualquier sección, menos tocar PL/SQL3).

Las tareas e incidencias se gestionan con JIRA. De hecho, no se hace demasiada distinción entre tareas e incidencias salvo en algunos detalles de prioridad. En teoría, la diferencia es que las tareas se planifican dentro de un sprint y las incidencias llegan y se hacen aunque no estén planificadas. La realidad es que las tareas pueden moverse de un sprint a otro, adelante y atrás, según la temperatura de la sala y la situación de los planetas.

El flujo de gestión del código, como idea básica general, está centrado en 2 ramas: trunk y desa(rollo). La rama principal, trunk, representa la versión actualmente en producción. La rama desa representa la versión en desarrollo para la próxima versión.

Flujo de trabajo Sigh Flow

Al comenzar de una situación “limpia”, existe la rama principal trunk y la de desarrollo desa. Al hacer la entrega de la versión nueva, la rama trunk se archiva, la rama desa pasa a llamarse trunk y se saca de ella una nueva rama llamada desa.

Esto en realidad no se hace cuando se entrega una versión sino que se hace unos dos meses antes. Más o menos ocurre así: Cuando quedan dos meses para entregar, un día se bloquea por completo el repositorio. Todos los desarrolladores, que estaban trabajando sobre desa tienen la opción de hacer commit de todo lo que tengan a medio construir o de guardarse los cambios en su ordenador en una carpeta de alguna forma y cruzar los dedos. Dejan entonces de trabajar durante un día entero porque está todo bloqueado y si acaso hicieran algo ese día, se va a perder porque no lo van a poder subir al repositorio. Así que todos optan por hacer commit a medias y no hacer nada ese día. Se bloquea el repositorio entonces. Dos personas hacen el juego de manos con las ramas moviendo y borrando y creando y renombrando. Al día siguiente, todos los desarrolladores pasan a trabajar en trunk durante los dos meses que quedan hasta la entrega, mientras desa, por ahora, queda en espera.

Durante estos meses, periódicamente se van haciendo actualizaciones de la rama desa con lo que se desarrolla en trunk. Aunque, por ahora, nadie esté trabajando en desa, es por mantenerla actualizada. Cada vez que hay alguna operación sobre las ramas del repositorio, este se bloquea para todos durante una media jornada. Esto ocurre tres o cuatro veces por semana. Según se va acercando la fecha de la entrega, la “oficina de proyecto” va restringiendo cada vez más el acceso al repositorio.

Con la fecha de entrega ya próxima, los desarrolladores en lugar guardar sus cambios en el repositorio cuando ya los tienen terminados, lo que hacen es dejarlos en sus máquinas locales sin hacer commit y esperar a que les abran el acceso para poder guardar. Esto se hace antes de cada despliegue en los entornos de pruebas, unas dos veces por semana, y se hace más o menos así: Karen, de la “oficina de proyecto”, decide quién puede o no puede guardar sus cambios según el analista correspondiente le diga que ha probado el cambio en la máquina de ese desarrollador. Así, cuando los cambios se desplieguen en los entornos de pruebas, en realidad ya están probados. O algo así.

Al llegar la entrega, en teoría los desarrolladores vuelven a pasar a trabajar sobre la rama desa, la nueva rama desa. En la práctica no. Porque la entrega tiene: a. errores, y b. cosas que no se han terminado del todo o que como son “pequeñas cositas”, se decide que se hagan como si fueran arreglos de errores. Entonces durante los dos meses siguientes a la entrega, los desarrolladores primero siguen trabajando sobre trunk y solo poco a poco van pasando a trabajar en desa o combinan trabajos en ambas ramas según el día de la semana o el tono de color del cielo. trunk permanece “cerrado” todo el tiempo ahora, salvo unos minutos antes de cada despliegue. desa a veces se cierra también. A veces intencionadamente, a veces accidentalmente.

Mientras desa sigue recibiendo los cambios de trunk hasta que cansados ya de esta versión, la oficina de proyecto decide un día secreto que ya no se van a hacer más despliegues de trunk. Si algún desarrollador ha estado trabajando los últimos días en alguna tarea que se había decidido que se hacía en trunk y no la ha terminado, pues bueno… básicamente se jode, porque “ah, haberlo terminado”.

Finalmente, todo el mundo pasa a trabajar en desa, la nueva desa que en realidad tiene ya 4 meses y que dentro de dos volverá convertirse en trunk.

Detalles de operación y otros

Mientras todo esto ocurre, unos procesos de backup hacen commit cada hora sobre la rama desa. Son unos pocos ficheros XML de logs del resultado de unas operaciones automáticas, en los que no hay, generalmente, ningún contenido interesante pero contienen la fecha y hora de modo que siempre cambian. Esto aporta al repositorio unos 90.000 commits extra para hacer bulto, aunque en realidad esto no hace mucha falta ya que la confusa gestión del repositorio, junto a diversas costumbres y tradiciones establecidas entre los desarrolladores4) ya hacen que el historial del repositorio sea generalmente inútil y complicado de navegar.

Aunque este es el flujo de trabajo principal, no es estrictamente cierto que solo se utilicen dos ramas. Se intenta que sea así porque los desarrolladores no pueden crear ramas nuevas y entonces crear una implica involucrar a Marcus, el departamento de sistemas, para que cree la rama y además cree un nuevo workspace de Eclipse para esa rama porque los desarrolladores tampoco pueden cambiar de una rama a otra. Pero aún así, a veces se crean ramas. A veces se crea una rama para desarrollar una aplicación diferente, por ejemplo. Otras veces se crea una rama sin decir a nadie para qué es y se les pone a media docena de personas el workspace de esa rama porque en algún futuro quizá se les dirá que trabajen en esa rama.

También puede ocurrir que, a veces, el Arquitecto necesite hacer tareas muy necesarias por necesidad del proyecto y entonces, como el lógico, lo primero que hace es bloquear el repositorio para todos. Así puede hacer esas cosas necesarias sin que nadie interfiera.

1)
O, a veces, incluso “la correcta”
2)
se dice pero no se hacen realmente; no hay un comienzo de sprint más allá de unos mails muy obsesivos que envía uno de los jefes diciendo que termina un sprint y empieza otro
3)
Salvo en algunos casos en que también
4)
Karen, por ejemplo, no es desarrolladora. No, en realidad no lo es. Pero toca mucho en los PL/SQL, y tiene la costumbre de hacer siempre una docena de commits por cada cambio que intenta hacer y todos con el mismo mensaje explicativo que no explica en realidad qué se ha hecho sino que se limita a poner el título de la tarea.