Ciclo de vida del código del proyecto
Desde que el desarrollador escribe el código de una aplicación, hasta que dicha aplicación se despliega en el servidor de explotación el código recorre un camino controlado que permite cubrir las exigencias de la gestión de la configuración y el control de calidad impuestas por MEDEA. Dicho camino es el recogido en el gráfico.
Las principales características de este camino vienen resumidas a continuación:
En el proyecto existen 2 ramas de código activas, el tronco en el que avanza el código y una rama que es la que está destinada a preproducción o a producción.
Si abrimos una nueva rama en producción la rama anterior queda muerta.
Los desarrolladores pueden hacer check-in al tronco y únicamente aquellos autorizados a las ramas.
El tronco se sube automáticamente cada día al proyecto de desarrollo de Jenkins que crea una build y si no hay problemas la despliega automáticamente en el servidor de desarrollo.
Las ramas se suben manualmente al proyecto de preproducción de Jenkins cuando se cree que están listas para desplegarse las versiones beta de la aplicación. El servidor de integración continua despliega automáticamente en el servidor de preproducción generando un Tag que será el futuro despliegue en producción.
Cualquier cambio realizado directamente en una rama debera ser llevado al tronco del proyecto mediante un merge.
1.- Sistemas que intervienen
La creación y despliegue de aplicaciones software en ÁTICA implica la participación de varios sistemas. A continuación veremos cuales son estos sistemas y que papel cumple cada uno de ellos.
1.1.- PC's de los desarrolladores
Cada uno de los desarrolladores que interviene en el proyecto dispondrá de un PC con FundeWeb instalado. Los desarrolladores se incorporarán al proyecto tal y como se indica en la guía técnica ¿Cómo me incorporo a un proyecto existente en un repositorio SVN?.
Por defecto los desarrolladores trabajaran con el tronco del proyecto, salvo que reciban instrucciones de su Jefe de Proyecto para que trabajen en la versión del proyecto que se encuentra en preproducción o en producción. En ese caso trabajarán en la rama correspondiente.
1.2.- Servidor de control de versiones (Subversion)
En ÁTICA disponemos de un servidor Subversion para el control de versiones del código fuente y compilado del proyecto. Dentro de cada proyecto disponemos de diferentes espacios con distintos cometidos.
Código fuente del tronco del proyecto: Donde se encuentra el código del tronco del proyecto. El código del tronco se encontrará, para cada uno de los proyectos en la carpeta /Proyecto. Dentro de esta carpeta hay 2 subcarpetas, una para el código fuente /Fuentes y otra para la documentación /Documentación. En estas carpetas es dónde se mantiene y va avanzando el código y la documentación del proyecto.
Versión del código para desarrollo o preproducción: Se encuentra dentro de la carpeta /web_egeria. En esta carpeta no se encuentra código fuente, sino el código compilado de la aplicación que genera y sube aquí automáticamente el servidor de integración continua y que, también automáticamente, se publica en el servidor de desarrollo. Distintas versiones del proyecto se machacan unas a otras en esta carpeta.
Versión del código para explotación: Se encuentra dentro de la carpeta /web_iuturna. En esta carpeta no se encuentra código fuente, sino el código compilado de la aplicación que genera y sube aquí automáticamente el servidor de integración continua y que, también automáticamente, se publica en el servidor de explotación. Distintas versiones del proyecto se machacan unas a otras en esta carpeta.
1.3.- Servidor de integración continua (Jenkins)
En ÁTICA disponemos de un servidor de integración continua, Jenkins. Este servidor de integración continua actua como un desarrollador más del proyecto integrando automáticamente el código, compilándolo y construyendo builds, chequeándolo automáticamente y, si todo está correcto, realizando despliegues automáticos en los servidores de desarrollo o explotación.
Por cada aplicación dispondremos de cuatro proyectos en el servidor de integración continua Jenkins.
NOMBREPROYECTO_desarrollo_GRUPOTRABAJO: Este proyecto integrará automáticamente el tronco del proyecto. Todos los días a las 00:00 automáticamente tomará el código del tronco del proyecto en
Subversion, lo compilará y construira una build, ejecutará los test unitarios y de integración que tengamos en el tronco y automáticamente desplegará el build en la carpeta /web_egeria del subversion del proyecto.Este código se desplegará automáticamente en el servidor de aplicaciones Egeria.
NOMBREPROYECTO_preproduccion_GRUPOTRABAJO: Cuando dispongamos de una rama lista para pasar a preproducción, manualmente tomaremos el código de la rama correspondiente de
Subversion y
Jenkins automáticamente lo compilará, constuirá una build, ejecutará los test unitarios y de integración que tengamos en la rama y automáticamente desplegará el build en la carpeta /web_egeria del subversion del proyecto. Este código se desplegará automáticamente en el servidor de aplicaciones Egeria.
Nota: Cómo carecemos de un servidor de preproducción, el proyecto de desarrollo y de preproducción despliegan los dos en web_egeria. Por eso cuando vayamos a desplegar una versión para preproducción debemos parar el despliegue automático del proyecto de desarrollo en Jenkins. |
NOMBREPROYECTO_produccion_GRUPOTRABAJO: Una vez chequeado en preproducción la aplicación por parte del usuario y pasados los test de rendimiento y de control de calidad adecuados, pasaremos manualmente el código de la rama correspondiente de
Subversion y
Jenkins automáticamente lo compilará, constuirá una build, ejecutará los test unitarios y de integración que tengamos en la rama y automáticamente desplegará el build en la carpeta /web_iuturna del subversion del proyecto. Este código se desplegará automáticamente en el servidor de aplicaciones Iuturna.
1.4.- Servidores de base de datos
En ÁTICA disponemos de 3 bases de datos para cada uno de los proyectos:
ISIS: Base de datos de desarrollo en ÁTICA. Esta es la base de datos que utilizarás para desarrollar tu aplicación.
VENUSCK: Base de datos de preproducción en ÁTICA. Esta base de datos copia el contenido de la base de datos de explotación, VENUS, todos los lunes de la semana. Si nos encontramos en preproducción debemos tener varias precauciones.
Avisar a sistemas para que cambien la fuente de datos del contenedor donde está la aplicación de ISIS a VENUSCK.
Si la estructura de base de datos en preproducción no es exactamente igual que en explotación debemos avisar a sistemas para que no actualice los esquemas correspondientes de nuestra aplicación en VENUSCK y modificar los esquemas correspondientes en VENUSCK para que se corresponda a las necesidades de nuestra aplicación en preproducción.
VENUS: Base de datos de desarrollo en ÁTICA. Esta es la base de datos que utilizará tu aplicación en producción.
Estas son las BBDD más utilizadas en ÁTICA pero existen otras que pueden ser utilizadas por tu proyecto. |
1.5.- Servidores de desarrollo
En ÁTICA se dispone de un servidor llamado Egeria para el desarrollo y preproducción de las aplicaciones. Por simplicidad este servidor no aparece en el gráfico del ciclo de vida del código del proyecto, ya que subversion copia automáticamente el contenido exacto de la carpeta web_egeria del servidor de control de versiones (SVN) al contenedor correspondiente del servidor de desarrollo.
1.6.- Servidores de explotación
En ÁTICA se dispone de un servidor llamado Iuturna para la versión de explotación de las aplicaciones. Por simplicidad este servidor no aparece en el gráfico del ciclo de vida del código del proyecto, ya que subversion copia automáticamente el contenido exacto de la carpeta web_iuturna del servidor de control de versiones (SVN) al contenedor correspondiente del servidor de explotación.
2.- Roles
2.1.- Desarrolladores
Las tareas que realizan los Desarrolladores dentro del ciclo de vida del código del proyecto son las siguientes:
Hacer checkout o update del tronco del proyecto para modificar el código del tronco
Modificar el código del tronco del proyecto
Hacer commit del código desarrollado por ellos en el tronco del proyecto
Hacer checkout o update de la rama de preproducción o producción, siempre y cuando se lo autorice el jefe de proyecto, para modificar el código de la rama
Modificar el código de la rama del proyecto activa en ese instante.
2.2.- Gestor de la configuración
Las tareas que realiza el gestor de la configuración dentro del ciclo de vida del código del proyecto son las siguientes:
Crear un tag del proyecto cuando crea que el tronco o rama activa está en condiciones de llevar a preproducción o a producción.
Parar el despliegue automático del tronco en el servidor de producción para que no interfiera en el despliegue de la aplicación en producción.
Subir manualmente a Jenkins el tag preparado para ser llevado a preproducción.
Subir manualmente a Jenkins el tag preparado para ser llevado a producción.
Generar los baseline de la aplicación cada vez que se libere una versión del proyecto.
2.3.- Jefe de Proyecto
Las tareas que realiza el gestor de la configuración dentro del ciclo de vida del código del proyecto son las siguientes:
2.4.- Integrador
Las tareas que realiza el Integrador dentro del ciclo de vida del código del proyecto son las siguientes:
Realizar el merge de la rama activa con el tronco cada vez que se produzcan modificaciones directamente en la rama del proyecto.
Resolver cualquier problema de integración que pueda surgir en el merge.
3.- Tronco y ramas
Para poder mantener un buen control sobre el código de nuestro proyecto, en MEDEA trabajaremos con un tronco y ramas. El tronco contendrá la línea principal de desarrollo de nuestro código, en las ramas tendremos el código de las distintas versiones destinadas a ser desplegadas en el servidor de explotación, aunque puede que algunas de ellas no lleguen al servidor de explotación y se queden en el de preproducción. La manera de trabajar en un proyecto normal será la siguiente.
Al comenzar a trabajar en un proyecto tendremos el tronco del proyecto donde todos los desarrolladores irán añadiendo el código que vayan desarrollando. Este código estará en la carpeta /Proyecto/Fuentes.
Tras varias iteraciones desarrollando código el jefe de proyecto considera que ya se está en condiciones de liberar una primera versión del proyecto. En ese momento el Gestor de la Configuración genera una rama del código en el servidor
Subversion del proyecto. Esta rama se creará mediante un
svn copy o mediante la opción
TortoiseSVN → Branch/Tag … de TortoiseSVN. Esta primera versión se etiquetará como 1.0.0.Beta. El código de las ramas estará en:
la carpeta Ramas/NombreVersion, por ejemplo en Ramas/1.0.0.Beta, Ramas/1.0.0.CR, etc, cuando estamos en desarrollo/pruebas, y
en la carpeta Version/NombreVersion, por ejemplo Version/1.0.0, etc, cuando ya tenemos una versión para desplegar en producción.
La versión 1.0.0.Beta se desplegará en el servidor de preproducción y puede que deba subrir modificaciones. Tras realizar estas modificaciones volvemos a crear otra rama que etiquetamos como 1.0.0.CR.
Desplegamos la versión 1.0.0.CR en el servidor de preproducción. A partir de aquí podemos tener que realizar nuevas versiones porque hay que modificar cosas o estar ya lista para sacar a explotación. Si tenemos que sacar nuevas versiones para preproducción las etiquetaremos 1.0.0.CRn y si es ya la versión para explotación la etiquetaremos 1.0.0.
Cada vez que generamos una nueva rama la anterior rama queda ya muerta. No se realizan modificaciones sobre ella. De esa manera únicamente tendremos dos líneas de código activas, el tronco y la rama desplegada en preproducción/producción.
Mientras uno o varios desarrolladores están trabajando con las ramas el resto del grupo de trabajo puede seguir trabajando con el tronco.
Una vez desplegada la versión 1.0.0 el integrador se encargará de llevar los cambios realizados en las ramas al tronco principal mediante un svn merge
En el gráfico del ciclo de vida del código del proyecto, podemos ver en su parte izquierda cómo tengo dos líneas de código simultáneas en el tiempo y como las versiones que vamos generando a partir de la rama de preproducción/explotación bloquean las ramas anteriores, teniendo en cada momento sólo dos líneas de código activas, el tronco y una rama.
Un caso especial es el de un grupo que esté realizando una versión de su proyecto para otra empresa/entidad. En este caso, para comenzar, creará una rama del proyecto y tratará este rama como si del tronco se tratase. En este caso tendrá el equivalente al tronco, pero siempre podrá realizar un merge que le permita llevar los cambios realizados en la rama al tronco o crear un parche de lo realizado en el tronco para aplicarlo en la rama.
4.- Despliegue automático de código en el servidor de desarrollo
Con el ciclo de vida del código del proyecto puesto en marcha en MEDEA tendremos automáticamente cada día una versión ejecutable del código del tronco. El servidor de integración continua Jenkins se encarga.
Cada noche a las 00:00 Jenkins se bajará el código del tronco del proyecto, compilará ese código, y le pasará las siguientes herramientas de verificación del estado del código:
Checkstyle para averiguar la calidad del código del proyecto.
Tareas que quedan sin resolver en el código (TODO existentes en el código).
FindBug para encontrar posibles Bug en el código.
Cobertura para ver el % de código que es revisado por los test unitarios y de integración.
TestNG para ver los resultados de los test unitarios y de integración ejecutados sobre el código.
Java NCSS para ver la evolución de los comentarios, javadocs, etc. en el proyecto.
Si la compilación del código del proyecto ha sido correcta y se ha construido la build del proyecto, el mismo Jenkins, automáticamente desplegará el build en la carpeta /web_egeria del subversion del proyecto. Este código se desplegará automáticamente en el servidor de aplicaciones Egeria.
Al no tener un servidor para preproducción debemos para el despliegue automático del tronco en el servidor de desarrollo para que este servidor pueda ser utilizado para la preproducción. Esto no significa que el servidor de integración continua no siga compilando automáticamente todas las noches la aplicación y construyendo el build, además de generar todos los informes mencionados anteriormente para conocer la evolución del proyecto. Lo único que dejará de hacer es el despliegue automático de la aplicación, pero podremos continuar probando la aplicación en local.
5.- Despliegue manual de versiones en preproducción. Beta y Candidate Releases
Con el ciclo de vida del código del proyecto puesto en marcha en MEDEA tendremos que desplegar “manualmente” la aplicación en preproducción. Previamente al despliegue manual en preproducción deberemos para el despliegue automático en desarrollo, ya que al no disponer de un servidor OAS para desarrollo y otro para preproducción compartimos el mismo servidor.
Para desplegar la versión Beta o la Candidate Release correspondiente en el servidor de integración contínua le tendremos que especificar la carpeta del proyecto donde está la versión.
Una vez subido el proyecto al servidor de integración continua Jenkins al proyecto correspondiente a preproducción, NOMBREPROYECTO_preproduccion_GRUPOTRABAJO, el funcionamiento de Jenkins es exactamente igual que el caso del despliegue en desarrollo.
Una vez finalizadas las pruebas en el servidor de preproducción tenemos que tener la precaución de volver a activar el despliegue automático del tronco en desarrollo.
6.- Despliegue manual de versiones en explotación
Con el ciclo de vida del código del proyecto puesto en marcha en MEDEA tendremos que desplegar “manualmente” la aplicación en explotación. Este despliegue es exactamente igual que el que se hacía para desplegar el proyecto en preproducción.
Para desplegar la versión en el servidor de integración contínua le tendremos que especificar la carpeta del proyecto donde está la versión que queremos desplegar en explotación.
Una vez subido el proyecto al servidor de integración continua Jenkins al proyecto correspondiente a explotación, NOMBREPROYECTO_explotación_GRUPOTRABAJO, el funcionamiento de Jenkins es exactamente igual que el caso del despliegue en preproducción o desarrollo.
7.- Aplicación de parches al tronco del proyecto
Si permitimos en MEDEA modificar el código de las ramas para incorporar pequeñas nuevas funcionalidades o resolver bugs en ellas tenemos que incorporar estos cambios hechos en la rama al tronco del proyecto, ya que si no lo hacemos perderemos la funcionalidad incorporada en la rama o repetiremos el error.
Para resolver esto el integrador se encargará de hacer un merge entre las ramas y el tronco para incorporar esta nuevas funcionalidades. Si hubiese algún problema de integración entre el código de la rama y el tronco será el Integrador el encargado de resolver el problema.
8.- Glosario