Anda di halaman 1dari 41

UNIVERSIDAD CENTRAL DEL ECUADOR

FACULTAD DEINGENIERÍA CIENCIAS FÍSICAS Y MATEMÁTICA

CARRERA DE INGENIERÍA INFORMÁTICA

PROYECTO DE TITULACION

TEMA:

INTEGRACION CONTINUA

AUTOR: Diana Cristina López Olives

SEMESTRE: 8vo-1

Quito – Ecuador

2019-2019
Contenido
INTEGRACION CONTINUA ........................................................................................................ 1
CAPITULO I ...................................................................................................................... 4
1. MARCO TEORICO ..................................................................................................... 4
1.1 ¿Qué es Integración Continua? .......................................................................................... 4
1.2 ¿Cómo funciona? ............................................................................................................... 5
1.3 ¿Por qué es necesaria la integración continua? ................................................................. 5
1.4 ¿En qué consiste la integración continua? ......................................................................... 5
1.5 ¿Como mejora la Integración Continua la calidad del software? ....................................... 6
1.6 Buenas prácticas que intervienen en la integración continua ........................................... 7
1.7 Componentes de la integración continúa .......................................................................... 9
Servidor de integración continúa ..................................................................................... 9
Servidor de control de versiones .................................................................................... 10
Pruebas de verificación.................................................................................................. 10
Análisis de código estático. ............................................................................................ 11
1.8 Beneficios de la integración continua .............................................................................. 12
1.9 Ventajas de integración continua .................................................................................... 13
1.9 Desventajas de la integración continua ........................................................................... 13
1.11 Costo de Distribución..................................................................................................... 15
CAPITULO II ................................................................................................................... 16
2. Las mejores herramientas utilizadas en Integración Continua.................................. 16
2.1 Jenkins ............................................................................................................................. 16
2.2 Travis CI ........................................................................................................................... 17
2.3 Bamboo ........................................................................................................................... 18
2.4 GitLab CI .......................................................................................................................... 19
2.6 CruiseControl ................................................................................................................... 20
2.7 Codeship .......................................................................................................................... 21
2.8 TeamCity .......................................................................................................................... 22
2.9 Tabla comparativa de herramientas de integración continua ......................................... 23
CAPITULO III ................................................................................................................. 24
3. Como construir un entorno de Integración Continua con Jenkins y Docker………………..24
3.1 Un master para dominarlos a todos ............................................................................... 25
3.3 Para crear: «Hello World»…………………………………………………………………………………………….27
3.4 Agentes, esclavos y nodos ............................................................................................... 29
3.5 Inspeccionando el código……………………………………………………………………………………………..35
3.5 Apagando y encendiendo……………………………………………………………………………………………. 39
4. Conclusiones.......................................................................................................... 40
5. Bibliografía ............................................................................................................ 41
INTRODUCCIÓN

En muchas ocasiones como desarrolladores estaremos haciendo deploy


de nuestras aplicaciones de forma manual; Por ejemplo, si hablamos de un sitio
web, el primer paso es subir todos los cambios a nuestra rama principal,
posteriormente ejecutar todas las pruebas unitarias, si las pruebas son exitosas
se procede ha compilar el proyecto y subir todo los cambios ha producción,
ejecutar las migraciones y listo, los clientes ya podrán hacer uso de los nuevos
features en el sitios web, claro, siempre y cuando ninguno de los pasos
anteriores hayan fallado.

Todos estos pasos a menudo son tediosos e involucran una cierta cantidad de
tiempo, tiempo en el que regularmente el desarrollador no tiene mucho que
hacer. Para evitar estos problemas surge la integración, entrega y despligue
continuo.

En el último artículo, hablaba de la necesidad de las pruebas, para el


aseguramiento de la entrega de valor. Y ciertamente, en uno de los comentarios
acertaron plenamente a nombrar otra práctica, muy necesaria para la entrega
de valor. La integración continua.

Seguro que muchos han vivido esta situación, dos, tres días antes de
pasar a un entorno, desarrollo o preproducción (en el mejor de los casos), o
incluso a producción (en el peor de los casos), alguien va al control de código
fuente y obtiene la última versión, todos sabemos que esto debería hacerse a
diario, pero eso es tema de otro artículo. El caso es que se trae todo, y lanza la
compilación, y lo siguiente que se oye es “ups, no compila”, la cara se nos
desencaja, a todo el equipo, y pensamos ¿qué ha pasado? Y ahora ¿qué binarios
desplegamos?

Otra situación que puede ocurrir, igual de preocupante, una vez con la
última versión, lo compilamos en “cualquier máquina”, todo va bien, lo subimos
al entorno, y de repente algunas funcionalidades, dependientes de referencias
externas fallan, y oímos la frase “en mi máquina (la de compilación) funciona”.
Esto habitualmente es debido a que no hemos usado una máquina limpia (con
las referencias en la misma versión que tendremos en los entornos), para esa
compilación. Son situaciones, que por desgracia, veo más frecuentemente de lo
que me gustarían.
CAPITULO I

1. MARCO TEORICO
1.1 ¿Qué es Integración Continua?
La integración continua (continuous
integration en inglés) Es un
modelo informático propuesto inicialmente
por Martin Fowler que Consiste en
hacer integraciones automáticas de un proyecto
lo más a menudo posible para así poder
detectar fallos cuanto antes. Entendemos por
integración la compilación y ejecución de
pruebas de todo un proyecto.

“Práctica de desarrollo software donde los miembros del equipo integran su


trabajo frecuentemente, al menos una vez al día. Cada integración se verifica con un
build automático (que incluye la ejecución de pruebas) para detectar errores de
integración tan pronto como sea posible.”

El proceso suele ser: cada cierto tiempo (horas), descargarse las fuentes desde
el control de versiones (por ejemplo CVS, Git, Subversion, Mercurial o Microsoft Visual
SourceSafe) compilarlo, ejecutar pruebas y generar informes.

