Control de versiones en Microsoft Dynamics AX 2012 mediante ramas de Team Foundation Server (ALM-VII)

En capítulos anteriores hablamos sobre cómo instalar y configurar Team Foundation Server, así como las posibilidades que ofrece para gestionar tareas y administrar el código fuente desde nuestra instancia de Microsoft Dynamics AX 2012. Comentamos las funciones básicas ,aunque imprescindibles, para proteger y desproteger el código en el servidor y las ventajas que ello suponía en cuanto a almacenar todo el histórico de cambios de los objetos, como por ejemplo: revisar el historial de cambios de un objeto, volver a una versión anterior, descartar cambios sin confirmar, etc.

Sin embargo hay ciertos problemas que una gestión básica del código fuente no es capaz de solucionar. Por ejemplo, en una instalación normal de nuestro ERP, a la vez que damos el soporte diario y realizamos pequeñas modificaciones para solucionar problemas, estamos llevando a cabo desarrollos de mayor o menor impacto. Estos desarrollos paralelos necesitan ser integrados en el código de producción de alguna forma, pero si usamos el mismo servidor para desarrollar y para hacer el mantenimiento, tendremos que llegar a un punto en el que todos los desarrollos estén totalmente terminados para pasar a producción de forma limpia y segura.

De la misma forma, si nuestra empresa desarrolla un producto final, es necesario avanzar el desarrollo de las siguientes versiones mientras damos soporte a las versiones publicadas en el pasado, incluso para diferentes versiones de AX. ¿Cómo estar seguro que un hotfix urgente desarrollado para un cliente llega a todas las versiones de nuestro producto que la necesitan, de forma limpia y estable?

Visual Studio loves Dynamics AX 2012

Por supuesto hace falta un buen método de trabajo para que todo esto pueda realizarse de forma ordenada y sin errores, pero también hace falta la ayuda de alguna herramienta y para eso tenemos las ramas (Branches) disponibles en casi todos los sistemas de control de versiones del mercado, y por supuesto en nuestro Team Foundation Server.

Estrategias de branching

Existen infinidad de estrategias para definir las ramas que necesitamos en nuestros equipos, y ello va a depender de la cantidad de equipos que tengamos, la cantidad de productos, de versiones, etc. NO HAY una estrategia de ramas estándar o válida para todos y es algo que se debe pensar con cuidado ya que la estrategia elegida nos va a suponer ventajas e inconvenientes. Lo más recomendable es empezar por la lectura de la guía Version Control Guide escrita por el grupo Visual Studio ALM Rangers donde explican la mayoría de opciones con sus pros y sus contras.

Siguiendo las recomendaciones de la Version Control Guide citada anteriormente, lo ideal es empezar por una estrategia muy sencilla y crear nuevas ramas sólo cuando son necesarias. La estrategia más sencilla es por supuesto no usar ninguna rama, o utilizar solo una (en la guía llamada estrategia Main Only), que es más o menos lo mismo.

Sin embargo lo ideal es utilizar al menos dos ramas para sacarles algo de rendimiento, de forma que que pronto pasaremos de la estrategia Main Only a algo más completo como Code Promotion o Development Isolation, y con algo más de madurez llegaremos a alguna estrategia que será una adaptación de una o varias de las recomendadas por los Rangers.

Aquí tenemos el esquema de algunas estrategias básicas para tomar como punto de partida y para aportar ideas (click para ampliar):

Hay que insistir en que crear nuevas ramas va a aumentar la cantidad de trabajo necesario para mantenerlas, por lo que conviene siempre empezar desde lo más sencillo a lo más complicado, y no crear nuevas ramas si no sabemos que de forma clara nos van a aportar beneficios.

Branching is "easy"

Crear nuevas ramas desde Visual Studio

Crear ramas en TFS es realmente sencillo. Las ramas son directorios dentro de nuestro control de código fuente, por lo que una vez creados estos directorios podemos hacer click derecho sobre ellos desde el Source Control Explorer de Visual Studio > Branching and Merging > Convert to Branch. Todo lo que haya dentro de esta carpeta desde ese momento pasará a formar parte de la rama, y se propagará al resto de ramas cuando hagamos la integración.

Para crear otras ramas dependientes de ésta (por ejemplo, desde Main necesitamos crear Test para una estrategia Code Promotion) hacemos click derecho sobre la rama existente > Branching and Merging > Branch, para crear una nueva rama dependiente de la original.

De esta forma podemos crear todas las ramas que queramos, dependiendo de la estructura que necesitemos. Haciendo click derecho sobre una rama > Branching and Merging > View Hierarchy podemos analizar las relaciones entre ramas y ajustar sus propiedades hasta que tengamos nuestra estructura terminada.

Branch Hierarchy

Conectar a ramas desde Dynamics AX 2012

Trabajar con ramas desde Dynamics AX es totalmente transparente. A pesar del título de este artículo, podemos asegurar que AX no trabaja con ramas en absoluto, para nuestro editor de X++ cada rama es una aplicación diferente.

