martes, agosto 09, 2011

Sobre las desventajas de las ramas de desarrollo

martes, agosto 09, 2011 por Martín

Hace unos días, gracias a @alexcuesta llegué a un gran video (al final del artículo) donde Martin Fowler y Mike Mason analizan los pros y los contras de lo que se conoce como Feature Branching. Bueno, en realidad los contras, porque en lo que exponen el 90% son contras y el 10% son justificaciones.

Feature Branching (artículo del 2009 muy completo del propio Fowler en el que se basa la charla) es una técnica de toda la vida, pero que con el auge de los sistemas de gestión de versiones distribuidos como git ha ido también ganando en popularidad, que consiste en el desarrollo de funcionalidades en ramas paralelas a la rama principal, para de este modo no afectar al desarrollo normal.

El feature branching se suele utilizar para el desarrollo de prototipos o desarrollo de nuevas funcionalidades que requieren bastante refactorización. Otra variante interesante es la que te ofrece Github con sus "forks" (algo propio de Github), que sería cuando un desarrollador hace un branch del código de un proyecto para añadirle nuevas funcionalidades, quitándose así de encima el engorro de tener que ser añadido al repositorio original, o poder trabajar sobre el código sin molestar a los desarrolladores principales, o simplemente experimentar un poco. Sea cual sea el objetivo, una vez implementadas las funcionalidades del branch, se realiza una integración (merge) con la rama principal. Martin Fowler lo dibuja muy claramente en su artículo:



Pero voy a los problemas. El desarrollo en ramas es muy cómodo, para trabajar como cowboys. Nadie te molesta. Tienes toda la rama para ti. Haces lo que quieres, refactorizas como quieres. Todo es color de rosa. Menos cuando toca integrar. Con el desarrollo en ramas, especialmente si hay otro equipo trabajando en más ramas o en la raíz del código, es muy habital que se produzcan unos procesos de integración de código bastante dolorosos. Cuanto más lejana esté la rama del desarrollo principal, más doloroso será el proceso de integración. Asimismo, cuanto más código nuevo tenga la rama, más doloroso será el proceso de integración. Esto, creo yo que es algo bastante conocido. ¿Quién no tiene alguna historia sobre este tipo de integraciones? Y es que no sólo hay que integrar el código. Asumiremos que el desarrollador habrá además hecho tests, que tendrá que integrar. Bueno, tests y demás recursos, como cambios en los esquemas de bases de datos, recursos en el servidor web, etc. etc. En definitiva, y recurriendo de nuevo a las imágenes del artículo de Fowler, se produce una "big merge":



Un caso especialmente peculiar es cuando hay varios cowboys en sus ramas, con sus desarrollos particulares, fantásticos, con sus estilos particulares, y ambos quieren integrar en la raíz del código. Llegamos a esa situación tan particular de: "gana aquel que hace commit primero" :)

La verdad, estoy totalmente con lo que comentan en el video de que el desarrollo en ramas es incompatible a la integración continua. Casi me atravería a añadir que incompatible con el desarrollo ágil, al ser la integración continua un proceso fundamental dentro de un proceso que se quiera considerar ágil. Efectivamente, la integración continua se basa en la continua generación de código dentro de la rama principal de desarrollo que forma nuestro producto de una manera diaria. Es decir que en cualquier instante de tiempo podemos lanzar un producto completamente funcional ya que todo nuestro desarrollo se encuentra constantemente actualizado.

La base de un sistema de integración continua es sin ninguna duda el disponer de un amplio repertorio de tests, ya sean hechos antes (TDD) o después del código y ya sean unitarios, de integración o funcionales.

Es fácil ver que el desarrollo en ramas es totalmente contrario a la integración continua. El código no está disponible hasta días, semanas, o hasta meses después, y no tiene garantizado el paso de los tests que haya en la rama principal (aunque haya tests en la rama, los de la raíz habrán evolucionado, y también habrá nuevos tests, así que tendrán que ser integrados. Como mucho la rama tendrá la garantía de que se pasan los tests que había en el momento de crear la rama).

Ya para terminar, Martin Fowler y Mike Mason recomiendan en el video dos alternativas al desarrollo en ramas. Una es FeatureToggles, que se podría "traducir" al castellano como "relés de funcionalidades", es decir tener algunas condiciones en nuestro producto que habiliten o deshabiliten una funcionalidad concreta. De este modo las funcionalidades experimentales se encuentran en la rama principal del código pero deshabilitadas, y se habilitan cuando sea necesario probarlas o cuando pasen a un estado estable. La otra alternativa es BranchByAbstraction que se basa en crear capas de abstracción o fachadas que abstraen las funcionalidades. De modo que el producto principal siempre utilizará la fachada y los desarrolladores pueden habilitar la implementación estable o la experimental de la misma mediante flags o configuración del sistema.

Y finalmente el video de marras:






comments

0 Respuestas a "Sobre las desventajas de las ramas de desarrollo"