Para esto suelen utilizarse aplicaciones como Solano CI, Bamboo, Pipeline,
ApacheContinuum, Hudson, Jenkins, GoCD, CruiseControl o Anthi ll (para proyectos
Java) o CruiseControl.Net, Team Foundation Build para .Net, que se encargan de
controlar las ejecuciones, apoyadas en otras herramientas como Ant o Maven
(también para proyectos Java), o Nant o MSBUILD (para .Net) que se encargan de
realizar las compilaciones, ejecutar las pruebas y realizar los informes. A menudo la
integración continua está asociada con las metodologías de programación extrema y
desarrollo ágil.

La integración continua es una práctica de desarrollo de software mediante la


cual los desarrolladores combinan los cambios en el código en un repositorio central
de forma periódica, tras lo cual se ejecutan versiones y pruebas automáticas. La
integración continua se refiere en su mayoría a la fase de creación o integración del
proceso de publicación de software y conlleva un componente de automatización (p.
ej., CI o servicio de versiones) y un componente cultural (p. ej., aprender a integrar con
frecuencia).

Los objetivos clave de la integración continua consisten en encontrar y arreglar


errores con mayor rapidez, mejorar la calidad del software y reducir el tiempo que se
tarda en validar y publicar nuevas actualizaciones de software.
Además es un tema el cual se ha vuelto muy popular en los últimos años,
principalmente, por el impulso que ha tenido por parte de grandes empresas, tales
como Netflix, Uber, entre otros; Las cuales basan su desarrollo en un enfoque agilista.

1.2 ¿Cómo funciona?


Cada programador debe subir su trabajo diario al repositorio. Esto permite que
cada vez que se detecte un cambio en el repositorio y/o de forma planificada por la
noche, se realice una construcción automática de todo el proyecto y se ejecuten,
también de forma automática, los tests. Se genera un informe que se envía por mail a
todo el equipo.

1.3 ¿Por qué es necesaria la integración continua?

Anteriormente, era común que los desarrolladores de un equipo trabajasen


aislados durante un largo periodo de tiempo y solo intentasen combinar los cambios
en la versión maestra una vez que habían completado el trabajo.

Como consecuencia, la combinación de los cambios en el código resultaba


difícil y ardua, además de dar lugar a la acumulación de errores durante mucho tiempo
que no se corregían. Estos factores hacían que resultase más difícil proporcionar las
actualizaciones a los clientes con rapidez.

1.4 ¿En qué consiste la integración continua?

Con la integración continua, los desarrolladores envían los cambios de forma


periódica a un repositorio compartido con un sistema de control de versiones como
Git. Antes de cada envío, los desarrolladores pueden elegir ejecutar pruebas de unidad
local en el código como medida de verificación adicional antes de la integración.

Un servicio de integración continua crea y ejecuta automáticamente pruebas


de unidad en los nuevos cambios realizados en el código para identificar
inmediatamente cualquier error.
La integración continua se refiere a la fase de creación y pruebas de unidad del
proceso de publicación de software. Cada revisión enviada activa automáticamente la
creación y las pruebas.

Con la entrega continua, se crean, prueban y preparan automáticamente los


cambios en el código y se entregan para la fase de producción. La entrega continua
amplía la integración continua al implementar todos los cambios en el código en un
entorno de pruebas y/o de producción después de la fase de creación

1.5 ¿Como mejora la Integración Continua la calidad del software?

Calidad de proceso
En primer lugar, con la integración continua se le da más visibilidad al proceso
de desarrollo en general, a todos los pasos que se siguen desde que se empieza a
programar un requisito del cliente hasta que está en producción.
Así, todo el mundo sabe las fases por las que va pasando el código, y el estado
del software en cada momento (si compila, si pasa las pruebas, en qué entorno está
cada versión, qué versión se está probando etc).
También le damos visibilidad a la estrategia de gestión de configuración,
política de ramas del control de versiones y tagueos, entre otras cosas.
Si todo el equipo no conocía esto bien, o las estrategias estaban poco definidas,
con la integración continua habrá que solucionarlo.
Y esto ya es un avance importante, porque en muchas empresas a las que
vamos, todas estas cosas imprescindibles no son conocidas por todo el equipo, ni
están claras ni bien definidas.
Calidad de producto
Por otro lado, también se mejora la calidad del producto software.
El principal objetivo de la integración continua es detectar los errores lo más pronto
posible, en fases tempranas del desarrollo, para poder solucionarlos rápidamente.
Así se introducen varios tipos de pruebas y comprobaciones, minimizando los
riesgos, y haciendo que el software tenga menos bugs que si no realizáramos
integración continua.
Por otra parte, en fases ya avanzadas de la integración continua se suelen
lanzar inspecciones continuas de código, análisis periódicos para detectar problemas
de calidad en él.
Los desarrolladores tendrán que mejorar esas deficiencias, e incluso en ciertas
ocasiones, se puede impedir que los desarrolladores suban el código al control de
versiones si no cumplen los estándares de calidad definidos por la empresa.

Calidad de las personas


Por último, también se mejora la calidad del equipo. Si no sabía, el equipo
acaba aprendiendo a hacer distintos tipos de pruebas (unitarias, de integración),
mejores prácticas de programación y en general a desarrollar código de mayor calidad.
Además, tener todo este proceso de desarrollo claro y tener todas estas
comprobaciones para minimizar los riesgos, le da más confianza al equipo.
Así es capaz de afrontar nuevos retos, mejoras y cambios y está más motivado.
Además de que le ahorra muchísimo tiempo, porque automatizamos procesos
repetitivos (por ejemplo ciertas pruebas de regresión), dejando más tiempo para hacer
otras cosas.
Y todo esto, al final se acaba reflejando en una mejora de cara al cliente y por
supuesto en términos económicos para la empresa.

1.6 Buenas prácticas que intervienen en la integración continua

Vamos a ir partiendo de la definición de Fowler para ir identificando los componentes


e ideas claves de la integración continua.

1. “Práctica de desarrollo software”