Es importante tener esto en cuenta al conectar a diferentes ramas desde Dynamics AX, y sobre todo al cambiar de una rama a otra, ya que será necesaria una sincronización completa desde TFS que puede llevar algún tiempo y provocar conflictos en la base de datos si las ramas son muy diferentes.

Así mismo, si utilizamos diferentes ramas es conveniente tenerlo en cuenta a la hora de definir la estructura de directorios de nuestro repositorio local. Es recomendable usar carpetas diferentes para cada rama para facilitar la sincronización si en algún momento queremos cambiar. De no hacerlo así, para cambiar de rama tendremos que borrar totalmente la carpeta del repositorio para que se vuelva a sincronizar desde cero.

Dicho esto, para conectar a una rama desde Dynamics AX sólo debemos indicarla en la configuración de Team Foundation Server (en Version Control > Version Control Parameters), como ya vimos en un capítulo anterior de esta serie.

Una vez configurado nuestro entorno, los check-in de código se realizarán sobre la rama indicada, y es responsabilidad de Visual Studio promover esos cambios al resto de ramas, según la estrategia que hayamos elegido.

El mítico MERGE

Ya hemos visto como es fácil crear ramas desde Visual Studio y conectarse a ellas desde Dynamics AX ¿Y ahora qué? Hasta aquí no hemos ganado nada comparado con trabajar con una sola rama, o con ninguna. Las ventajas de esta forma de trabajar empiezan a notarse al promover código entre ramas utilizando las herramientas de Visual Studio y en concreto la función MERGE.

Todos los sistemas de gestión de código disponen de esta función, que ha dado lugar a términos como “mergear” y demás atrocidades contra nuestro idioma que toleramos de forma natural (“mergéame el branch“)… Lo que hace esta función, como sea que la llamemos, es promover el código de una rama e integrarlo con otra, solventando los conflictos que puedan causar cambios simultáneos en varias ramas de manera automática cuando es posible, y presentando utilidades para solucionar estos conflictos de manera manual cuando no lo es.

Algunos merges naturales son de Desarrollo a Main o de Main a Test o a Release, dependiendo de nuestra estrategia. También se puede hacer el merge en sentido inverso, por ejemplo, para refrescar nuestras ramas de desarrollo (si tenemos varias) desde Main , o parar incorporar en Main un hotfix urgente desarrollado en una rama inferior para parches. Este merge en sentido inverso, aunque internamente es la misma función, es referido en algunos sitios como operación Refresh.

La función merge integrara los cambios en el código existente de forma automática la mayoría de las veces, pero encontrará cambios que entran en conflicto con la versión del servidor que ha integrado previamente otro programador que será necesario resolver manualmente. Para ellos nos ofrece una herramienta de comparación muy similar a la herramienta Comparador de Dynamics AX, donde podremos elegir utilizar nuestra versión o la del servidor, además de otras funciones que nos permiten comparar ambas versiones con sus versiones anteriores y resolver varios conflictos a la vez. Su funcionamiento es muy intuitivo y por supuesto está soportado por todas las versiones de Visual Studio (imágenes de 2010 y 2013) tanto en TFS on-premise como en la versión Visual Studio Online en la nube.

Se encontrarán menos conflictos cuanto más a menudo se integren las ramas, lo que beneficia sistemas de trabajo incremental con iteraciones cortas y tareas pequeñas como las metodologías ágiles.

Ramas y trazabilidad – Siguiendo la pista a los cambios

El uso de ramas y de procesos merge para integrar cambios entre ellas nos permite un gran nivel de trazabilidad de los cambios. Por supuesto esta trazabilidad dependerá de nuestra manera de trabajar, pero si implementamos en nuestros equipos algunas normas sencillas como por ejemplo sólo hacer check-in de cambios referentes a un solo work item a la vez, y siempre relacionar los check-in con un elemento de trabajo, podremos mover entre entornos mediante merges sólo los check-in pertenecientes a determinados elementos de trabajo, permitiendo en la práctica pasar a Test o a Producción sólo los requerimientos que estén terminados, mientras en los entornos de desarrollos permanecen desarrollos sin terminar.

Aparte de eso, tendremos en todo momento información de cuándo cada cambio se movió entre entornos (entre ramas), cuándo un determinado cambio se compiló por primera vez (lo veremos en el siguiente capítulo de esta serie), por qué se realizó determinado cambio y en qué entornos se ha copiado. Para todo esto utilizamos la relación entre work items y change sets, y también el historial de cambios. En la siguiente imagen vemos un cambio que ya se ha pasado a Test, pero no a Producción:

Changeset tracking (VS 2013)

¿No es genial? 🙂

En el próximo capítulo cerraremos el círculo de esta larga serie de artículos hablando sobre procesos build automáticos, y en los siguientes comentaremos el ciclo completo y algunos trucos. ¡No te los pierdas!