3.
1. Hoja de Control
Realizado por Fecha Firma
Dpto. de Arquitectura 21/10/2013
Revisado por Fecha Firma
Isaac Andrés Díez Bargueño
Aprobado por Fecha Firma
1.1 Control de versiones
Versión Motivo del cambio
Responsable del
cambio
Fecha Cambio
v1.0 Versión inicial Antonio Iglesias 11/10/2013
v1.1
Adición de los capítulos para
Maven y Jenkins
Rubén Martín 21/10/2013
2. Objetivo
En el presente documento se pretende analizar la problemática y plantear una solución sobre
cómo gestionar el código fuente de los proyectos de manera que simplifique tareas como
desplegar una cierta versión en un entorno concreto o realizar una marcha atrás de la versión
que se ha desplegado que es particularmente importante cuando los proyectos adquieren un
gran tamaño y hay varios entornos en los que se pueden desplegar (Desarrollo, Sandbox,
Preproducción, Producción).
3. Herramientas
Las herramientas que vamos a usar son:
● Eclipse IDE (con algún plugin de SVN)
● Control de Versiones con Subversión (SVN)
● Gestión y Construcción de Proyectos con Apache Maven
www.beeva.com
3
4.
● Artifactory: Repositorio de artefactos generados por Maven
● Integración contínua con Jenkis y Maven Release Plugin para Jenkis
4. Conocimientos previos
4.1 Política de versionado
Para el versionado vamos a usar la siguiente notación:
nombreProyectomajor.minor.bugfix[.revisión]
donde:
nombreProyecto: el nombre del proyecto, claro
major: indica la versión principal, este número sólo cambiará cuando se añadan
nuevas funcionalidades claves de la aplicación respecto de la versión anterior
minor: indican funcionalidad menor, cambiará cuando haya cambios significativos con
respecto a la funcionalidad existente o corrección de grandes fallos.
bugfix: corrección de pequeños fallos con respecto a la versión anterior.
revisión: correcciones o cambios que se hayan realizado de una versión que se haya
liberado
4.2 Maven y Artifactory, artefactos estables y artefactos en construcción
Puesto que no es el objetivo de este documento hablar del uso de Maven, sólo haremos un
inciso sobre Maven para indicar el uso que haremos de las versiones estables y las versiones
SNAPSHOT de los artefactos generados con Maven y dónde se guardan en el repositorio de
Maven (Artifactory).
● Versiones no definitivas (en construcción): en el pom se debe indicar que la versión se
esta desarrollando, para ello hay que añadir el sufijo “SNAPSHOT” a la versión en el
pom.xml, por ejemplo:
<version>3.1.1SNAPSHOT</version>
El tratamiento de Maven para estas versiones es diferente, por ejemplo, cuando se hace un
deploy de una versión snapshot, siempre se añade una copia del artefacto en el repositorio, el
nombre del artefacto se compone del artifactId + version + timestamp, con lo que para cada
deploy se genera un objeto distinto que se guarda en la misma ruta del repositorio pero que se
distinguen por la hora en la que se han guardado dentro del repositorio.
Los deploys de estas versiones se realizan en el repositorio indicado en la etiqueta
“snapshotRepository” del pom.xml, por ejemplo:
www.beeva.com
4
5.
<snapshotRepository>
<id>repoBeeva</id>
<name>Beeva Artifactory for Snapshots</name>
<url>http://ic.bbvaglobalnet.com/artifactory/libssnapshotlocal</url>
</snapshotRepository>
Cuando se tiene una dependencia de un artefacto SNAPSHOT, maven comprueba si la copia
que se tiene en el repositorio local es más reciente que la copia existente en el repositorio
remoto (artifactory) si ésta es más actual, se la bajará actualizando el repositorio local (.m2),
con lo nos aseguramos de que siempre usamos la versión más actual.
● Versiones definitivas (estables): en el pom se debe indicar que la versión se ha liberado
y por lo tanto es definitiva y estable, para ello simplemente hay que quitar el sufijo
“SNAPSHOT” de la etiqueta versión del pom.xml, por ejemplo, si se estaba
desarrollando la versión 3.1.1SNAPSHOT pues sería:
<version>3.1.1</version>
El tratamiento de maven para las versiones definitivas es, en los deploys simplemente se “pisa”
la versión que hay en el repositorio, aunque es una buena práctica configurar artifactory para
que no permita hacer deploy de una versión existente en el repositorio (habitualmente se hace
así), esto es así porque las versiones estables no se deben cambiar, de hecho, cuando se tiene
una dependencia de una versión estable, si ésta está ya presente en el repositorio local, maven
no la bajará del repositorio remoto.
Los deploys de estas versiones se realizan en el repositorio indicado en la etiqueta
“repository” del fichero pom.xml, por ejemplo:
<repository>
<id>repoBeeva</id>
<name>Beeva Artifactory</name>
<url>http://ic.bbvaglobalnet.com/artifactory/libsreleaselocal/</url>
</repository>
Otra práctica habitual es configurar artifactory para requerir autenticación a la hora de hacer
deploy de versiones estables (releases), la configuración de la autenticación se hace en el
fichero “settings.xml” de maven.
Se puede acceder a este fichero fácilmente desde eclipse desde:
Window > Preferences > Maven > User Settings
www.beeva.com
5
7.
actualizado y donde los desarrolladores hacen periódicamente los commits.
/tags: este subdirectorio contendrá los diferentes tags del proyecto, entendiendo como tag al
código congelado de una cierta versión y que se correspondrá con una release del mismo, o
sea, una versión estable del que tenemos la certeza que no cambiará, éstas serán las que se
desplieguen en el entorno de producción.
La siguiente imagen muestra una situación normal en un proyecto con las herramientas
anteriores:
5. Herramienta de control de librerías y dependencias
En Beeva, como herramienta de control de librerías y gestión de dependencias, se utiliza la
herramienta Maven.
5.1 ¿Qué es Maven?
Maven es una herramienta de construcción de código para java que permite compilar, ejecutar
test o realizar distribuciones, capaz de tratar de forma automática las dependencias de librerías
del proyecto.
Alguna de las ventajas que tenemos al utilizar Maven son:
www.beeva.com
7
8.
● Estandariza la estructura de directorios. Maven propone una estructura estándar de
directorios, gracias a esto eliminamos la problemática de estructuras arbitrarias
basadas en nuestro criterio.
● Integración. Maven se integra con otras herramientas y Frameworks tales como eclipse,
Selenium, CSV, SVN, hibernate, etc.
● Gestión de dependencias. Maven aporta un sistema de gestión de dependencias basado
en repositorios, lo que ayuda a reducir la duplicación de librerías requeridas durante la
generación de un proyecto. Para ello la sugerencia de Maven es almacenar todas las
librerías en un repositorio central. Maven usa por defecto el repositorio público ibiblio.org
que es el repositorio que contiene los groupsID de casi todos los jar de libre distribución
que se puedan encontrar en Internet. Adicionalmente se pueden definir repositorios
propios de librerías internas.
5.2 Estructura Maven
Para utilizar Maven es necesario utilizar una estructura defina que se explica a continuación:
● Proyectos Jar:
Proyecto
|src
|_|main
|_|_|java
|_|_|_|<paquetesjava>
|_|_|resources
|_|_|_|<ficherosrecursos>
|_|test
|_|_|java
|_|_|_|<paquetesjava>
|_|_|resources
|_|_|_|<ficherosrecursos>
|target
● Proyectos War:
Proyecto
|src
|_|main
|_|_|java
|_|_|_|<paquetesjava>
|_|_|resources
|_|_|_|<ficherosrecursos>
www.beeva.com
8
9.
|_|_|webapp
|_|_|_|<contenidoweb>
|_|_|_|WEBINF
|_|_|_|METAINF
|_|test
|_|_|java
|_|_|_|<paquetesjava>
|_|_|resources
|_|_|_|<ficherosrecursos>
|target
5.3 Definición del fichero de construcción pom.xml
Además de la estructura anteriormente explicada también es necesario definir un fichero de
configuración “pom.xml”, POM son las siglas de "Project Object Model" (Modelo de Objetos de
Proyecto) y contiene los detalles para la construcción de un proyecto Maven.
El “Pom.xml” es un archivo XML ubicado en la raíz del proyecto. Es un fichero de configuración
en donde declaramos datos sobre el proyecto, las dependencias y puglins necesarios para
compilar un proyecto.
Un ejemplo de la configuración que tiene el fichero pom.xml tiene que contener es el siguiente:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<! The Basics >
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<! Build Settings >
<build>...</build>
www.beeva.com
9
12.
6. Herramienta de integración continua
6.1 ¿Qué es la integración continua?
La integración continua (CI) es una metodología informática que consiste en realizar
integraciones (o también llamadas construcciones) de un proyecto de forma automatizada y
continua, entendiéndose por integración la compilación, ejecución de tests, generación de los
paquetes de software e incluso el posible despliegue de todo un proyecto.
6.2 Finalidades que se persiguen en su implantación
Los propósitos principales que persigue esta metodología de desarrollo son:
● Agilizar y facilitar la ejecución iterativa de todas las tareas relacionadas con la
construcción de un proyecto permitiendo la automatización y planificación de las
mismas.
● Anticipar la detección de posibles fallos.
En definitiva, la integración continua tiene como finalidad última minimizar progresivamente en
cada iteración el coste del desarrollo tanto en las pruebas de las funcionalidades como en la
detección y solución temprana de problemas, consiguiendo con ello maximizar la calidad del
producto entregado.
6.3 Ventajas que se derivan de su utilización
Las principales ventajas que aporta la herramienta de integración continua son las siguientes:
● Disponibilidad constante y en cualquier fase del proyecto de una construcción del
desarrollo que se está implementando, ya sea para pruebas, demos o incluso para
lanzamientos anticipados.
● La ejecución inmediata, y en cada iteración, de las pruebas unitarias del código
implementado en el desarrollo.
● La detección y solución de forma continúa de problemas de integración por parte de los
desarrolladores, consiguiendo de este modo evitar en gran medida los problemas de
última hora que se acarrean a medida que se va aproximando la fecha de entrega del
producto.
● Monitorización continua e inmediata de las métricas de calidad del proyecto, así como
del resultado obtenido en cada iteración del mismo.
6.4 Descripción del entorno de integración continua utilizado por Beeva
www.beeva.com
12
13.
La herramienta adoptada por Beeva para implantar esta metodología de desarrollo es Jenkins.
Este software de código abierto (distribuido y desarrollado libremente) ha sido desarrollado en
Java, y permite ser ejecutado tanto en contenedores de servlets (por ejemplo Apache Tomcat),
como de forma directa, utilizando para ello el servidor de aplicaciones Winstone.
Jenkins permite trabajar con diferentes herramientas de control de versiones (repositorios),
ejecutando proyectos basados en Apache Ant y Apache Maven, así como la ejecución (tanto en
local como en remoto) de Shell scripts o procesos por lotes de Windows.
6.5 Configuraciones y utilización de Jenkins
El entorno de integración continua sobre Jenkins utilizado por Beeva presenta la siguiente
configuración:
● Utilización de Subversion (SVN) como repositorio de software y herramienta de control
de versiones.
● Utilización mayoritaria de Apache Maven para la compilación, ejecución de pruebas
unitarias del desarrollo y generación del paquete de software, contemplándose también
la posibilidad de utilizar Apache Ant debido a que la configuración de Jenkins incluye el
plugin para la integración de esta herramienta.
● Despliegue de los paquetes generados mediante la ejecución de procesos por lotes
(Shell scripts) preferiblemente.
Para integrar un proyecto en Jenkins, se deberá configurar (al menos) una nueva tarea
independiente de las ya existentes, que en términos generales deberá ejecutar de forma
ordenada los siguientes pasos:
● Descarga del código fuente del repositorio Subversion (SVN).
● Compilación del código descargado.
● Ejecución de las pruebas unitarias.
● Generación del paquete de software que contendrá el código compilado.
● Despliegue del paquete generado en el servidor que proceda.
6.6 Plugins utilizados en el entorno Jenkins
A continuación se ofrece un listado de los plugins más relevantes utilizados en el entorno
Jenkins de Beeva:
● Subversion Plugin: Para la descarga de proyectos almacenados en el repositorio de
software Subversion (SVN). Este plugin se incluye con la distribución de Jenkins.
● Maven 2 Project Plugin: Para la construcción de proyectos basados en Apache Maven.
Este plugin se incluye con la distribución de Jenkins.
● ant: Para la construcción de proyectos basados en Apache Ant. Este plugin se incluye
con la distribución de Jenkins.
● Jenkins Sonar Plugin: Para la integración de la plataforma Sonar en Jenkins, destinada a
www.beeva.com
13
14.
la realización de análisis de calidad del software implementado.
● Selenium Plugin: Para la integración de Selenium en Jenkins. Selenium es un framework
para el testeo de software destinado a aplicaciones web que permite la ejecución
programada de pruebas funcionales, sirviéndose para ello de diversos componentes
(IDE, Remote Control, Grid, etc).
● Publish Over SSH: Para el envío de ficheros y la ejecución de comandos y scripts en
servidores remotos a través del protocolo SSH (Secure Shell).
7. Generación de Releases
La generación de las Releases se hará, por un lado con Eclipse (y el plugin de SVN), con el que
se creará el branch y por otro con Jenkis, que tendrá configurado el plugin “Maven Release” (el
Jenkis que usamos en Beeva bajo el control del equipo de sistemas ya lo está).
7.1 Procedimiento de Generación de una Release
1. Cuando decidamos que la línea de desarrollo principal está estable, procedemos a
generar un branch desde el Eclipse: botón derecho sobre el “trunk” > “team” >
“branch”. El nombre del branch incluirá el nombre del proyecto y la versión:
nombreProyectoreleaseVersion, esta instrucción realmente lo que hace es hacer
una copia del “trunk” y ponerla en el directorio “branches” con el nombre que hayamos
elegido (de hecho, tanto create branch como create tag están basados en el svn copy).
2. Preparar el pom.xml para que funcione con el plugin de Jenkis: sólo se requiere poner la
etiqueta “scm” y que apunte al branch recién creado:
<scm>
<connection>scm:svn:http://subversion.bbvaglobalnet.com/java/…./branches/proyectoXreleas
eVersion</connection>
<developerConnection>scm:svn:http://subversion.bbvaglobalnet.com/java/.../branches/proyect
oXreleaseVersion</developerConnection>
</scm>
3. Generar la Release con la tarea de Jenkis, la tarea de generación de releases de Jenkis
estará asociada al despliegue en el entorno de Desarrollo. La pantalla será algo así
como:
www.beeva.com
14
15.
Los campos que tenemos que rellenar son:
releaseVersion: la versión que vamos a liberar (la que tiene el sufijo SNAPSHOT de la
etiqueta “version” del pom.xml)
developmentVersion: la siguiente versión que se empezará a desarrollar, el plugin
creará un artefacto SNAPSHOT con la versión que se indique.
version: la ruta de donde se va a sacar el codigo a liberar, en nuestro caso el branch
creado en el primer punto:
www.beeva.com
15
16.
Lo que conseguimos es, por un lado generar una release (versión estable) con la versión
3.0.1 que se desplegará en el repositorio de releases, por otro lado se generará un tag (código
congelado e intocable) con la versión 3.0.1, normalmente éste tag será el que se despliegue en
entornos como preproducción o producción.
Por último, no olvidar que si el artefacto generado es dependencia de otros, hay que actualizar
la versión a la generada.
7.2 Procedimiento de Generación de una revisión de una Release
¿Qué pasa si encontramos un bug en un tag? básicamente, generar otro que lo corrija, quizá
a priori parece un poco tedioso y muchas veces estaremos tentados a corregir el bug
directamente en el tag con excusas como: “... si es una tonteria, es sólo cambiar una clase!” ó
“... no te preocupes, que lo tengo localizado y fijo que no falla” pero esta práctica tiene el riesgo
de que por cualquier cosa el bug este mal corregido (y pasa a veces) y no podamos volver a
una situación conocida, con lo cual un tag NUNCA se debe modificar, para asegurarnos de que
www.beeva.com
16
17.
no es así se procede de la siguiente manera: por un lado se configura el artifactory para que no
se haga deploy de una versión estable (un release) de la que ya se ha hecho deploy
anteriormente y por otro lado, se debe configurar el repositorio de subversion para que no se
permita hacer commits a tags.
Lo primero que hay que aclarar es que no siempre queremos incluir el bugfix en el propio tag, si
éste puede esperar a la siguiente release, el tag/release se dejará tal y como está y sólo se
cambiaría el “trunk” para incluir el bugfix en la siguiente release, pero si es importante incluir el
bugfix en una determinada versión, el procedimiento es:
1. Partir de un branch, en una situación normal, cuando ya se ha generado un branch para
una versión concreta, sólo hará falta modificar el código asociado al branch, de hecho
sólo hará falta un branch por versión y éste contendrá el código asociado a la última
revisión de la versión.
2. Modificar el branch, desplegarlo en el entorno de desarrollo para su validación. Una vez
validado, hay que incluir el bugfix en las versiones posteriores y el “trunk” (se puede usar
el merge de SVN)
3. Una vez validado se genera desde Jenkis otra release, recordar el número que se
modifica de la versión es el 4º (revisión) ya que la versión de la release es la misma:
www.beeva.com
17
18.
Como podemos ver en la imagen, el branch del que se parte es el mismo que se uso
para generar la ultima release/tag.
4. El tag está listo para ser validado y desplegado en Producción.
5. Por último, no olvidar que si el artefacto generado es dependencia de otros, hay que
actualizar la versión a la generada.
Como hemos visto, nosotros en ningún caso ni generamos un tag manualmente, ni lo
modificamos, el tag es generado a partir de un “branch” por el plugin de Jenkis, por otro lado,
aparecerá en las listas de despliegue para ser desplegado en el entorno que queramos.
www.beeva.com
18