Como ya sabemos, la integración continua afecta al proceso de desarrollo del
software, incorporando nuevas prácticas o interconectando las que ya había.
Para implantar integración continua solemos definir un “pipeline”, un conjunto de
etapas, de fases por las que va pasando el software y que se automatizan.
Un ejemplo de un pipeline podría ser que con cada subida de código al
repositorio de control de versiones este se descargue y compile.
Si está todo correcto, que se ejecuten una serie de pruebas unitarias, o se despliegue
el código a otro entorno para hacer pruebas de sistema.

Esta es una de las primeras cosas que hay que definir, saber cómo es el
desarrollo, cuál es el criterio para que el código promocione de un entorno a otro, y
qué se hace en cada entorno.
Y si el código no pasa algún punto hay que establecer cuál es la estrategia para
resolver el error, quién se encarga de ello, cómo se gestiona.
Este sería un ejemplo de cómo se vería un pipeline implementado en Jenkins.

Esto es a lo que me refería con visibilidad del proceso. Podremos saber qué
revisión de código compila, cuál no y en qué punto del pipeline se encuentra cada
subida del código.

2. “Los miembros del equipo integran su trabajo frecuentemente”


¿Dónde se suele integrar, poner en común el trabajo que hace cada
desarrollador? En el control de versiones.

En un equipo, el código que implementa cada desarrollador no suele actuar aislado.


Cuando se distribuye el trabajo entre los miembros del equipo, y cada uno
comienza a trabajar, normalmente se asumen cosas de otros componentes del
software que todavía no están implementados o que está programando otra persona.
Y hasta que no juntamos todo ese código, no nos damos cuenta de los errores de ese
tipo que cometemos.

Antes, lo que se tendía a hacer es que cada desarrollador programara de forma


independiente y luego al final se realizaba la integración de todo el código.
Esto se traduce en integraciones difíciles, que tardan mucho en completarse y mucho
sufrimiento, ya que hay muchos cambios, mucho código que integrar.
Uno de los motivos por los que surge la integración continua es para evitar
esto. La idea es que en vez de dejar la integración para el final, se vayan haciendo
pequeñas integraciones de código frecuentemente.

1.7 Componentes de la integración continúa

Si bien los procesos de integración continua pueden variar y adaptarse de acuerdo


a las diferentes metodologías y procesos de desarrollo en general existen 4 principales
componentes en un esquema de integración continua típico.

• Servidor de integración continúa.


• Repositorio Central.
• Pruebas de auto verificación.
• Análisis de código estático.

Servidor de integración continúa

El servidor de integración de continua facilita las tareas de automatización,


despliegue, ejecución de pruebas y análisis de código. Existen varias alternativas en el
mercado Open source y de licencia comercial integrados con los diferentes ambientes
de desarrollo.
Estos servidores ejecutan tareas programadas que garantizan la calidad del código
y facilitan la detección de errores. Entre las alternativas más populares se encuentran
Jenkins, Hudson , Bamboo, Team City y CruiseControl.NET

Panel de resultados de un proyecto en Jenkins. La imagen muestra el Javadoc


generado, el análisis de cobertura, el resultado de las pruebas y un resumen de las
ultimas ejecuciones.
Servidor de control de versiones

El servidor de control de versión se encarga de almacenar el código fuente y de


permitir la actualización y descarga en los ambientes de desarrollo, pruebas y
producción.

Dependiendo de las necesidades de cada equipo y proyectos existen diferentes


alternativas. Git y Mercurial permiten la administración distribuida de cambios
haciendo commit en repositorios locales y sincronizando con el servidor central
mientras otras alternativas como SVN está diseñado para realizar commits
directamente sobre el servidor central.

Cambios en un commit git

Pruebas de verificación.

Las pruebas automatizadas son las encargadas de garantizar que el construcción es


estable y cumple con las características diseñadas. Para realizar estas pruebas la idea es
crear pruebas de caja blanca (evalúan la estructura interna de la aplicación) como las
pruebas de unidad e integración y pruebas de caja negra (prueban el funcionamiento sin
conocer la estructura) como las pruebas de sistema o pruebas funcionales.
Si bien estas últimas son complejas de automatizar existen herramientas que
permiten la simulación interacciones del usuario con la aplicación y evaluación de
resultados.

Análisis de código estático.

Las herramientas de análisis de código estático no permiten o evalúan si


componentes o unidades del software realizan la tarea para la cual fueron diseñadas
sin embargo ayudan a mantener la calidad de código fuente al evaluar métricas como
la documentación de métodos, el nombrado de variables y el encapsulamiento.
Herramientas como FxCop para .Net o PMD para java permiten identificar defectos en
el código mediante la verificación de reglas.
1.8 Beneficios de la integración continua

Mejore la productividad de desarrollo

La integración continua mejora la productividad del


equipo al liberar a los desarrolladores de las tareas
manuales y fomentar comportamientos que ayudan a
reducir la cantidad de errores y bugs enviados a los
clientes

Encuentre y arregle los errores con mayor rapidez

Gracias a la realización de pruebas más frecuentes, el


equipo puede descubrir y arreglar los errores antes de
que se conviertan en problemas más graves.

Entregue las actualizaciones con mayor rapidez

La integración continua le permite a su equipo entregar


actualizaciones a los clientes con mayor rapidez y
frecuencia.

Como muchos otros procedimientos de la metodología Ágil, una de las funciones


principales de la CI o Integración Continua, es facilitar el trabajo a los desarrolladores.
Cuando hablamos de integración continua, nos referimos a la creación de código entre
diferentes desarrolladores y bajo una minuciosa comprobación del mismo.

Para hacer que esto sea posible y fácil, no esperaremos a que el código esté
finalizado, como se hacía en los métodos convencionales o de cascada, sino que
dividiremos el trabajo en pequeñas tareas, también denominadas sprints, que no
suponen un gran esfuerzo ni necesitan una gran inversión de tiempo, de forma que se
puedan ir comprobando dichas tareas frecuentemente.

