{"id":2139,"date":"2016-10-04T10:50:21","date_gmt":"2016-10-04T08:50:21","guid":{"rendered":"https:\/\/inlab.fib.upc.edu\/?p=2139"},"modified":"2016-10-04T10:50:21","modified_gmt":"2016-10-04T08:50:21","slug":"aplicacion-de-sistemas-de-integracion-continua","status":"publish","type":"post","link":"https:\/\/inlab.fib.upc.edu\/es\/uncategorized-ca\/aplicacion-de-sistemas-de-integracion-continua","title":{"rendered":"Aplicaci\u00f3n de sistemas de integraci\u00f3n continua"},"content":{"rendered":"<p>\u00bfProblemas en el momento de unir grandes bloques de c\u00f3digo de diversos desarrolladores? \u00bfEl equipo de trabajo no est\u00e1 coordinado y se solapan algunas tareas? \u00bfDedicamos el tiempo suficiente a revisar el funcionamiento de nuestro c\u00f3digo? \u00bfO nos enteramos de los errores a trav\u00e9s de las quejas de los usuarios? \u00bfNos topamos con m\u00e1s dificultades de las que desear\u00edamos cada vez que queremos presentar nuestro software al usuario final? Si alguna de las respuestas a las preguntas anteriores es s\u00ed, este art\u00edculo ser\u00e1 de tu inter\u00e9s.<\/p>\n<p>Para el desarrollo de proyectos de software, en inLab seguimos el ciclo de desarrollo por iteraciones (<em>sprints<\/em>) o incremental basado en <a href=\"https:\/\/proyectosagiles.org\/que-es-scrum\/\" target=\"_blank\" rel=\"noopener\">Scrum<\/a>. Con este m\u00e9todo se divide temporalmente, normalmente en periodos de dos o tres semanas, el desarrollo de las funcionalidades requeridas por el cliente pudiendo implementar, comprobar, desplegar y mostrar al cliente cada una de ellas con independencia de las otras beneficiando as\u00ed a ambas partes.<\/p>\n<p>Gracias a esta divisi\u00f3n del bloque de funcionalidades, el equipo de desarrollo puede centrarse \u00fanica y exclusivamente en la misma fase de trabajo, si el cliente cambia los requisitos s\u00f3lo afecta a la iteraci\u00f3n actual y una mala implementaci\u00f3n de las funcionalidades no interfiere con el trabajo realizado en anteriores iteraciones.<\/p>\n<p>Este m\u00e9todo de desarrollo, se adapta con resultados muy atractivos a algunas de las pr\u00e1cticas adoptadas del <a href=\"http:\/\/www.extremeprogramming.org\/\" target=\"_blank\" rel=\"noopener\"><em>extreme programming<\/em><\/a> que utilizamos en inLab como la <a href=\"http:\/\/www.martinfowler.com\/articles\/continuousIntegration.html\" target=\"_blank\" rel=\"noopener\">integraci\u00f3n continua<\/a>. En pocas palabras, \u00e9ste modelo de trabajo pretende que el equipo de desarrollo integre su c\u00f3digo diariamente, que dicho c\u00f3digo pase una serie de pruebas predefinidas por los programadores para verificar su correcto funcionamiento y que el despliegue del producto est\u00e9 disponible en cualquier momento ya sea en un sistema de pre-producci\u00f3n o incluso en uno de producci\u00f3n.<\/p>\n<p><em>\u00abIntegration is primarily about communication. Integration allows developers to tell other developers about the changes they have made. Frequent communication allows people to know quickly as changes develop.\u00bb<\/em><\/p>\n<p class=\"rteright\">&#8211; Martin Fowler, 1 May 2006, Continuous Integration<\/p>\n<p>En el d\u00eda a d\u00eda, antes de empezar a programar, cada desarrollador actualiza su entorno bajando los \u00faltimos cambios del repositorio de c\u00f3digo compartido, si existe cualquier conflicto debe resolverlo y a partir de aqu\u00ed puede empezar a dise\u00f1ar una de las nuevas funcionalidades. Para ello, utilizamos <a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\" target=\"_blank\" rel=\"noopener\">TDD<\/a>, otra de las pr\u00e1cticas del <em>extreme programming<\/em> preparando las pruebas que validar\u00e1n el comportamiento de dichas funcionalidades, implementando la funcionalidad y comprobando que los test definidos anteriormente se ejecutan correctamente. Una vez terminada la funcionalidad, el desarrollador es libre de enviar su aportaci\u00f3n al repositorio antes de repetir el mismo proceso para otra funcionalidad. De esta forma, cada d\u00eda un s\u00f3lo desarrollador realiza varios <em>commits<\/em> con peque\u00f1os cambios, facilitando la detecci\u00f3n de errores y la comprensi\u00f3n de los cambios para otros miembros del equipo. Antes de terminar la jornada el desarrollador tiene que compartir sus cambios, para ello antes tiene que descargarse las aportaciones de sus compa\u00f1eros, resolver posibles conflictos, verificar que todos los test funcionan y finalmente enviar sus cambios al repositorio.<\/p>\n<p>Es en este flujo de trabajo donde entran en juego los sistemas de integraci\u00f3n continua, automatizando y facilitando algunas de estas tareas desde la construcci\u00f3n del proyecto hasta el despliegue del mismo.<\/p>\n<p>Los sistemas de integraci\u00f3n continua son entornos que pretenden gestionar estos procesos de forma aut\u00f3noma liberando as\u00ed a los programadores de estas labores. T\u00edpicamente detectan los cambios en el desarrollo de los proyectos, lanzan la bater\u00eda de test para controlar que el comportamiento del software es el deseado y despliegan en una m\u00e1quina de desarrollo todo el c\u00f3digo. No obstante, los procesos que acabamos de listar son tan s\u00f3lo algunos de una extensa colecci\u00f3n que nos facilitan algunos software de integraci\u00f3n continua.<\/p>\n<p>Las diversas tareas que ejecutan estos sistemas suelen representarse visualmente mediante tarjetas ordenadas que, en caso de funcionar lanzan la siguiente tarea y en caso de fallar pueden llegar a avisar al equipo de desarrollo para que revisen qu\u00e9 ha pasado. Incluso se puede llegar a configurar algunas tarjetas para que su ejecuci\u00f3n tenga que ser lanzada manualmente, podr\u00eda ser el caso de un despliegue del software a un entorno de producci\u00f3n, el cual no siempre nos interesar\u00e1 hacer.<\/p>\n<p class=\"rtecenter\"><img fetchpriority=\"high\" decoding=\"async\" class=\" size-full wp-image-2127\" alt=\"tareas sistemas integraci\u00f3n continua\" src=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/tarjetas.png\" width=\"571\" height=\"134\" srcset=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/tarjetas.png 571w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/tarjetas-300x70.png 300w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/tarjetas-370x87.png 370w\" sizes=\"(max-width: 571px) 100vw, 571px\" \/>\u200b<\/p>\n<p>Entre las ventajas que aporta la inclusi\u00f3n de estos sistemas en los proyectos encontramos la detecci\u00f3n de errores en cada iteraci\u00f3n del c\u00f3digo, la disponibilidad del proyecto construido en todo momento y la seguridad de tener la implantaci\u00f3n en el entorno de producci\u00f3n ya comprobada.<\/p>\n<p>Hay multitud de herramientas de integraci\u00f3n continua: <a href=\"https:\/\/jenkins.io\/\" target=\"_blank\" rel=\"noopener\">Jenkins<\/a>, <a href=\"http:\/\/www.eclipse.org\/hudson\/\" target=\"_blank\" rel=\"noopener\">Hudson<\/a>, <a href=\"https:\/\/www.atlassian.com\/software\/bamboo\" target=\"_blank\" rel=\"noopener\">Bamboo<\/a>, <a href=\"https:\/\/www.solanolabs.com\/\" target=\"_blank\" rel=\"noopener\">Solano<\/a>, <a href=\"http:\/\/cruisecontrol.sourceforge.net\/\" target=\"_blank\" rel=\"noopener\">CruiseControl<\/a>\u2026<\/p>\n<p>En inLab utilizamos este tipo de herramientas en diversos proyectos, tomaremos como ejemplo un proyecto de aplicaciones m\u00f3viles formado por una API, una aplicaci\u00f3n m\u00f3vil y una web de administraci\u00f3n gestionados por Jenkins.<\/p>\n<p class=\"rtecenter\"><img decoding=\"async\" class=\" size-full wp-image-2130\" alt=\"ejemplo proyecto\" src=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/ejemplo_proyecto.png\" width=\"609\" height=\"188\" srcset=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/ejemplo_proyecto.png 609w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/ejemplo_proyecto-300x93.png 300w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/ejemplo_proyecto-370x114.png 370w\" sizes=\"(max-width: 609px) 100vw, 609px\" \/>\u200b<\/p>\n<p>Cada cierto tiempo Jenkins revisa si existe alg\u00fan cambio en la rama de desarrollo del repositorio y si es as\u00ed inicia el flujo de trabajo. Este per\u00edodo de tiempo es parametrizable, tambi\u00e9n se puede lanzar manualmente.<\/p>\n<p>Una vez iniciado el flujo, la primera tarjeta trae la \u00faltima versi\u00f3n del c\u00f3digo, construye el proyecto descargando sus dependencias y preparando el espacio de trabajo para la ejecuci\u00f3n de las siguientes tarjetas.<\/p>\n<p>Una vez el proyecto est\u00e1 listo, se inician dos tarjetas en paralelo, son las de ejecuci\u00f3n de test unitarios de la API y la de test de la aplicaci\u00f3n m\u00f3vil. Al terminar los test unitarios de la API, una nueva tarjeta se encarga de lanzar los test de integraci\u00f3n migrando previamente los \u00faltimos cambios producidos en la base de datos.<\/p>\n<p>Ejecutando este tipo de pruebas en un sistema de integraci\u00f3n continua como Jenkins conseguimos validar el buen funcionamiento del proyecto en un entorno independiente del nuestro.<\/p>\n<p>Si las tarjetas de test de la API tienen \u00e9xito, la siguiente tarjeta desplegar\u00e1 la API a la m\u00e1quina de pre-producci\u00f3n mientras otra tarjeta ejecuta los test de calidad de la API.<\/p>\n<p>En la tarjeta de calidad hemos configurado varios plugins que nos proporcionan informaci\u00f3n acerca del software que estamos desarrollando. Gracias a un plugin para Jenkins llamado <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Clover+PHP+Plugin\" target=\"_blank\" rel=\"noopener\">Clover PHP<\/a> en la tarjeta de calidad obtenemos m\u00e9tricas de la cantidad de c\u00f3digo cubierto por los test. <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/DRY+Plugin\" target=\"_blank\" rel=\"noopener\">DRY Plugin<\/a> nos genera una vista donde obtenemos informaci\u00f3n acerca de la posible duplicaci\u00f3n de c\u00f3digo en el proyecto. Otro plugin, <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/PMD+Warnings\" target=\"_blank\" rel=\"noopener\">PMD Warnings<\/a> nos muestra alertas sobre el mal funcionamiento o uso incorrecto de nuestro c\u00f3digo clasific\u00e1ndolas en distintos niveles de prioridad. Por \u00faltimo, <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/JDepend+Plugin\" target=\"_blank\" rel=\"noopener\">JDepend Plugin<\/a> ense\u00f1a las dependencias entre clases y posibles ciclos en el dise\u00f1o del software.<\/p>\n<div class=\"peuCentrat\"><img decoding=\"async\" class=\" size-full wp-image-2133\" alt=\"Clover PHP coverage report\" src=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/clover_coverage_report.png\" style=\"height: 320px; width: 600px;\" width=\"960\" height=\"512\" srcset=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/clover_coverage_report.png 960w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/clover_coverage_report-300x160.png 300w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/clover_coverage_report-768x410.png 768w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/clover_coverage_report-370x197.png 370w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/>Figura 1: Ejemplo de informe de cobertura de c\u00f3digo de Clover PHP<\/div>\n<p>&nbsp;<\/p>\n<div class=\"peuCentrat\"><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-2136\" alt=\"PMD Warnings warning\" src=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/pmd_warning.png\" style=\"width: 600px; height: 213px;\" width=\"703\" height=\"250\" srcset=\"https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/pmd_warning.png 703w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/pmd_warning-300x107.png 300w, https:\/\/inlab.fib.upc.edu\/wp-content\/uploads\/2016\/10\/pmd_warning-370x132.png 370w\" sizes=\"(max-width: 703px) 100vw, 703px\" \/>\u200bFigura 2: Ejemplo de alerta de PMD Warnings<\/div>\n<p>Una vez el despliegue en la m\u00e1quina de pre-producci\u00f3n est\u00e9 listo podremos lanzar manualmente la tarjeta de los test de carga. Estos permiten comprobar el correcto funcionamiento del c\u00f3digo en una m\u00e1quina que ser\u00e1 lo m\u00e1s parecida posible a la m\u00e1quina de producci\u00f3n.<\/p>\n<p>Cuando los test de calidad hayan acabado de forma satisfactoria, Jenkins nos permitir\u00e1 lanzar de forma manual el despliegue de la API en la m\u00e1quina de producci\u00f3n. Este proceso tiene que ser manual porque no siempre nos interesar\u00e1 reemplazar la API ya existente.<\/p>\n<p>Adem\u00e1s, como punto extra, existe una \u00faltima tarjeta que lanza el despliegue de la web de administraci\u00f3n. Este punto es posterior al lanzamiento de la API porque la web es dependiente de ella.<\/p>\n<p>Paralelamente, la compilaci\u00f3n de la versi\u00f3n de desarrollo de la aplicaci\u00f3n se realiza en un servidor externo y los ficheros generados son recuperados por Jenkins para subirlos a una web de uso interno. Todo este proceso se realiza en una \u00fanica tarjeta.<\/p>\n<p>Si la tarjeta anterior se ha ejecutado de forma correcta, Jenkins nos permitir\u00e1 lanzar exactamente el mismo proceso pero generando una versi\u00f3n firmada para producci\u00f3n y preparando los archivos APK y IPA listos para distribuir en Play Store para Android y en App Store para iOS.<\/p>\n<p>En caso de que cualquier tarjeta falle, a trav\u00e9s de un <a href=\"https:\/\/wiki.jenkins-ci.org\/display\/JENKINS\/Slack+Plugin\" target=\"_blank\" rel=\"noopener\">plugin<\/a> hemos configurado Jenkins para que nos notifique v\u00eda <a gref=\"https:\/\/slack.com\/\" target=\"_blank\" rel=\"noopener\">Slack<\/a> en un canal concreto. Adem\u00e1s, para algunos procesos que requieren cierto tiempo o se tratan de despliegues a producci\u00f3n Jenkins tambi\u00e9n nos avisar\u00e1 al finalizar.<\/p>\n<p>No debemos olvidar que este tipo de sistemas pretenden automatizar procesos pero no redimen al desarrollador de la programaci\u00f3n de pruebas ni de la configuraci\u00f3n de los despliegues de entornos de pre-producci\u00f3n y producci\u00f3n.<\/p>\n<p>Si despu\u00e9s de leer este art\u00edculo est\u00e1is pensando en introducir la integraci\u00f3n continua en alguno de vuestros proyectos os recomendamos <a href=\"http:\/\/www.martinfowler.com\/articles\/originalContinuousIntegration.html\" target=\"_blank\" rel=\"noopener\">esta lectura<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00bfProblemas en el momento de unir grandes bloques de c\u00f3digo de diversos desarrolladores? \u00bfEl equipo de trabajo no est\u00e1 coordinado y se solapan algunas tareas? \u00bfDedicamos el tiempo suficiente a revisar el funcionamiento de nuestro c\u00f3digo? \u00bfO nos enteramos de los errores a trav\u00e9s de las quejas de los usuarios? \u00bfNos topamos con m\u00e1s dificultades [&hellip;]<\/p>\n","protected":false},"author":594,"featured_media":2124,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"experteses":[27],"class_list":["post-2139","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized-ca","experteses-knowledgeyserviceengineering-es"],"acf":[],"_links":{"self":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/posts\/2139","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/users\/594"}],"replies":[{"embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/comments?post=2139"}],"version-history":[{"count":0,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/posts\/2139\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/media\/2124"}],"wp:attachment":[{"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/media?parent=2139"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/categories?post=2139"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/tags?post=2139"},{"taxonomy":"experteses","embeddable":true,"href":"https:\/\/inlab.fib.upc.edu\/es\/wp-json\/wp\/v2\/experteses?post=2139"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}