Estas comprobaciones se deben llevar a cabo por lo menos una vez al día y suelen
ser realizadas al finalizar cada jornada laboral. En base a los resultados, podemos seguir
creando o entramos en la fase de modificación, donde una vez detectado el error, el
grupo decidirá cómo se puede superar y para ello, que deben modificar.

Ágil implica trabajar de forma rápida e intentar reducir el rango de errores al


mínimo posible. Una forma de poder conseguirlo es fomentando el trabajo en equipo,
de forma que se ayuden para superar las trabas y aprendan los unos de los otros. Otra
característica es desglosar los grandes proyectos en pequeñas tareas, de forma que el
trabajo se mucho más llevadero, la presión menor y los tiempos de entrega /
validación, más frecuentes.

Por lo tanto, un flujo contínuo de revisiones, opiniones, pruebas, feedback


entre el cliente y entre los miembros del equipo, superación de errores, cuidar el
código y trabajar cómodo hace que este tipo de prácticas sean tan frecuente hoy en
día. Ahora ya sabemos que un trabajo más eficiente y rentable es posible.

1.9 Ventajas de integración continua

• Como es fácilmente deducible, el nombre que adquiere esta práctica es


descriptivo y literal. Nos basamos en la comprobación continua del código para
poder integrar poco a poco las mejoras o ir actualizando a diario para obtener
un resultado mucho más fiable y en periodo menor de tiempo. Lo que nos
permite ajustarnos mejor a los timings propuestos y evitar las presiones
derivadas de última hora por la presión de las entregas.

• Otra de las ventajas que tiene la CI es a nivel personal. Puesto que estas prácticas
se llevan a cabo en proyectos conjuntos, son los propios desarrolladores los que
van a ir analizando el código creado, apoyándose los unos en los otros. Ellos
mismos van a tener que aprender diferentes métodos de integración y verse
obligados a superar día tras día diferentes errores o fallos encontrados en el código
creado. Esto fomenta la comunicación entre el equipo, y hace que sea mucho más
enriquecedor tanto a nivel individual como a nivel de grupo o equipo.

• En todo momento se tendrá una versión para pruebas, o una primera fase para
poder contrastar la evolución del código de forma que haga posible detectar
los errores a tiempo y poder corregirlos.

• A su vez, en todo momento cada miembro del equipo tiene acceso a la versión
final.

• La integración continua garantiza unos resultados de calidad y un


funcionamiento correcto del proyecto gracias a su continua supervisión y a la
reducción de errores.
• Evidentemente todo este proceso de revisiones y correcciones lo más
frecuentes posibles, forman parte de una automatización que se desarrolla
para facilitar la comunicación entre el equipo y la evolución del proyecto.

• Otro factor importante en la integración continua, es la monitorización de las


métricas más relevantes de nuestro proyecto, de forma que podamos tener
presente en todo momento la calidad del mismo. Esto a la larga, nos llevará a
un buen código sin necesidad de modificaciones una vez llevado a la última
fase, puesto que lo vamos optimizando a medida que lo construimos.

1.10 Desventajas de la Integración Continua

• Cultura de la organización, sin ánimo de extenderme mucho, construir el caso


de uso de la integración contínua en una organización cuyos procedimientos no
incluyen pruebas unitarias puede ser algo duro.

• Tiempo de configuración inicial, en un entorno en el que se diseñan,


desarrollan y documentan adecuadamente los casos de prueba, sólo nos queda
invertir el tiempo oportuno en la configuración de las herramientas de
integración continua. Si no disponemos de pruebas unitarias, es más
conveniente empezar por ahi.

• Buenas pruebas unitarias, cierto que el papel lo soporta todo, pero en


ocasiones las pruebas unitarias también. Hacer revisión de código de las
pruebas unitarias, o ideas simples como un desarrollador realiza el código y
otro las pruebas de ese código te dará resultados sorprendentes. En cierta
ocasión recuerdo que para irse pronto a casa los desarrolladores hacían que las
pruebas siempre fueran bien (AssertTrue(true)).

• Costes de hardware, es necesario un conjunto de máquinas que albergarán las


diversas herramientas para la integración contínua: repositorio,
automatización, entornos.

• Costes de personal de QA, además de las máquinas habrá personal que se


encargue de la configuración, seguimiento, realización y generación de
informes de las pruebas. La ventaja es que cualquiera puede ver el resultado de
las pruebas con lo que los propios desarrolladores pueden corregir aquellas
partes del código que no sean correctas, o los gestores de proyecto controlar la
calidad del producto construido.
1.11 Costo de Distribución

Como puedes ver, la implementación es algo más costosa, debido a la necesidad de


usar diferentes herramientas que nos permitan llevar a cabo un proceso ágil, midiendo
las métricas y detectar los errores a tiempo.

Pero en el resto de campos, implementar la integración continua en nuestros


desarrollos, ha hecho que seamos mucho más económicos que la competencia, sobre
todo en las etapas de mantenimiento, puesto que los posibles errores se localizan
rápidamente y se solucionan prácticamente de inmediato.

Gracias que creamos un código limpio y organizado, enfocado siempre al


consumidor final.
CAPITULO II

2. Las mejores herramientas utilizadas en Integración Continua

La integración continua (IC) permite a los desarrolladores de software evitar una


larga y problemática fase de integración al final de un proyecto. En lugar de compilar
todos los componentes al final, con la IC se van implementando todas las novedades
directamente en el código base.

Esto requiere disciplina y un proceso eficiente, pues de lo contrario la IC


obstaculizará más de lo que ayudará. El proceso se puede facilitar además con
software específico. Actualmente existe una gran cantidad de herramientas en el
mercados las cuales nos permiten implementar integración y entrega continua.

Todas tienen como objetivo ayudar al desarrollador en la implementación de esta


metodología, y lo hacen de diferentes modos y con la ayuda de características
distintas. Pero estas herramientas no solo se diferencian unas de otras en cuanto a sus
características, sino que también existe una gran variedad en lo que respecta a precios
y licencias.

Mientras que muchas de ellas son de código abierto y se encuentran disponibles de


forma gratuita, otros fabricantes ofrecen herramientas comerciales. A continuación, te
ofrecemos un resumen de las más utilizadas y examinamos sus características y
funciones:

2.1 Jenkins

Esta herramienta se presenta como un “mayordomo” para el desarrollador (fuente: https://jenkins.io/)

Jenkins es probablemente una de las herramientas de integración continua más


conocidas del mercado. Este software escrito en Java ha continuado desarrollándose
constantemente desde el año 2005 (entonces, bajo el nombre de Hudson) y cuenta en
la actualidad con numerosas funciones que asisten no solo en la integración continua,
sino también en el despliegue y la entrega continua.

• Escrito en Java
• Se ejecuta en un contenedor EJB
• Más de 1 000 plugins
• Asiste también en la entrega y el despliegue continuo
• Compatible con muchos sistemas de control de versiones
• Controles mediante GUI (basados en web), API REST o línea de comandos
• Alojamiento opcional en la nube
• Gratuita
• De código abierto (licencia MIT)

2.2 Travis CI

Travis CI ofrece una interfaz clara (fuente: https://travis-ci.org/)

A los usuarios de GitHub les encantará Travis CI, puesto que esta herramienta de
integración continua trabaja en estrecha relación con el popular software de control de
versiones. Esta herramienta puede configurarse con un sencillo archivo YAML que se
guarda en el directorio raíz del proyecto. GitHub informa a Travis CI de todos los
cambios efectuados en el repositorio y mantiene el proyecto actualizado.

• Programado en Ruby
• Multiplataforma
• Funciona con GitHub
• Se configura con un archivo YAML
• Gratuita para proyectos de código abierto
• Precio para proyectos comerciales: entre 69 y 489 dólares/mes
• De código abierto (licencia MIT)

2.3 Bamboo

Bamboo de Atlassian es compatible con otras muchas aplicaciones (fuente:


https://www.atlassian.com/software/bamboo/features)

La compañía Atlassian, que gestiona también el servicio de alojamiento de archivos


Bitbucket, ofrece desde el año 2007 la herramienta de integración continua Bamboo.
Esta herramienta no solo sirve de ayuda en la integración continua, sino también para
funciones de despliegue y gestión de lanzamientos. Funciona a través de una interfaz
web.

• Escrito en Java
• Multiplataforma
• Fácil integración de otros productos Atlassian
• Gran cantidad de addons
• Realización de varias pruebas al mismo tiempo
• Interfaz web y API REST
• Gratuita para proyectos de código libre, ONG y centros escolares
• De lo contrario, pago único de entre 10 y 126 500 dólares, dependiendo del
número de servidores utilizados

2.4 GitLab CI

Gracias a la IC y la EC, GitLab ofrece un desarrollo de software sin interrupciones (fuente:


https://about.gitlab.com/features/gitlab-ci-cd/)

GitLab CI forma parte del conocido sistema de control de versiones GitLab. Además
de integración continua, GitLab ofrece despliegue y entrega continua. Al igual que con
Travis CI, la configuración de GitLab CI se lleva a cabo con un archivo YAML. Por lo
demás, su utilización es sencilla.

• Forma parte de GitLab


• Programado en Ruby y Go
• Configuración con un archivo YAML
• Asiste también en la entrega y el despliegue continuo
• Open Core
• Alojamiento propio o en la nube
• Versión gratuita con pocas funciones
• Precio para otras versiones, entre 4 y 99 dólares/mes por usuario.

2.5 CircleCI
La herramienta de integración continua CircleCI funciona tanto con GitHub como
con Bitbucket.
En las fases de prueba, pueden emplearse tanto contenedores como máquinas
virtuales. CircleCI confiere mucha importancia a la ejecución de procesos de desarrollo
sin interferencias, por lo que arroja de forma automática builds compatibles con otros
entornos.

• Configuración con un archivo YAML


• Soporta también el despliegue continuo
• Alojamiento propio o en la nube
• Se ejecuta en contenedores Docker, máquinas virtuales Linux y MacOS
• Gratuita para un contenedor
• De otro modo, entre 50 y 3 150 dólares al mes

2.6 CruiseControl

Esta consagrada herramienta sigue sorprendiendo a desarrolladores de todo el mundo (fuente:


http://cruisecontrol.sourceforge.net/overview.html)

CruiseControl se encuentra entre las aplicaciones más antiguas de integración


continua. La herramienta se lanzó al mercado en 2001 y ha continuado desarrollándose
desde entonces entre otros, por Martin Fowler, pionero en el ámbito de la integración
continua. Junto con un claro cuadro de mandos, los desarrolladores tienen a su
disposición numerosos plugins que les facilitarán el trabajo.

• Escrito en Java
• Multiplataforma
• Cuadro de mandos basado en web
• Versiones para Ruby (CruiseControl.rb) y .NET (CruiseControl.NET)
• De código abierto (licencia BSD)
• Gratuita

2.7 Codeship

Codeship ofrece a los desarrolladores opciones sencillas en la nube que ayudan a acelerar el trabajo (fuente:
https://codeship.com/)

La herramienta de integración continua Codeship pertenece a CloudBee, que también


cuenta con Jenkins en su catálogo. El programa está disponible en dos versiones: La
versión básica, con una interfaz web sencilla, y la versión profesional, configurada con
archivos en el repositorio. Aquellos que deseen trabajar con un contenedor Docker,
tendrán que hacerse con la versión profesional.

• Interfaz web en la versión básica


• Archivos de configuración en el repositorio en la versión profesional
• Asistencia Docker en la versión profesional
• Gratuita para 100 compilaciones al mes en una pipeline de prueba
• Precio entre 75 y 1500 dólares/mes
2.8 TeamCity

TeamCity promete una rápida familiarización con la integración continua (fuente:


https://www.jetbrains.com/teamcity/)

El software TeamCity destaca sobre todo por sus “gated commits”. Con ellos, la
herramienta comprueba los cambios en el código antes de integrarlos a la línea
principal. Únicamente cuando el código está libre de errores, pasa a formar parte del
código base para todo el equipo. TeamCity lleva a cabo las pruebas automáticamente
en un segundo plano, de modo que el desarrollador puede continuar trabajando.

• Escrito en Java
• Multiplataforma
• Gated Commits
• Gratuito para 100 builds con 3 agentes de compilación
• Pago único de entre 299 euros y 21 999 euros
• Con 50 % de descuento para startups y gratuita para proyectos de código abierto

2.9 Tabla comparativa de herramientas de integración continua

Todas las herramientas de integración continua presentan ventajas e inconvenientes.


Con la ayuda de la siguiente tabla, podrás reconocer de un vistazo cuál de ellas resulta
más adecuada para ti. De este modo, podrás comprobar por ejemplo si el servicio cuenta
también con entrega continua o si ofrece alojamiento en la nube.
Capitulo III
3. Como construir un entorno de Integración Continua con Jenkins y
Docker

En esta entrada se explicará cómo aprovechar la tecnología Docker para construir un


entorno de Integración Continua que monitorice tu repositorio de código fuente, construya
tu producto, pase los tests, audite el código de forma automática con SonarQube y deje los
binarios listos para descargar.

En un escenario clásico tendríamos unas cuantas máquinas virtuales encargadas de


hacer todas esas tareas, pero con Docker podemos ir a un escenario donde repartir las
tareas en diferentes contenedores en lugar de máquinas virtuales, resultando un entorno
mucho más ligero, más fácil de escalar y más sencillo de portar.

Nuestro entorno de Integración Continua estará compuesto por:

• Un contenedor «master» de Jenkins, que orquestará las tareas


• Uno o varios contenedores «agentes» (también conocidos como «esclavos»), que
ejecutarán las tareas
• Un analizador automático de código en un contenedor SonarQube

Para este estudio se utilizara Docker Toolbox para Windows con la consola Docker
QuickStart Terminal, aunque los comandos son los mismos si usas Docker para otras
plataformas.

3. 1 Un master para dominarlos a todos

Si ya has utilizado alguna vez Jenkins, sabrás que normalmente hay un


nodo máster encargado de guardar la configuración y lanzar las tareas o «jobs«, y varios
nodos «agentes» (también conocidos como «esclavos«) que son los que ejecutan las tareas.
Pues vamos a ello…. en la consola donde tengas Docker instalado ejecuta:

docker pull jenkinsci/jenkins:lts

Esto descargará la imagen con la última versión de Jenkins LTS (Long Time Support)

Arrancamos el contenedor:

docker run --name jenkins_master -p 8080:8080 -p 50000:50000 -v


jenkins_home:/var/jenkins_home jenkinsci/jenkins:lts
Un poco de explicación de este comando:

• Ponle un nombre al contenedor: jenkins_master


• Publica los puertos 8080 y 50000 para que sean accesibles
• Monta un volumen en la carpeta var/jenkins_home del HOST (externa al
contenedor), donde se guardarán la configuración y los resultados de las tareas. De esta
forma si el contenedor se destruye no se perderá la información.
Si ahora accedes con un navegador a http://IP_DEL_HOST:8080, te saldrá este bonito
recibimiento:

La contraseña inicial será visible en la consola o en el


archivo /var/jenkins_home/secrets/initialAdminPassword

Introduce la clave y continúa con el proceso de configuración:


Por ahora deja la opción por defecto de «Install suggested plugin«.

Sólo falta crear un usuario administrador:

Ahora deberías ver la pantalla de bienvenida:


3.2 Para crear: «Hello World»

Para hacer una prueba rápida del funcionamiento de Jenkins, ve a «New item»para
crear un nuevo job:

En la sección «Build«, haz click en «Add build step» y selecciona «Execute Shell»

Escribe:

echo Hello World


Y ahora «Save» y «Build Now«. Tras unos segundos aparecerá el número de build:

Haz click en el número y después en «Console output»

3.3 Agentes, esclavos y nodos


En el apartado anterior arrancaste un master de Jenkins que, además, es capaz de
ejecutar tareas. Aunque esto está bien, no es un escenario real. En los sistemas de
Integración Continua lo habitual es tener un master (o varios en sistemas muy grandes) que
coordina tareas y varios agentes que se encargan de ejecutarlas.

Es habitual encontrar la palabra esclavos (slaves) o nodos (nodes) para referirse a los
agentes. En Jenkins estos conceptos son sinónimos, yo me referiré a ellos como agentes,
puedes consultar las últimas versiones de la documentación para más información.

Conectar un agente se hace en dos partes: se da de alta en el sistema y después se


conecta mediante algún protocolo admitido como SSH o JNLP u otros.

Comenzamos, haz click en «Manage Jenkins» y «New Node» :


Ponle un nombre, por ejemplo «agent1» y OK

En el siguiente paso asegúrate que:

• Remote root directory: /home/jenkins

• Launch method: Launch agent via Java Web Start. Hay otros métodos para

conectarse como SSH, pero para este ejemplo utilizaremos JNLP

Y «Save»
Con estos pasos le estás diciendo a Jenkins que vas a conectar un nuevo agente. Necesitas
un dato importante, un token secreto para conectarte que está indicado después del
parámetro -secret:

Seguimos, el repositorio DockerHub de la gente de Jenkins, nos ofrece una imagen ya


configurada para hacer de agente y que ya lleva OpenJDK instalado para poder comenzar a
trabajar con proyectos Java.
Este comando descargará la imagen:

docker pull jenkinsci/jnlp-slave

Arranca el contenedor:

docker run --name jenkins_agent1 jenkinsci/jnlp-slave -url http://HOST_IP:8080


TUSECRETOabcdef0123456789 agent1

• Nombra al contenedor como: jenkins_agent1


• En HOST_IP escribe la dirección de tu servidor Jenkins, igual que la escribes en el
navegador
• El siguiente parámetro es el token secreto que te proporcionó Jenkins en el paso
anterior
• El último parámetro es el nombre del agente con el que lo diste de alta. En tu caso
agent1
Si todo va bien estarás viendo algo así:
En el panel de control de Jenkins verás como el agente se ha conectado y el número de
«ejecutores» (executors) que tiene. Por ahora estará «Idle», es decir sin ejecutar nada.

Hasta ahora no hemos construido nada útil, pero ya tenemos un master y un agente
listo para empezar a trabajar, así que vamos a construir un proyecto real. Para este tutorial
he elegido el proyecto FitNesse, que es una herramienta de colaboración tipo wiki y un
framework de test de aceptación open source escrito en Java y se construye con gradle.
El código fuente original de está en https://github.com/unclebob/fitnesse.

Para hacer este ejemplo te recomiendo que hagas un fork


de https://github.com/jaruzafa/fitnesse_CI_DEMO, que es un clon del original (con
algunos cambios que veremos más adelante) y que mantengo congelado para este tutorial,
así si el proyecto original cambia sustancialmente en el futuro, los pasos de este tutorial te
seguirán funcionando.

En el panel de Jenkins ve a «New Job» y elige «Freestyle Project«, ponle un nombre


original como «FitNesse». Te llevará a la pantalla de configuración.
En el apartado «Source Code Management» le indicas el repositorio donde tienes el código
fuente de tu proyecto.

• Repositories: En mi caso le he puesto:


https://github.com/jaruzafa/fitnesse_CI_DEMO pero si haces un clon, pon la
dirección de tu repositorio

• Branches to build: */demo


• Aunque no es estrictamente necesario para este ejemplo , en mis proyectos suelo
añadirle un «Additional behaviour» -> «Clean before checkout». De esta forma me
aseguro de que no quedan «restos» de compilaciones o tests previos y siempre
construyo el producto tal y como viene de su repositorio, aunque tarde un poco más.

Vamos al apartado «Build Triggers«. Aquí se determina qué evento «dispara» la build.
• Selecciona «Poll SCM» y escribe H/5 * * * *
• Esto le indica a Jenkins que «pregunte» tu repositorio cada 5 minutos si hay
cambios. Si los hay, dispara el job.

En el apartado «Build» es donde todo ocurre.


• Haz click en «Add build step» y selecciona Invoke Gradle Script
• Selecciona «Use Gradle Wrapper» para este proyecto.
• En el apartado «Tasks» escribe test y standaloneJar.
Esto ejecutará los tests unitarios y generará los jar del proyecto.
Y por último, para poder ver los resultados de los tests y que Jenkins guarde los jar que se
han generado en la build, añade dos «Post-build actions «:

• Archive the artifacts


• Files to archive: build/libs/*.jar
• Esto guardará los jar en Jenkins. En sistemas más grandes los binarios se suelen
almacenar en repositorios dedicados para ello (como Nexus, Artifactory, etc.) pero
para este ejemplo está bien.
• Publish JUnit test result report
• Test report XMLs: **/test-results/**/*.xml
• Aquí le estás diciendo a Jenkins dónde encontrar los resultados de los tests unitarios

Puedes lanzar el job de dos formas:

• Manual: Haz click en el botón «Build Now«


• Automática: Cómo recordarás, le hemos dicho a Jenkins que mire cada 5 minutos en
el repositorio Git por si hay cambios. Haz un commit en el repositorio y espera a que se
dispare solo. Recuerda que el commit deberás hacerlo en la misma rama que indicaste
en el apartado «Source Code Configuration» (en mi caso es la rama «demo»). Este es
una forma común de arrancar un job en un entorno de Integración Continua, pero hay
otras.

En cuanto arranque el job verás esto:

Espera unos minutos y en cuanto acabe tendrás algo así:

En la columna de la izquierda tendrás el histórico de builds. En el centro enlaces a los jar


generados (¡que puedes descargar!) y a los resultados de los tests unitarios. Cuando
ejecutes varias veces el job, a la derecha te saldrá una gráfica con la tendencia de los
resultados de los tests. Está fuera del alcance de este post explicar cada una de las opciones,
así que te animo a que explores y le eches un vistazo a la documentación de Jenkins.
3.4 Inspeccionando el código

En sistemas de Integración Continua reales, además de compilar y ejecutar tests, es


habitual realizar auditorias automáticas de código, así como mediciones de cobertura de
código. En este ejemplo te mostraré como conectar SonarQube (una herramienta open
source muy popular) al sistema de Integración Continua. Por supuesto seguiremos
utilizando Docker .
La gente de SonarQube amablemente ha preparado una serie de imágenes listas
para usar, así que vamos a ello. Descarga la imagen con:
docker pull sonarqube:lts

Y arranca con:

docker run --name sonarqube -d -p 9000:9000 -p 9092:9092 -v


sonarqube_home:/opt/sonarqube/data sonarqube:lts

Un poquito de explicación de este último comando:

• Nombra el contenedor como sonarqube


• -d: Ejecuta el contenedor en modo «daemon»
• -p 9000:9000 -p 9092:9092: Publica los puertos 9000 y 9002
• -v sonarqube_home:/opt/sonarqube/data: Monta un volumen donde guardará los
datos fuera del contenedor. Esto es necesario ya que si el contenedor se destruyera
perderías toda la información
Vamos a asegurarnos de que SonarQube está levantado y le vas a instalar el plugin de Java.
Con tu navegador ve a http://HOST_IP:9000 deberías ver:

En el enlace de arriba a la derecha haz click en «Log In«, el usuario y contraseña por defecto
son admin / admin. Ahora ve a «Administration» -> «System» -> «Update Center«->
«Available» y busca «Java» . Instalas el plugin y se reiniciará el servicio,
Ya tenemos el contenedor con SonarQube levantado y configurado con el plugin de Java.
Ahora hay que decirle a Jenkins dónde está. Por defecto Jenkins no viene con el plugin de
SonarQube instalado, así que vamos a instalarlo.

Ve al panel de control de Jenkins en http://HOST_IP:8080, pincha «Manage Jenkins» y haz


click en «Manage Plugins»

Ahora ve a la pestaña de «Available» y busca «SonarQube Scanner for Jenkins» y «Install»

Con el plugin de SonarQube ya instalado, toca decirle donde está tu servidor Sonar y que
Scanner vas a usar. Así que ve a «Manage Jenkins» y «Configure System«. Busca el apartado
SonarQube Servers y haz click en «Add SonarQube«. Basta con rellenar los
campos Name (dale un nombre descriptivo) y Server URLque será http://HOST_IP:9000. Te
adjunto una captura de mi configuración:
Sólo falta decirle qué Scanner vas a usar. Esto se hace vía «Manage Jenkins» y «Global tool
configuration«. busca el apartado «SonarQube Scanner» y haz click en «SonarQube
Scanner installations» y «Add SonarQube Scanner» . Escribe un nombre descriptivo, y para
que Jenkins se encargue de instalar el software necesario marca «Install automatically» .
Esta es una de las cosas que más me gustan de Jenkins, la posibilidad de dejar que se
encargue de instalar las herramientas cuando las necesita, ya que descarga mucho trabajo
del mantenimiento de los nodos agente.

Con esto Jenkins ya sabe dónde tenemos SonarQube y que Scanner vamos a usar,
pero nuestro job todavía no.

Vamos a continuar con el ejemplo del apartado anterior de FitNesse. Para poder
hacer el análisis del código y obtener la cobertura de los test unitarios tienes que hacer dos
cosas: preparar el archivo project-sonar.properties y activar el plugin JaCoCo
en build.gradle para tener la información de cobertura de código.
En el archivo build.gradle añade esta línea después del bloque plugins:
apply plugin: "jacoco"

Esto prepara el proyecto para guardar la información de cobertura al ejecutar los tests.

Además, SonarQube necesita saber algunas cosas de tu proyecto. Crea un archivo


llamado project-sonar.properties con este contenido:
sonar.projectKey=my:Fitnesse
sonar.projectName=Fitnesse
sonar.projectVersion=1.0
sonar.sources=src
sonar.exclusions=**/*.min.js,src/**/bootstrap.js,src/**/codemirror.js,src/**/jquery.tagsinp
ut.js
sonar.tests=test
sonar.java.source=1.7
sonar.java.binaries=build/classes
sonar.java.libraries=lib
sonar.jacoco.reportPath=build/jacoco/test.exec

El significado de cada campo lo puedes encontrar en la documentación de SonarQube, pero


básicamente le estamos indicando donde encontrar los fuentes, algunas exclusiones, dónde
se generan los binarios y dónde está la información de cobertura.
Sólo falta decirle al job que vamos a hacer un análisis con SonarQube. Ve al job que has
creado en el apartado anterior y haz click en «Configure«. Ve a la sección «Build» y «Add
Build Step» y añade «Execute SonarQube Scanner«.

Guarda la configuración y dale a «Build Now» para probar que todo está bien. En unos
minutos deberías ver:
En los resultados del job de FitNesse verás un nuevo enlace a los resultados del análisis de
código y cobertura de SonarQube. Siguiendo el enlace te llevará a la página con los
resultados del proyecto:

Acabamos de construir un entorno de Integración Continua con un proyecto real. Si no


conoces SonarQube te animo a que te leas la documentación y explores las posibilidades
que te ofrece.

3.5 Apagando y encendiendo


Docker proporciona comandos para controlar el ciclo de vida de los contenedores. Si

no has trabajado antes con Docker estos son los que necesitas para este tutorial:

Lista los contenedores que están actualmente en ejecución:


docker ps

Lista todos los contenedores, incluso los que están parados:


docker ps -a

Detiene el contenedor especificado. Puedes pasarle el id del contenedor o por nombre. Si le

pasas el id, puedes indicarle sólo los 3 o 4 primeros carácteres en lugar de todo el «churro».
docker stop identificador o nombre

Por ejemplo:
docker stop sonarqube
docker stop ab12

Arranca el contenedor especificado, anteriormente lo habrás detenido con un docker stop.


docker start identificador o nombre.

4. Conclusiones
• La Integración Continua nos permite detectar de manera temprana, errores que
son generados por algún integrante del equipo de desarrollo, cada cambio que un
desarrollador realice en un repositorio compartido será descargado, compilado,
testeado (en base a pruebas unitarias y pruebas de aceptación) por el servidor de
integración continua.

• Al tener un sistema que verifica las integraciones frecuentes, se dedica menos


tiempo a investigar donde están los fallos y podemos dedicar más tiempo los que
más nos gusta que es programar.

• La Integración continua es barata, sino la aplicas el tiempo entre integraciones es


mucho más largo y esto dificulta encontrar y solucionar problemas, lo que lleva a
un coste mayor.

• Al estar las pruebas automatizadas lo máximo posible dedicamos menos tiempo a


depurar y más a añadir características.

• Permite entregar software más rápido, al estar validando constantemente, somos


capaces de entregar release más frecuentemente.
5. Bibliografía

• Extreme Programming: A Humanistic Discipline of Software Development».

• Beck, Kent (1999). Extreme Programming Explained. ISBN 978-0-201-61641-5.

• «A Brief History of DevOps, Part III: Automated Testing and Continuous


Integration». CircleCI. 1 de febrero de 2018. Consultado el 19 de mayo de 2018.

• Beck, Kent (28 March 1998). "Extreme Programming: A Humanistic Discipline of


Software Development". Fundamental Approaches to Software Engineering: First
International Conference, FASE'98, Held as Part of the Joint European Conferences
on Theory and Practice of Software, ETAPS'98, Lisbon, Portugal, 28 March – 4 April
1998, Proceedings, Volume 1. Lisbon: Springer. p. 4. ISBN 9783540643036.

• Booch, Grady (1991). Object Oriented Design: With Applications. Benjamin


Cummings. p. 209. ISBN 9780805300918. Retrieved 18 August 2014.

Anda mungkin juga menyukai