SlideShare uma empresa Scribd logo
1 de 22
Baixar para ler offline
DesplegandocódigoconPhing,
PHPUnit,CoderyJenkins
www.ladrupalera.com
@ladrupalera
JoséAntonioRodríguezBonilla
 
 
Índice de contenidos 
Introducción 
Consideraciones 
Configurando Github 
Realizando nuestra primera tarea 
Implementando Drupal Developer Plugin 
Integrando Phing 
Elaborando nuestro primer Test 
 
Referencias 
Web externas 
 
VP1.9 
1 / 20 
 
 
 
Manual de uso
Introducción
El objetivo de esta guía no es detallar los pasos para la instalación de las herramientas que
se comentan a continuación. Más bien nos centraremos en el flujo de despliegue y revisión
del código que generamos desde un entorno local hacia otro remoto, tomando como fuente
de datos un repositorio de datos (en este caso Github), pasando por la revisión y análisis de
dicho código mediante herramientas externas que nos ayudarán a garantizar unos mínimos
de calidad antes de realizar un despliegue.
Para ello, y antes de entrar en materia, daremos por supuesto que tenemos instalado
Jenkins en un servidor con los siguientes Plugins. No obstante, en lo sucesivo iremos
comentando en qué momento debemos instalar cada uno de los plugins:
● Drupal developer plugin
● Git client plugin
● Git plugin
● Github plugin
● Phing plugin
● XUnit plugin
Además de esto, deberemos tener instalados los siguientes servicios en nuestra máquina de
integración:
● PHPUnit
● Phing
● PHP (5.4)
● Git
Consideraciones
Lo que se pretende ofrecer en esta guía es una serie de pasos que garantice, mediante la
fusión de ramas a través de Github (Merge), la ejecución de una serie de procesos que
garantice que el código mergeado en una rama cumpla con los requisitos funcionales,
además de garantizar una sintaxis adecuada, antes de un despliegue, de forma que
podamos automatizar una serie de tareas que generalmente realizamos a mano. Para ello,
utilizaremos como herramienta motora Jenkins, encargada de centralizar todo el proceso de
revisión y garantía del código, asumiendo la responsabilidad de realizar un despliegue en
caso de éxito o bien, detener dicho despliegue y avisar a los responsables de los errores
cometidos.
Jenkins es un software de Integración continua open source escrito en Java. Está basado en
el proyecto Hudson y es, dependiendo de la visión, un fork del proyecto o simplemente un
cambio de nombre. Jenkins proporciona integración continua para el desarrollo de software.
Es un sistema corriendo en un servidor que es un contenedor de servlets, como Apache
Tomcat. Soporta herramientas de control de versiones como CVS, Subversion, Git, Mercurial,
 
VP1.9 
2 / 20 
 
 
 
Perforce y Clearcase y puede ejecutar proyectos basados en Apache Ant y Apache Maven,
así como scripts de shell y programas batch de Windows. El desarrollador principal es
Kohsuke Kawaguchi.
Y pasamos a la práctica directamente. Para ello, debemos configurar en primer lugar una
serie de tareas o jobs en Jenkins de forma lineal. Es decir, si la primera tarea no cumple con
los requisitos deseados, no pasaremos a la siguiente. Esto nos permite atomizar los
procesos involucrados en la revisión de un despliegue:
1. Análisis de comentarios, seguridad y sintaxis a través de Coder
2. Ejecución de tests unitarios
3. Despliegue en el entorno
Estas tareas se ejecutarán de forma secuencial, de manera que si una de ellas no cumple
con los requisitos deseados, el proceso se detendrá automáticamente notificando a las
partes implicadas de las incidencias producidas durante el despliegue.
Las condiciones previas que deberían darse antes de iniciar este proceso son las siguientes:
● Tener un entorno remoto versionado en Github apuntando a una rama, en este caso
‘Staging’
● Tener un entorno local versionado en nuestra máquina, a ser posible a través de un
Fork de la rama principal de Staging, de forma que tengamos la posibilidad de
solicitar integraciones en la rama principal. No obstante, este flujo es relativo y se
basa en el ejemplo real citado a continuación, pero las posibilidades en cuanto a
tests basados en haltonfail son prácticamente infinitas.
En el ejemplo que tratamos a continuación, el servidor Jenkins ha sido instalado en la misma
máquina donde integraremos el código a través de Github. No obstante, podría estar
perfectamente en una máquina remota y realizar un despliegue a través de SSH en un
servidor remoto. Si este fuera el caso, un error muy frecuente a tener en cuenta es el acceso
mediante el par de claves pública/privada del usuario Jenkins que ejecuta las peticiones en
el servidor remoto de despliegue, por lo que sería aconsejable realizar previamente una
conexión desde la consola del servidor Jenkins a la máquina remota con el usuario jenkins
(que instala el servidor por defecto) para comprobar que el acceso se realiza sin problemas
de autenticación. Además de esto, también es importante revisar los accesos mediante SSH
al repositorio Github donde tengamos alojado nuestro código de integración para
asegurarnos que el usuario jenkins puede acceder al mismo y realizar escrituras.
Configurando Github
Sabiendo esto, vamos a establecer el primer paso la llamada automática al trigger o
disparador de Jenkins en Github cuando se produce un Merge en una rama determinada.
Para ello, en nuestro repositorio principal (o de integración) deberemos acceder a la
configuración del repositorio mediante la pestaña ‘Settings’:
 
VP1.9 
3 / 20 
 
 
 
Después, debemos acceder a la pestaña ‘Webhooks & Services’:
En esta ventana, debemos acceder el servicio ‘Jenkins (Github Plugin)’:
Para configurar el servicio, nos solicitará un URL de acceso que utilizará para avisar a Jenkins
mediante una petición POST de que ha habido un merge en una rama. Para conocer esta
URL, debemos acceder a la configuración de Jenkins ‘Administrar Jenkins’, y acceder a la
‘Configuración del sistema’. Si hemos instalado el Github Plugin correctamente, podremos
ver la URL que debemos poner en su sección correspondiente:
NOTA​: Para ver la ruta habrá que hacer click en el icono de interrogación que aparece a la
derecha.
Una vez introducida esta URL en Github, éste nos permite realizar un test a través de un
botón de acción. No obstante, el ‘status’ de esta petición no se actualiza hasta que se realiza
una petición real a través de un Merge (al menos en los ejemplos realizados durante la
redacción de este documento), por lo que no debemos preocuparnos demasiado por este
asunto de momento.
 
VP1.9 
4 / 20 
 
 
 
Realizando nuestra primera tarea
Una vez hemos concluido la configuración de nuestro repositorio en Github y hemos
finalizado la instalación y configuración de Jenkins, vamos a pasar a configurar nuestra
primera tarea. Para ello, hacemos click en el primer item del bloque de la izquierda de
nuestro Jenkins ‘Nueva tarea’:
Una vez hacemos click en este item, crearemos un nuevo proyecto de estilo libre, y
pondremos un nombre de prueba para la tarea:
Una vez hacemos click en OK, pasamos a la siguiente pantalla, de la cual resaltamos los
aspectos más importantes a nivel de configuración:
 
VP1.9 
5 / 20 
 
 
 
Hemos destacado 3 opciones, aunque podemos realizar diferentes pruebas con el resto de
configuraciones:
● Github project: marcando este item, introduciremos la URL de nuestro repositorio.
● Dentro de ‘Configurar el origen del código fuente’, deberemos marcar la opción Git, y
aquí tendremos que introducir la URL del proyecto. En este caso, no introduciremos
la URL del repositorio, sino aquella utilizada para poder hacer un checkout del
mismo. Esto se puede hacer de dos maneras:
○ Mediante SSH: si lo hacemos así, tendremos que asegurarnos que el usuario
Jenkins de nuestra máquina tiene acceso al repositorio que queremos
configurar. Esto lo configuraremos en nuestro repositorio en Github otorgando
permisos a través de la clave pública del usuario.
○ Mediante HTTPS: con esta alternativa, Jenkins nos permitirá introducir las
credenciales del usuario con acceso al repositorio. De esta forma, dicho
usuario también tendría que tener acceso a este repositorio.
Podemos ver información de estas URL dentro de nuestro propio repositorio en Github tal y
como se muestra en la imagen a continuación:
En este aspecto, es importante resaltar un punto. Una vez hemos introducido las
credenciales o bien el acceso SSH en nuestro Jenkins, al pulsar el botón tabulador Jenkins
internamente comprobará el acceso al repositorio. Si existe algún problema con las
credenciales, en este momento dará un aviso notificando del error de acceso. Si este es el
caso, sería necesario comprobar que la comunicación entre nuestro usuario Jenkins y el
repositorio en Github se está produciendo (en el caso del acceso por SSH), o bien
comprobar que las credenciales introducidas (HTTPS) son correctas para el acceso a dicho
repositorio.
 
VP1.9 
6 / 20 
 
 
 
Una vez hemos asegurado que las credenciales son correctas, debemos especificar la rama
sobre la que queremos trabajar; en este caso hemos optado por la rama por defecto
(master).
El siguiente punto, ‘’Build when a change is pushed to Github” es que el que nos dará la
clave para automatizar la tarea que necesitemos. Esta opción indica a Jenkins que debe
ejecutar esta tarea cuando alguien realiza un push o un merge en la rama master que
hemos configurado, por lo tanto esta opción es vital para poner en marcha nuestro proceso
de despliegue automático.
Ahora, solo nos quedaría configurar la acción a realizar cuando se detecte un push en
nuestra rama master. En nuestro caso, debido a que nuestro servidor Jenkins está instalado
en el mismo servidor que nuestro entorno de integración, bastaría con añadir un nuevo paso
y ejecutar un comando a través de la shell:
En este caso, el comando básicamente cambia la ubicación del sistema al DOCUMENT
ROOT de nuestro servidor apache y realiza un PULL desde la rama master con el usuario
developer. Si tuviésemos nuestro entorno de integración en una máquina remota, bastaría
con realizar esta misma acción a través de SSH.
Con esta tarea ya tenemos nuestro primer despliegue automático a través de Jenkins.
Implementando Drupal Developer Plugin
Una vez que hemos visto cómo realizar un despliegue directo a través de Jenkins en un
entorno, vamos a añadir una nueva “capa de dificultad”. En este caso vamos a aplicar una
validación de código a través del plugin ‘Drupal Developer Plugin’, un módulo de Jenkins
que implementa una serie de validaciones de coding estandar y genera las métricas
necesarias para evaluar la calidad del código. Este ejemplo sólo sería válido si estamos
trabajando sobre un gestor de contenido basado en Drupal y queremos ser respetuosos con
los estándares de código.
Para ello, antes de crear una nueva tarea, vamos a añadir una nueva configuración a la tarea
que hemos creado anteriormente para que ésta solo se lleve a cabo siempre y cuando la
validación a través del plugin de Jenkins haya sido satisfactoria. En la configuración de
nuestra tarea de despliegue, marcamos la siguiente opción:
 
VP1.9 
7 / 20 
 
 
 
Además, vamos a desactivar la opción que activamos anteriormente ‘’Build when a change
is pushed to Github” para evitar que esta tarea se ejecute automáticamente, y solo lo haga
cuando la tarea que vamos a crear ahora haya cumplido todos los requisitos que
necesitamos.
En un ejemplo real, realmente esta configuración habría que hacerla después de haber
creado la tarea de prueba con el plugin ‘Drupal Developer Plugin’, de lo contrario Jenkins no
reconocería la prueba que hemos introducido en este ejemplo, pero la ponemos aquí para
darle continuidad a nuestro trabajo. Básicamente estamos especificando que solo se realice
un despliegue en nuestro entorno de integración siempre y cuando la tarea ‘Prueba Coder’
se haya ejecutado con éxito.
El siguiente paso sería, en primer lugar, instalar los plugins necesarios para Jenkins. Para
ello, desde la administración de Jenkins, accedemos a la sección de administración de
Plugins:
Una vez aquí, debemos buscar e instalar los siguientes plugins:
● Checkstyle Plug-in: este plugin es necesario para generar las métricas a través de
Jenkins y poder evaluar los resultados de los archivos generados.
● Drupal Developer: este plugin realiza una serie de análisis sobre nuestro código
fuente para evaluar su calidad, parámetros de seguridad, etc.
No vamos a centrarnos aquí en los pormenores de la instalación, ya que existe
documentación en la web oficial de Jenkins sobre estos plugins que describen bastante
bien su funcionamiento e instalación.
Pasamos pues directamente a crear una nueva con las mismas características que la
anterior (Proyecto libre), poniendo el nombre que consideremos oportuno, y pasamos a
describir la configuración de la tarea. Para el origen de datos (Github) y la URL del
 
VP1.9 
8 / 20 
 
 
 
repositorio, la configuración sería exactamente la misma, por lo que vamos a obviar de
nuevo la explicación de estos parámetros. Como en la anterior tarea desmarcamos
finalmente la opción ‘Build when a change is pushed to GitHub’, vamos a marcarla en esta
nueva tarea, de forma que sea ésta la que se ejecute en primer lugar, y en caso de éxito
pase a la tarea de despliegue como ya configuramos anteriormente. En este caso,
tendríamos que añadir un nuevo paso denominado ‘Review code on Drupal’:
En esta prueba, vamos a marcar todos los tests para asegurar la integridad del código en
todos sus niveles.
Los parámetros a configurar son los siguientes (es necesario pulsar el botón ‘Avanzado’ para
ver todas las opciones):
● Drupal root directory: DOCUMENT ROOT de nuestro gestor de contenidos
● Logs directory: directorio en el que el plugin generará los archivos XML con los
resultados de los tests
● Exclude these modules/themes: es importante configurar bien este apartado, ya que
para obtener unos resultados que luego nos sirvan realmente de interés,
ignoraremos todos aquellos directorios que no nos vayan a reportar información de
interés para nuestro propósito. En nuestro caso, hemos ignorado todas las carpetas
de módulos exceptuando la carpeta ‘custom’ o ‘main’ dentro de ‘sites/all/’, ya que es
en esta ubicación donde almacenaremos nuestros módulos personalizados, es decir,
aquellos que realmente nos interesa evaluar.
Una vez realizado este paso, debemos añadir una acción para poder evaluar los resultados
de los tests generados por el plugin. Para ello, hacemos click en ‘Añadir paso’ y agregamos
la opción ‘Public Checkstyle analysis results’ con los siguientes parámetros:
 
VP1.9 
9 / 20 
 
 
 
Pasamos a describir los parámetros más significativos:
● Checkstyle results: es la carpeta donde el plugin Drupal Developer genera los
archivos XML de los resultados de los tests realizados (hemos configurado esta
carpeta en el paso anterior). De esta forma, el plugin Checkstyle analizará todos los
archivos XML ubicados en este directorio para generar las métricas necesarias.
● Health priorities: desde aquí podemos priorizar las tareas que nos interesa analizar en
función de su prioridad
● Status thresholds (Totals): desde aquí podemos configurar el plugin para que su
resultado sea exitoso o fallido en función del número de incidencias detectadas y su
prioridad. Es aquí donde podemos refinar nuestra herramienta hasta encontrar la
flexibilidad/rigidez adecuada para el desarrollo de nuestro proyecto.
Una vez hemos guardado nuestra nueva tarea, es hora de ejecutarla a través de la pantalla
principal de Jenkins:
Es importante resaltar que, en el caso de que una tarea haya detectado alguna incidencia,
siempre nos resultará muy útil la información que Jenkins almacena para intentar detectar el
problema:
 
VP1.9 
10 / 20 
 
 
 
Suponiendo que nuestra tarea ha tenido éxito, bien considerando que ha pasado todos los
estándares de calidad necesarios, o bien asumiendo que se ha detectado alguna
inconsistencia en el código que ha impedido la ejecución de la siguiente tarea, si hacemos
click en el desplegable que aparece junto al nombre de nuestra tarea veremos una serie de
opciones, entre las que tenemos que elegir ‘Checkstyle Warnings’ (esta opción sólo
aparecerá si se ha configurado debidamente el plugin Checkstyle y se han generado los
reportes necesarios, en caso contrario sería conveniente revisar los logs para detectar los
problemas ocurridos):
 
VP1.9 
11 / 20 
 
 
 
Una vez hacemos click, nos apareceŕan por fin las métricas de nuestros resultados:
Podemos resaltar tres secciones interesantes:
● Files: aquí podremos ver un listado general de todos los archivos con problemas
detectados, junto al número de incidencias por archivo.
● Warnings: desglose de cada uno de las incidencias detectadas, junto a su prioridad.
Además, si hacemos click en alguno de estos errores, el plugin nos presenta el
interior del archivo remarcando el error detectado.
● Details: aquí podemos ver una descripción ampliada de los errores detectados
Integrando Phing
Para entrar en contexto, Phing es un port de Apache Ant destinado a la ejecución de tareas,
como puede ser la creación de carpetas, actualizaciones sobre un repositoiro, elaborar tests
de PHP Unit, etc. todo ello configurado en un archivo XML que después será ejecutado por
Jenkins. De esta forma, podemos generar un archivo XML con una serie de tests
personalizados que luego se integrarán en el flujo de despliegue de Jenkins. En nuestro
ejemplo, vamos a elaborar un test personalizado que ejecutaremos con PHP Unit, para
luego poder evaluar los resultados obtenidos del test y poder visualizar el resultado de esta
información con el ‘xUnit Plugin’ de Jenkins.
Bien, de antes ponernos a instalar plugins de Jenkins, es necesario instalar Phing en el
servidor de integración continua. La mejor manera de instalar Phing es a través de PEAR y
del canal PEAR de Phing, así pues hay que entrar en la terminal e introducir los siguientes
comandos:
pear channel-discover pear.phing.info
pear install --alldeps phing/phing
pear channel-discover pear.phing.info
 
VP1.9 
12 / 20 
 
 
 
Para asegurarnos que la instalación se ha realizado correctamente, podemos ejecutar el
siguiente comando en la consola del sistema:
phing -v
Lo siguiente que tendremos que hacer será crear un fichero en la raíz de nuestro proyecto
con el nombre build.xml y ahí escribir las tareas o targets. Si ejecutamos ‘phing’ en la
consola del sistema, éste intentará localizar el archivo build.xml en el directorio donde
hayamos ejecutado el comando. Si no encuentra este archivo, Phing te devuelve un error
indicando que no ha encontrado el archivo.
Lo bueno de las tareas automatizadas es que no son independientes unas de otras, sino que
desde una tarea puedes hacer una llamada a otra o incluso pueden existir tareas que
dependan de otras para que puedan ser ejecutadas. No es el objetivo de este manual
describir con más detalle la estructura del archivo XML ni su relación de dependencias,
aunque existe documentación bastante bien detallada sobre su configuración.
El siguiente paso, antes de entrar en el detalle de nuestro archivo XML, será instalar
PHPUnit, que es el framework que utilizaremos en este ejemplo para la ejecución de tests
unitarios sobre nuestro código. Antes de poder instanciar sus clases y programar la creación
de un test, es necesario instalar dicho framework en el sistema. Para ello, podemos
descargarlo de su repositorio oficial y ubicarlo dentro de nuestro sistema:
wget https://phar.phpunit.de/phpunit.phar
chmod +x phpunit.phar
sudo mv phpunit.phar /usr/local/bin/phpunit
phpunit --version
Si todo ha ido bien, el sistema nos reportará la versión de PHP Unit instalada. En nuestro
ejemplo, usaremos PHPUnit 4.8.24 junto a la versión 5.4.45 de PHP. Damos por hecho que
estamos ejecutando estos tests en una máquina con esta versión de PHP o superior
instalada.
Elaborando nuestro primer Test
Aunque no es objeto de este manual indagar en el uso de PHP Unit para la elaboración de
tests unitarios, diremos que PHPUnit se creó con idea de que cuanto antes se detecten los
errores en el código antes podrán ser corregidos. Este conocido framework para PHP nos
permite crear y ejecutar juegos de tests unitarios de manera sencilla. Como todos los
frameworks de pruebas unitarias, PHPUnit utiliza assertions para verificar que el
comportamiento de una unidad de código es el esperado. El objetivo de las pruebas
unitarias es aislar cada parte del programa y demostrar que las partes de forma individual
son correctas. Una prueba unitaria proporciona un contrato escrito que la pieza de código
debe satisfacer. Como resultado, las pruebas unitarias encuentran problemas en las fases
 
VP1.9 
13 / 20 
 
 
 
iniciales del desarrollo de software.
La idea detras de un assert es crear un objeto, ejecutar algunas funciones y después
comprobar su estado interno. Lo mejor es utilizar un ejemplo para ilustrarlo:
class TddTests extends PHPUnit_Framework_TestCase
{
public function test_tdd_help()
{
$this->assertEquals(1,1);
}
}
Como observamos en el código, básicamente lo que hemos hecho es crear una clase
TddTests heredada de la clase PHPUnit_Framework_TestCase. Es aquí dentro donde
podremos elaborar la programación de los tests. Existen infinidad de asserts proporcionados
por PHPUnit para la elaboración y ejecución de diferentes tipos de tests unitarios, aunque en
nuestro ejemplo utilizaremos un caso sencillo mediante el assert assertEquals. Este assert
compara dos cadenas de texto pasadas por argumento, y nos devolverá un resultado
TRUE/FALSE en función de si estas dos cadenas son iguales (TRUE) o diferentes (FALSE).
Nuestra función test_tdd_help que invoca al assert devolverá en cualquier caso un
resultado positivo, ya que los dos argumentos comparativos que le pasamos a nuestro
assert son iguales, no obstante, este ejemplo nos permite hacernos una idea del
funcionamiento básico de un assert con PHPUnit y el poder que obtenemos con la
ejecución de este tipo de tests.
Antes de entrar en la configuración del test unitario a través de Phing, vamos a asegurarnos
que nuestro test está bien programado y podemos ejecutarlo sin problemas a través de la
consola. De esta forma, si posteriormente nos encontramos con algún problema de
configuración, podremos aislar los problemas más fácilmente y detectar con más facilidad
el punto de fallo. Para ello, vamos a crear un archivo llamado TddTests.php ubicado, desde
el DOCUMENT ROOT de nuestra instalación de Drupal, en sites/all/modules/main/tdd con
el siguiente contenido. Aunque la ubicación o los nombres de los archivos pueden cambiar
en función de nuestras necesidades, hemos establecido esta ubicación únicamente para
ilustrar el ejemplo:
<?php
define('DRUPAL_ROOT', '/var/www');
require_once DRUPAL_ROOT . '/includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
class TddTests extends PHPUnit_Framework_TestCase
{
public function test_tdd_help()
{
$this->assertEquals(1,1);
 
VP1.9 
14 / 20 
 
 
 
}
}
?>
Las tres primeras líneas cargan el bootstrap de Drupal en caso de que tuviéramos que hacer
uso de su API. Aunque en este ejemplo no es estrictamente necesario, lo referenciamos por
si el lector quiere ampliar el código de este ejemplo apoyándose en la API de nuestro CMS.
El resto contiene la clase que hemos comentado anteriormente, integrando el assert
assertEquals que, en todo caso, nos devolverá un resultado positivo.
Ubicándonos de nuevo en el DOCUMENT ROOT de nuestro portal, ejecutamos en consola
el siguiente comando:
phpunit sites/all/modules/main/tdd/TddTests.php
Si todo ha ido bien, el framework nos devolverá la siguiente respuesta por pantalla:
PHPUnit 4.8.24 by Sebastian Bergmann and contributors.
.
Time: 392 ms, Memory: 42.75Mb
OK (1 test, 1 assertion)
En este caso, nos indica que se ha ejecutado un test con un assert, sin ningún error
encontrado. Vamos a realizar ahora una modificación en nuestro archivo PHP cambiando el
valor de uno de los dos argumentos, de forma que el assert nos devuelva un resultado
negativo. Volvemos a ejecutar nuestro comando por consola y ahora el resultado es:
PHPUnit 4.8.24 by Sebastian Bergmann and contributors.
Time: 392 ms, Memory: 42.75Mb
There was 1 failure:
1) TddTests::test_tdd_help
Failed asserting that 0 matches expected 1.
/var/www/sites/all/modules/main/tdd/TddTests.php:10
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
 
VP1.9 
15 / 20 
 
 
 
Como vemos en el ejemplo, en esta ocasión, además de informarnos de la ejecución
completa del test, nos indica que ha detectado un error, y sabiendo esto, únicamente nos
queda recuperar la información resultante del test para poder tratarla con alguna
herramienta (¿os imagináis cual?) y poder interactuar con el flujo de despliegue en función
de los resultados de los tests.
Volvemos pues al punto de partida con Phing. Ahora que ya sabemos para qué sirve PHP
Unit, y hemos comprobado su funcionamiento a través de un sencillo ejemplo a través de
un comando por consola, estamos preparados para integrar esta funcionalidad a nuestra
herramienta de integración continua, estableciendo su configuración con el apoyo de Phing.
Vamos pues a crear nuestro primer archivo build.xml en el raíz de nuestro plataforma, o bien
ubicarlo en algún directorio que sea accesible con posterioridad con Jenkins. El contenido
del archivo es el siguiente:
<?xml version="1.0"?>
<project name="MyApplication" default="build">
<property name="package" value="MyApplication" override="true" />
<target name="clean">
<delete dir="../reports"/>
</target>
<target name="prepare">
<mkdir dir="../reports/logs"/>
</target>
<target name="phpunit">
<phpunit printsummary="true" haltonfailure="true"
pharlocation="/usr/local/bin/phpunit">
<formatter todir="../reports/logs" type="xml"/>
<batchtest>
<fileset dir="../">
<include name="src/sites/all/modules/main/tdd/TddTests.php"/>
</fileset>
</batchtest>
<formatter type="xml" todir="../reports" outfile="logfile.xml"/>
</phpunit>
<phpunitreport infile="../reports/logfile.xml"
styledir="/usr/share/php/data/phing/etc"
format="frames"
todir="../reports"/>
</target>
<target name="build" depends="clean,prepare,phpunit"/>
</project>
Como hemos comentado anteriormente, no es objetivo de este manual entrar en
profundidad a explicar la creación y configuración de este archivo, no obstante, pasaremos
a comentar algunas etiquetas que resultan interesantes para entender su funcionamiento:
● delete dir y mkdir: le indicamos la ubicación de nuestro directorio de reportes para
que lo borre antes y lo vuelva a crear de comenzar la ejecución de nuestros tests
● phpunit: le indicamos la ruta de nuestro ejecutable PHP Unit
 
VP1.9 
16 / 20 
 
 
 
● formatter todir: indicamos donde deberán almacenarse nuestros reportes, y en qué
formato
Posteriormente indicamos la ruta de nuestro test, además de especificar el nombre de
nuestro archivo ‘logfile.xml’ con los resultados de nuestros tests.
Como ya hicimos anteriormente con PHPUnit, es hora de probar de forma aislada la
composición de nuestro archivo build.xml y comprobar que funciona correctamente antes
de integrarlo directamente en Jenkins, de esta forma nos aseguraremos que la estructura
de nuestro archivo XML es correcta, y como ya hemos asegurado antes que nuestro test
unitario funcionaba correctamente, ahora vamos a subir un nuevo peldaño incluyendo dicha
ejecución a través de Phing. Bastaría con ejecutar por consola el siguiente comando en el
mismo directorio que hemos creado nuestro archivo build.xml:
phing
Si nuestro archivo build.xml se encuentra en una ubicación diferente, podemos establecer la
ruta del archivo con el parámetro -f. Si todo ha ido correctamente, el resultado por consola
debería ser similar al siguiente:
Buildfile: /var/www/build.xml
MyApplication > clean:
[delete] Deleting directory /var/www/reports
MyApplication > prepare:
[mkdir] Created dir: /var/www/reports/logs
MyApplication > phpunit:
[phpunit] Total tests run: 1, Failures: 0, Errors: 0, Incomplete: 0, Skipped: 0, Time elapsed:
0.00471 s
MyApplication > build:
BUILD FINISHED
Total time: 0.1681 seconds
Bien. Llegados a este punto, creo que estamos suficientemente preparados para pasar la
ejecución de nuestro test a través de Jenkins, nuestra herramienta de integración continua.
Para ello, previamente hay que instalar los módulos ‘Phing Plugin’ para poder ejecutar
nuestras tareas a través del archivo build.xml y ‘xUnit Plugin’, que nos permitirá la
visualización de las métricas generadas por Phing. No vamos a entrar en más detalles sobre
la instalación de Plugins en Jenkins porque ya lo hemos comentado anteriormente. Así que
 
VP1.9 
17 / 20 
 
 
 
pasamos a crear directamente nuestra tarea, siguiendo los pasos anteriormente con el
mismo origen de datos, la misma URL de nuestro repositorio, etc. Nos centraremos en la
tarea específica que habrá que crear para ejecutar un script de Phing. Para ello, añadiremos
un nuevo paso denominado ‘Invoke Phing Targets’. Este paso debería aparecer
automáticamente si hemos instalado correctamente nuestros plugins:
El único aspecto aquí a remarcar es el campo ‘Phing Build File’. Simplemente tenemos que
indicar la ruta donde hemos creado nuestro archivo build.xml partiendo de nuestro
DOCUMENT ROOT. Otro aspecto muy importante a tener en cuenta aquí, y que suele ser la
causa de muchos problemas, es el origen de los datos. Esto quiere decir que para que
Jenkins pueda leer correctamente nuestro archivo build.xml, éste debe estar versionado en
nuestro repositorio, ya que, recordamos, éste es el origen de datos de nuestra tarea en
Jenkins, por lo tanto cualquier cambio que hayamos realizado en nuestro archivo build.xml
debe estar correctamente actualizado en nuestro repositorio para que Jenkins pueda
ejecutarlo.
El siguiente paso consiste, dentro de la misma tarea, en añadir una nueva acción ‘Publish
xUnit test result report’. Al igual que en el paso anterior, esta acción solo estará presente si
hemos instalado correctamente nuestros plugins. Pasamos a describir la configuración de
esta acción:
 
VP1.9 
18 / 20 
 
 
 
De esta acción vamos a comentar dos aspectos importantes:
● Ruta de los reportes: es importante recordar que esta ruta debe coincidir con la ruta
que hemos configurado en nuestro archivo build.xml de Phing, que es el encargado
de generar dichos reportes.
● Failed Tests: aunque es bastante obvio, me limitaré a comentar que aquí podemos
configurar la flexibilidad de nuestros avisos, de forma que podamos configurarlo de
tal modo que la tarea pueda resultar exitosa o fallida en función del número de tests
que se hayan ejecutado con éxito, etc.
Como comentamos en puntos anteriores, esta tarea puede ser configurada para que sea
ejecutada antes o después de otras tareas en nuestro proceso de despliegue, aunque una
vez conocida la práctica, creo que en este punto tenemos el conocimiento suficiente como
para decidir en qué momento necesitamos ejecutar este test.
Web externas
● Jenkins:​https://jenkins.io/
● Phing: ​https://www.phing.info/
● PHP Unit: ​https://phpunit.de/
● Github: https://github.com/
● xUnit Plugin: ​https://wiki.jenkins-ci.org/display/JENKINS/xUnit+Plugin
● Phing Plugin: ​https://wiki.jenkins-ci.org/display/JENKINS/Phing+Plugin
● Git Plugin: https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin
● Drupal Developer Plugin:
 
VP1.9 
19 / 20 
 
 
 
https://wiki.jenkins-ci.org/display/JENKINS/Drupal+Developer+Plugin
● Checkstyle Plugin: https://wiki.jenkins-ci.org/display/JENKINS/Checkstyle+Plugin
 
VP1.9 
20 / 20 
 
www.ladrupalera.com
@ladrupalera

Mais conteúdo relacionado

Mais procurados

Eclipse para novatos java
Eclipse para novatos javaEclipse para novatos java
Eclipse para novatos java
martaferrari
 

Mais procurados (14)

Test Unitarios y E2E front y Back
Test Unitarios y E2E front y BackTest Unitarios y E2E front y Back
Test Unitarios y E2E front y Back
 
Git: un enfoque práctico
Git: un enfoque prácticoGit: un enfoque práctico
Git: un enfoque práctico
 
spring-boot-es
spring-boot-esspring-boot-es
spring-boot-es
 
Java desde cero maven
Java desde cero mavenJava desde cero maven
Java desde cero maven
 
Control de versiones con Git y Github
Control de versiones con Git y GithubControl de versiones con Git y Github
Control de versiones con Git y Github
 
Git + Github - Betabeers Córdoba XII
Git + Github - Betabeers Córdoba XIIGit + Github - Betabeers Córdoba XII
Git + Github - Betabeers Córdoba XII
 
Introducción a git y git hub
Introducción a git y git hubIntroducción a git y git hub
Introducción a git y git hub
 
File
FileFile
File
 
Dependency Managers iOS
Dependency Managers iOSDependency Managers iOS
Dependency Managers iOS
 
Dependency Managers
Dependency ManagersDependency Managers
Dependency Managers
 
Guia01 control versiones
Guia01 control versionesGuia01 control versiones
Guia01 control versiones
 
Intro a GIT
Intro a GITIntro a GIT
Intro a GIT
 
Proyect Evenge. Event manager
Proyect Evenge. Event managerProyect Evenge. Event manager
Proyect Evenge. Event manager
 
Eclipse para novatos java
Eclipse para novatos javaEclipse para novatos java
Eclipse para novatos java
 

Destaque

Destaque (9)

Phing
PhingPhing
Phing
 
Building and Deploying PHP Apps Using phing
Building and Deploying PHP Apps Using phingBuilding and Deploying PHP Apps Using phing
Building and Deploying PHP Apps Using phing
 
Deploying PHP applications with Phing
Deploying PHP applications with PhingDeploying PHP applications with Phing
Deploying PHP applications with Phing
 
QA on Drupal projects - Drupal Dev Days Seville 2017
QA on Drupal projects - Drupal Dev Days Seville 2017QA on Drupal projects - Drupal Dev Days Seville 2017
QA on Drupal projects - Drupal Dev Days Seville 2017
 
Phing: Building with PHP
Phing: Building with PHPPhing: Building with PHP
Phing: Building with PHP
 
Ain't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to AutomationAin't Nobody Got Time For That: Intro to Automation
Ain't Nobody Got Time For That: Intro to Automation
 
PHP Cloud Deployment Toolkits
PHP Cloud Deployment ToolkitsPHP Cloud Deployment Toolkits
PHP Cloud Deployment Toolkits
 
Building and deploying PHP applications with Phing
Building and deploying PHP applications with PhingBuilding and deploying PHP applications with Phing
Building and deploying PHP applications with Phing
 
Responsive testing in Drupal - Drupal Developer Days
Responsive testing in Drupal - Drupal Developer DaysResponsive testing in Drupal - Drupal Developer Days
Responsive testing in Drupal - Drupal Developer Days
 

Semelhante a Desplegando código con Phing, PHPunit, Coder y Jenkins

Control de versiones utilizando subversion
Control de versiones utilizando subversionControl de versiones utilizando subversion
Control de versiones utilizando subversion
Julio Pari
 
249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf
249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf
249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf
AnaMorales765627
 

Semelhante a Desplegando código con Phing, PHPunit, Coder y Jenkins (20)

GuiaPrincipiantesGitHubrfuenzalidadev.pptx
GuiaPrincipiantesGitHubrfuenzalidadev.pptxGuiaPrincipiantesGitHubrfuenzalidadev.pptx
GuiaPrincipiantesGitHubrfuenzalidadev.pptx
 
Herramientas de integración continua en proyectos software
Herramientas de integración continua en proyectos softwareHerramientas de integración continua en proyectos software
Herramientas de integración continua en proyectos software
 
Curso Vagrant
Curso VagrantCurso Vagrant
Curso Vagrant
 
Control de versiones utilizando subversion
Control de versiones utilizando subversionControl de versiones utilizando subversion
Control de versiones utilizando subversion
 
Gwt
GwtGwt
Gwt
 
Técnicas para la Implementación de Desarrollo Continuo en AWS
Técnicas para la Implementación de Desarrollo Continuo en AWSTécnicas para la Implementación de Desarrollo Continuo en AWS
Técnicas para la Implementación de Desarrollo Continuo en AWS
 
Internal.docx
Internal.docxInternal.docx
Internal.docx
 
Turbogears_Instalación
Turbogears_InstalaciónTurbogears_Instalación
Turbogears_Instalación
 
Gestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniterGestionar mis proyectos con ayuda de CodeIgniter
Gestionar mis proyectos con ayuda de CodeIgniter
 
Pipeline de Integración continua
Pipeline de Integración continuaPipeline de Integración continua
Pipeline de Integración continua
 
instalacion e intregracion de OcsInventory-NG y GLPI
instalacion e intregracion de OcsInventory-NG y GLPIinstalacion e intregracion de OcsInventory-NG y GLPI
instalacion e intregracion de OcsInventory-NG y GLPI
 
Cherokee presentacion
Cherokee presentacionCherokee presentacion
Cherokee presentacion
 
Cuckoosandbox
CuckoosandboxCuckoosandbox
Cuckoosandbox
 
Cuckoo sandbox
Cuckoo sandboxCuckoo sandbox
Cuckoo sandbox
 
Técnicas para implementación de Continuous Delivery en AWS
Técnicas para implementación de Continuous Delivery en AWSTécnicas para implementación de Continuous Delivery en AWS
Técnicas para implementación de Continuous Delivery en AWS
 
Cuckoo sandbox
Cuckoo sandboxCuckoo sandbox
Cuckoo sandbox
 
249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf
249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf
249380217-Taller-de-Instalacion-e-Integracion-de-OcsInventory-y-GLPI.pdf
 
Configuración maquinas virtuales
Configuración maquinas virtualesConfiguración maquinas virtuales
Configuración maquinas virtuales
 
Instalación KOHA: desarrollo, requerimientos y configuración
Instalación KOHA: desarrollo, requerimientos y configuraciónInstalación KOHA: desarrollo, requerimientos y configuración
Instalación KOHA: desarrollo, requerimientos y configuración
 
Beef framework
Beef frameworkBeef framework
Beef framework
 

Mais de La Drupalera

Mais de La Drupalera (17)

QA en SEO: Amigos con derecho a roce - Drupalcamp 2019
QA en SEO: Amigos con derecho a roce - Drupalcamp 2019QA en SEO: Amigos con derecho a roce - Drupalcamp 2019
QA en SEO: Amigos con derecho a roce - Drupalcamp 2019
 
Consejos y trucos para cualificar una oportunidad Drupal
Consejos y trucos para cualificar una oportunidad DrupalConsejos y trucos para cualificar una oportunidad Drupal
Consejos y trucos para cualificar una oportunidad Drupal
 
Designer vs Front-end - DrupalCampES 2018 Alicante
Designer vs Front-end - DrupalCampES 2018 AlicanteDesigner vs Front-end - DrupalCampES 2018 Alicante
Designer vs Front-end - DrupalCampES 2018 Alicante
 
¡Ojo al dato!: Cómo evitar microinfartos a la gente de marketing - DrupalCamp...
¡Ojo al dato!: Cómo evitar microinfartos a la gente de marketing - DrupalCamp...¡Ojo al dato!: Cómo evitar microinfartos a la gente de marketing - DrupalCamp...
¡Ojo al dato!: Cómo evitar microinfartos a la gente de marketing - DrupalCamp...
 
PSD to HTML (Drupal) - Drupal Day Spain 2017 Cáceres
PSD to HTML (Drupal) - Drupal Day Spain 2017 CáceresPSD to HTML (Drupal) - Drupal Day Spain 2017 Cáceres
PSD to HTML (Drupal) - Drupal Day Spain 2017 Cáceres
 
Tips para posicionarte como desarrollador Drupal - Drupal Day Spain 2017 Cáceres
Tips para posicionarte como desarrollador Drupal - Drupal Day Spain 2017 CáceresTips para posicionarte como desarrollador Drupal - Drupal Day Spain 2017 Cáceres
Tips para posicionarte como desarrollador Drupal - Drupal Day Spain 2017 Cáceres
 
Tu drupal está listo… ¿lo sabe Google? - DrupalCamp 2017
Tu drupal está listo… ¿lo sabe Google? - DrupalCamp 2017Tu drupal está listo… ¿lo sabe Google? - DrupalCamp 2017
Tu drupal está listo… ¿lo sabe Google? - DrupalCamp 2017
 
Docker, your best ally to migrate & upgrading your Drupal - Drupal Dev Days S...
Docker, your best ally to migrate & upgrading your Drupal - Drupal Dev Days S...Docker, your best ally to migrate & upgrading your Drupal - Drupal Dev Days S...
Docker, your best ally to migrate & upgrading your Drupal - Drupal Dev Days S...
 
Beyond the web: Mobile apps using Drupal & Ionic 2 - Drupal Dev Days Seville ...
Beyond the web: Mobile apps using Drupal & Ionic 2 - Drupal Dev Days Seville ...Beyond the web: Mobile apps using Drupal & Ionic 2 - Drupal Dev Days Seville ...
Beyond the web: Mobile apps using Drupal & Ionic 2 - Drupal Dev Days Seville ...
 
Efficiently theming a multi-site Drupal 8 portal - Drupal Dev Days Seville 2017
Efficiently theming a multi-site Drupal 8 portal - Drupal Dev Days Seville 2017Efficiently theming a multi-site Drupal 8 portal - Drupal Dev Days Seville 2017
Efficiently theming a multi-site Drupal 8 portal - Drupal Dev Days Seville 2017
 
XML Sitemap Drupal Module
XML Sitemap Drupal ModuleXML Sitemap Drupal Module
XML Sitemap Drupal Module
 
QA on drupal projects
QA on drupal projectsQA on drupal projects
QA on drupal projects
 
¡This is drupal! - Global Training Days
¡This is drupal! - Global Training Days¡This is drupal! - Global Training Days
¡This is drupal! - Global Training Days
 
¿Cómo aplicar una estrategia de Marketing efectiva basada en Drupal?
¿Cómo aplicar una estrategia de Marketing efectiva basada en Drupal?¿Cómo aplicar una estrategia de Marketing efectiva basada en Drupal?
¿Cómo aplicar una estrategia de Marketing efectiva basada en Drupal?
 
Drupal vs Wordpress
Drupal vs WordpressDrupal vs Wordpress
Drupal vs Wordpress
 
Marketing, Comunidad, Empleo y Negocio Internacional basado en Drupal
Marketing, Comunidad, Empleo y Negocio Internacional basado en DrupalMarketing, Comunidad, Empleo y Negocio Internacional basado en Drupal
Marketing, Comunidad, Empleo y Negocio Internacional basado en Drupal
 
Caso de éxito Drupal - Procomún - DrupalCamp Spain 2016
Caso de éxito Drupal - Procomún - DrupalCamp Spain 2016Caso de éxito Drupal - Procomún - DrupalCamp Spain 2016
Caso de éxito Drupal - Procomún - DrupalCamp Spain 2016
 

Último

Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
AnnimoUno1
 

Último (11)

Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 

Desplegando código con Phing, PHPunit, Coder y Jenkins

  • 3.     Manual de uso Introducción El objetivo de esta guía no es detallar los pasos para la instalación de las herramientas que se comentan a continuación. Más bien nos centraremos en el flujo de despliegue y revisión del código que generamos desde un entorno local hacia otro remoto, tomando como fuente de datos un repositorio de datos (en este caso Github), pasando por la revisión y análisis de dicho código mediante herramientas externas que nos ayudarán a garantizar unos mínimos de calidad antes de realizar un despliegue. Para ello, y antes de entrar en materia, daremos por supuesto que tenemos instalado Jenkins en un servidor con los siguientes Plugins. No obstante, en lo sucesivo iremos comentando en qué momento debemos instalar cada uno de los plugins: ● Drupal developer plugin ● Git client plugin ● Git plugin ● Github plugin ● Phing plugin ● XUnit plugin Además de esto, deberemos tener instalados los siguientes servicios en nuestra máquina de integración: ● PHPUnit ● Phing ● PHP (5.4) ● Git Consideraciones Lo que se pretende ofrecer en esta guía es una serie de pasos que garantice, mediante la fusión de ramas a través de Github (Merge), la ejecución de una serie de procesos que garantice que el código mergeado en una rama cumpla con los requisitos funcionales, además de garantizar una sintaxis adecuada, antes de un despliegue, de forma que podamos automatizar una serie de tareas que generalmente realizamos a mano. Para ello, utilizaremos como herramienta motora Jenkins, encargada de centralizar todo el proceso de revisión y garantía del código, asumiendo la responsabilidad de realizar un despliegue en caso de éxito o bien, detener dicho despliegue y avisar a los responsables de los errores cometidos. Jenkins es un software de Integración continua open source escrito en Java. Está basado en el proyecto Hudson y es, dependiendo de la visión, un fork del proyecto o simplemente un cambio de nombre. Jenkins proporciona integración continua para el desarrollo de software. Es un sistema corriendo en un servidor que es un contenedor de servlets, como Apache Tomcat. Soporta herramientas de control de versiones como CVS, Subversion, Git, Mercurial,   VP1.9  2 / 20   
  • 4.     Perforce y Clearcase y puede ejecutar proyectos basados en Apache Ant y Apache Maven, así como scripts de shell y programas batch de Windows. El desarrollador principal es Kohsuke Kawaguchi. Y pasamos a la práctica directamente. Para ello, debemos configurar en primer lugar una serie de tareas o jobs en Jenkins de forma lineal. Es decir, si la primera tarea no cumple con los requisitos deseados, no pasaremos a la siguiente. Esto nos permite atomizar los procesos involucrados en la revisión de un despliegue: 1. Análisis de comentarios, seguridad y sintaxis a través de Coder 2. Ejecución de tests unitarios 3. Despliegue en el entorno Estas tareas se ejecutarán de forma secuencial, de manera que si una de ellas no cumple con los requisitos deseados, el proceso se detendrá automáticamente notificando a las partes implicadas de las incidencias producidas durante el despliegue. Las condiciones previas que deberían darse antes de iniciar este proceso son las siguientes: ● Tener un entorno remoto versionado en Github apuntando a una rama, en este caso ‘Staging’ ● Tener un entorno local versionado en nuestra máquina, a ser posible a través de un Fork de la rama principal de Staging, de forma que tengamos la posibilidad de solicitar integraciones en la rama principal. No obstante, este flujo es relativo y se basa en el ejemplo real citado a continuación, pero las posibilidades en cuanto a tests basados en haltonfail son prácticamente infinitas. En el ejemplo que tratamos a continuación, el servidor Jenkins ha sido instalado en la misma máquina donde integraremos el código a través de Github. No obstante, podría estar perfectamente en una máquina remota y realizar un despliegue a través de SSH en un servidor remoto. Si este fuera el caso, un error muy frecuente a tener en cuenta es el acceso mediante el par de claves pública/privada del usuario Jenkins que ejecuta las peticiones en el servidor remoto de despliegue, por lo que sería aconsejable realizar previamente una conexión desde la consola del servidor Jenkins a la máquina remota con el usuario jenkins (que instala el servidor por defecto) para comprobar que el acceso se realiza sin problemas de autenticación. Además de esto, también es importante revisar los accesos mediante SSH al repositorio Github donde tengamos alojado nuestro código de integración para asegurarnos que el usuario jenkins puede acceder al mismo y realizar escrituras. Configurando Github Sabiendo esto, vamos a establecer el primer paso la llamada automática al trigger o disparador de Jenkins en Github cuando se produce un Merge en una rama determinada. Para ello, en nuestro repositorio principal (o de integración) deberemos acceder a la configuración del repositorio mediante la pestaña ‘Settings’:   VP1.9  3 / 20   
  • 5.     Después, debemos acceder a la pestaña ‘Webhooks & Services’: En esta ventana, debemos acceder el servicio ‘Jenkins (Github Plugin)’: Para configurar el servicio, nos solicitará un URL de acceso que utilizará para avisar a Jenkins mediante una petición POST de que ha habido un merge en una rama. Para conocer esta URL, debemos acceder a la configuración de Jenkins ‘Administrar Jenkins’, y acceder a la ‘Configuración del sistema’. Si hemos instalado el Github Plugin correctamente, podremos ver la URL que debemos poner en su sección correspondiente: NOTA​: Para ver la ruta habrá que hacer click en el icono de interrogación que aparece a la derecha. Una vez introducida esta URL en Github, éste nos permite realizar un test a través de un botón de acción. No obstante, el ‘status’ de esta petición no se actualiza hasta que se realiza una petición real a través de un Merge (al menos en los ejemplos realizados durante la redacción de este documento), por lo que no debemos preocuparnos demasiado por este asunto de momento.   VP1.9  4 / 20   
  • 6.     Realizando nuestra primera tarea Una vez hemos concluido la configuración de nuestro repositorio en Github y hemos finalizado la instalación y configuración de Jenkins, vamos a pasar a configurar nuestra primera tarea. Para ello, hacemos click en el primer item del bloque de la izquierda de nuestro Jenkins ‘Nueva tarea’: Una vez hacemos click en este item, crearemos un nuevo proyecto de estilo libre, y pondremos un nombre de prueba para la tarea: Una vez hacemos click en OK, pasamos a la siguiente pantalla, de la cual resaltamos los aspectos más importantes a nivel de configuración:   VP1.9  5 / 20   
  • 7.     Hemos destacado 3 opciones, aunque podemos realizar diferentes pruebas con el resto de configuraciones: ● Github project: marcando este item, introduciremos la URL de nuestro repositorio. ● Dentro de ‘Configurar el origen del código fuente’, deberemos marcar la opción Git, y aquí tendremos que introducir la URL del proyecto. En este caso, no introduciremos la URL del repositorio, sino aquella utilizada para poder hacer un checkout del mismo. Esto se puede hacer de dos maneras: ○ Mediante SSH: si lo hacemos así, tendremos que asegurarnos que el usuario Jenkins de nuestra máquina tiene acceso al repositorio que queremos configurar. Esto lo configuraremos en nuestro repositorio en Github otorgando permisos a través de la clave pública del usuario. ○ Mediante HTTPS: con esta alternativa, Jenkins nos permitirá introducir las credenciales del usuario con acceso al repositorio. De esta forma, dicho usuario también tendría que tener acceso a este repositorio. Podemos ver información de estas URL dentro de nuestro propio repositorio en Github tal y como se muestra en la imagen a continuación: En este aspecto, es importante resaltar un punto. Una vez hemos introducido las credenciales o bien el acceso SSH en nuestro Jenkins, al pulsar el botón tabulador Jenkins internamente comprobará el acceso al repositorio. Si existe algún problema con las credenciales, en este momento dará un aviso notificando del error de acceso. Si este es el caso, sería necesario comprobar que la comunicación entre nuestro usuario Jenkins y el repositorio en Github se está produciendo (en el caso del acceso por SSH), o bien comprobar que las credenciales introducidas (HTTPS) son correctas para el acceso a dicho repositorio.   VP1.9  6 / 20   
  • 8.     Una vez hemos asegurado que las credenciales son correctas, debemos especificar la rama sobre la que queremos trabajar; en este caso hemos optado por la rama por defecto (master). El siguiente punto, ‘’Build when a change is pushed to Github” es que el que nos dará la clave para automatizar la tarea que necesitemos. Esta opción indica a Jenkins que debe ejecutar esta tarea cuando alguien realiza un push o un merge en la rama master que hemos configurado, por lo tanto esta opción es vital para poner en marcha nuestro proceso de despliegue automático. Ahora, solo nos quedaría configurar la acción a realizar cuando se detecte un push en nuestra rama master. En nuestro caso, debido a que nuestro servidor Jenkins está instalado en el mismo servidor que nuestro entorno de integración, bastaría con añadir un nuevo paso y ejecutar un comando a través de la shell: En este caso, el comando básicamente cambia la ubicación del sistema al DOCUMENT ROOT de nuestro servidor apache y realiza un PULL desde la rama master con el usuario developer. Si tuviésemos nuestro entorno de integración en una máquina remota, bastaría con realizar esta misma acción a través de SSH. Con esta tarea ya tenemos nuestro primer despliegue automático a través de Jenkins. Implementando Drupal Developer Plugin Una vez que hemos visto cómo realizar un despliegue directo a través de Jenkins en un entorno, vamos a añadir una nueva “capa de dificultad”. En este caso vamos a aplicar una validación de código a través del plugin ‘Drupal Developer Plugin’, un módulo de Jenkins que implementa una serie de validaciones de coding estandar y genera las métricas necesarias para evaluar la calidad del código. Este ejemplo sólo sería válido si estamos trabajando sobre un gestor de contenido basado en Drupal y queremos ser respetuosos con los estándares de código. Para ello, antes de crear una nueva tarea, vamos a añadir una nueva configuración a la tarea que hemos creado anteriormente para que ésta solo se lleve a cabo siempre y cuando la validación a través del plugin de Jenkins haya sido satisfactoria. En la configuración de nuestra tarea de despliegue, marcamos la siguiente opción:   VP1.9  7 / 20   
  • 9.     Además, vamos a desactivar la opción que activamos anteriormente ‘’Build when a change is pushed to Github” para evitar que esta tarea se ejecute automáticamente, y solo lo haga cuando la tarea que vamos a crear ahora haya cumplido todos los requisitos que necesitamos. En un ejemplo real, realmente esta configuración habría que hacerla después de haber creado la tarea de prueba con el plugin ‘Drupal Developer Plugin’, de lo contrario Jenkins no reconocería la prueba que hemos introducido en este ejemplo, pero la ponemos aquí para darle continuidad a nuestro trabajo. Básicamente estamos especificando que solo se realice un despliegue en nuestro entorno de integración siempre y cuando la tarea ‘Prueba Coder’ se haya ejecutado con éxito. El siguiente paso sería, en primer lugar, instalar los plugins necesarios para Jenkins. Para ello, desde la administración de Jenkins, accedemos a la sección de administración de Plugins: Una vez aquí, debemos buscar e instalar los siguientes plugins: ● Checkstyle Plug-in: este plugin es necesario para generar las métricas a través de Jenkins y poder evaluar los resultados de los archivos generados. ● Drupal Developer: este plugin realiza una serie de análisis sobre nuestro código fuente para evaluar su calidad, parámetros de seguridad, etc. No vamos a centrarnos aquí en los pormenores de la instalación, ya que existe documentación en la web oficial de Jenkins sobre estos plugins que describen bastante bien su funcionamiento e instalación. Pasamos pues directamente a crear una nueva con las mismas características que la anterior (Proyecto libre), poniendo el nombre que consideremos oportuno, y pasamos a describir la configuración de la tarea. Para el origen de datos (Github) y la URL del   VP1.9  8 / 20   
  • 10.     repositorio, la configuración sería exactamente la misma, por lo que vamos a obviar de nuevo la explicación de estos parámetros. Como en la anterior tarea desmarcamos finalmente la opción ‘Build when a change is pushed to GitHub’, vamos a marcarla en esta nueva tarea, de forma que sea ésta la que se ejecute en primer lugar, y en caso de éxito pase a la tarea de despliegue como ya configuramos anteriormente. En este caso, tendríamos que añadir un nuevo paso denominado ‘Review code on Drupal’: En esta prueba, vamos a marcar todos los tests para asegurar la integridad del código en todos sus niveles. Los parámetros a configurar son los siguientes (es necesario pulsar el botón ‘Avanzado’ para ver todas las opciones): ● Drupal root directory: DOCUMENT ROOT de nuestro gestor de contenidos ● Logs directory: directorio en el que el plugin generará los archivos XML con los resultados de los tests ● Exclude these modules/themes: es importante configurar bien este apartado, ya que para obtener unos resultados que luego nos sirvan realmente de interés, ignoraremos todos aquellos directorios que no nos vayan a reportar información de interés para nuestro propósito. En nuestro caso, hemos ignorado todas las carpetas de módulos exceptuando la carpeta ‘custom’ o ‘main’ dentro de ‘sites/all/’, ya que es en esta ubicación donde almacenaremos nuestros módulos personalizados, es decir, aquellos que realmente nos interesa evaluar. Una vez realizado este paso, debemos añadir una acción para poder evaluar los resultados de los tests generados por el plugin. Para ello, hacemos click en ‘Añadir paso’ y agregamos la opción ‘Public Checkstyle analysis results’ con los siguientes parámetros:   VP1.9  9 / 20   
  • 11.     Pasamos a describir los parámetros más significativos: ● Checkstyle results: es la carpeta donde el plugin Drupal Developer genera los archivos XML de los resultados de los tests realizados (hemos configurado esta carpeta en el paso anterior). De esta forma, el plugin Checkstyle analizará todos los archivos XML ubicados en este directorio para generar las métricas necesarias. ● Health priorities: desde aquí podemos priorizar las tareas que nos interesa analizar en función de su prioridad ● Status thresholds (Totals): desde aquí podemos configurar el plugin para que su resultado sea exitoso o fallido en función del número de incidencias detectadas y su prioridad. Es aquí donde podemos refinar nuestra herramienta hasta encontrar la flexibilidad/rigidez adecuada para el desarrollo de nuestro proyecto. Una vez hemos guardado nuestra nueva tarea, es hora de ejecutarla a través de la pantalla principal de Jenkins: Es importante resaltar que, en el caso de que una tarea haya detectado alguna incidencia, siempre nos resultará muy útil la información que Jenkins almacena para intentar detectar el problema:   VP1.9  10 / 20   
  • 12.     Suponiendo que nuestra tarea ha tenido éxito, bien considerando que ha pasado todos los estándares de calidad necesarios, o bien asumiendo que se ha detectado alguna inconsistencia en el código que ha impedido la ejecución de la siguiente tarea, si hacemos click en el desplegable que aparece junto al nombre de nuestra tarea veremos una serie de opciones, entre las que tenemos que elegir ‘Checkstyle Warnings’ (esta opción sólo aparecerá si se ha configurado debidamente el plugin Checkstyle y se han generado los reportes necesarios, en caso contrario sería conveniente revisar los logs para detectar los problemas ocurridos):   VP1.9  11 / 20   
  • 13.     Una vez hacemos click, nos apareceŕan por fin las métricas de nuestros resultados: Podemos resaltar tres secciones interesantes: ● Files: aquí podremos ver un listado general de todos los archivos con problemas detectados, junto al número de incidencias por archivo. ● Warnings: desglose de cada uno de las incidencias detectadas, junto a su prioridad. Además, si hacemos click en alguno de estos errores, el plugin nos presenta el interior del archivo remarcando el error detectado. ● Details: aquí podemos ver una descripción ampliada de los errores detectados Integrando Phing Para entrar en contexto, Phing es un port de Apache Ant destinado a la ejecución de tareas, como puede ser la creación de carpetas, actualizaciones sobre un repositoiro, elaborar tests de PHP Unit, etc. todo ello configurado en un archivo XML que después será ejecutado por Jenkins. De esta forma, podemos generar un archivo XML con una serie de tests personalizados que luego se integrarán en el flujo de despliegue de Jenkins. En nuestro ejemplo, vamos a elaborar un test personalizado que ejecutaremos con PHP Unit, para luego poder evaluar los resultados obtenidos del test y poder visualizar el resultado de esta información con el ‘xUnit Plugin’ de Jenkins. Bien, de antes ponernos a instalar plugins de Jenkins, es necesario instalar Phing en el servidor de integración continua. La mejor manera de instalar Phing es a través de PEAR y del canal PEAR de Phing, así pues hay que entrar en la terminal e introducir los siguientes comandos: pear channel-discover pear.phing.info pear install --alldeps phing/phing pear channel-discover pear.phing.info   VP1.9  12 / 20   
  • 14.     Para asegurarnos que la instalación se ha realizado correctamente, podemos ejecutar el siguiente comando en la consola del sistema: phing -v Lo siguiente que tendremos que hacer será crear un fichero en la raíz de nuestro proyecto con el nombre build.xml y ahí escribir las tareas o targets. Si ejecutamos ‘phing’ en la consola del sistema, éste intentará localizar el archivo build.xml en el directorio donde hayamos ejecutado el comando. Si no encuentra este archivo, Phing te devuelve un error indicando que no ha encontrado el archivo. Lo bueno de las tareas automatizadas es que no son independientes unas de otras, sino que desde una tarea puedes hacer una llamada a otra o incluso pueden existir tareas que dependan de otras para que puedan ser ejecutadas. No es el objetivo de este manual describir con más detalle la estructura del archivo XML ni su relación de dependencias, aunque existe documentación bastante bien detallada sobre su configuración. El siguiente paso, antes de entrar en el detalle de nuestro archivo XML, será instalar PHPUnit, que es el framework que utilizaremos en este ejemplo para la ejecución de tests unitarios sobre nuestro código. Antes de poder instanciar sus clases y programar la creación de un test, es necesario instalar dicho framework en el sistema. Para ello, podemos descargarlo de su repositorio oficial y ubicarlo dentro de nuestro sistema: wget https://phar.phpunit.de/phpunit.phar chmod +x phpunit.phar sudo mv phpunit.phar /usr/local/bin/phpunit phpunit --version Si todo ha ido bien, el sistema nos reportará la versión de PHP Unit instalada. En nuestro ejemplo, usaremos PHPUnit 4.8.24 junto a la versión 5.4.45 de PHP. Damos por hecho que estamos ejecutando estos tests en una máquina con esta versión de PHP o superior instalada. Elaborando nuestro primer Test Aunque no es objeto de este manual indagar en el uso de PHP Unit para la elaboración de tests unitarios, diremos que PHPUnit se creó con idea de que cuanto antes se detecten los errores en el código antes podrán ser corregidos. Este conocido framework para PHP nos permite crear y ejecutar juegos de tests unitarios de manera sencilla. Como todos los frameworks de pruebas unitarias, PHPUnit utiliza assertions para verificar que el comportamiento de una unidad de código es el esperado. El objetivo de las pruebas unitarias es aislar cada parte del programa y demostrar que las partes de forma individual son correctas. Una prueba unitaria proporciona un contrato escrito que la pieza de código debe satisfacer. Como resultado, las pruebas unitarias encuentran problemas en las fases   VP1.9  13 / 20   
  • 15.     iniciales del desarrollo de software. La idea detras de un assert es crear un objeto, ejecutar algunas funciones y después comprobar su estado interno. Lo mejor es utilizar un ejemplo para ilustrarlo: class TddTests extends PHPUnit_Framework_TestCase { public function test_tdd_help() { $this->assertEquals(1,1); } } Como observamos en el código, básicamente lo que hemos hecho es crear una clase TddTests heredada de la clase PHPUnit_Framework_TestCase. Es aquí dentro donde podremos elaborar la programación de los tests. Existen infinidad de asserts proporcionados por PHPUnit para la elaboración y ejecución de diferentes tipos de tests unitarios, aunque en nuestro ejemplo utilizaremos un caso sencillo mediante el assert assertEquals. Este assert compara dos cadenas de texto pasadas por argumento, y nos devolverá un resultado TRUE/FALSE en función de si estas dos cadenas son iguales (TRUE) o diferentes (FALSE). Nuestra función test_tdd_help que invoca al assert devolverá en cualquier caso un resultado positivo, ya que los dos argumentos comparativos que le pasamos a nuestro assert son iguales, no obstante, este ejemplo nos permite hacernos una idea del funcionamiento básico de un assert con PHPUnit y el poder que obtenemos con la ejecución de este tipo de tests. Antes de entrar en la configuración del test unitario a través de Phing, vamos a asegurarnos que nuestro test está bien programado y podemos ejecutarlo sin problemas a través de la consola. De esta forma, si posteriormente nos encontramos con algún problema de configuración, podremos aislar los problemas más fácilmente y detectar con más facilidad el punto de fallo. Para ello, vamos a crear un archivo llamado TddTests.php ubicado, desde el DOCUMENT ROOT de nuestra instalación de Drupal, en sites/all/modules/main/tdd con el siguiente contenido. Aunque la ubicación o los nombres de los archivos pueden cambiar en función de nuestras necesidades, hemos establecido esta ubicación únicamente para ilustrar el ejemplo: <?php define('DRUPAL_ROOT', '/var/www'); require_once DRUPAL_ROOT . '/includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); class TddTests extends PHPUnit_Framework_TestCase { public function test_tdd_help() { $this->assertEquals(1,1);   VP1.9  14 / 20   
  • 16.     } } ?> Las tres primeras líneas cargan el bootstrap de Drupal en caso de que tuviéramos que hacer uso de su API. Aunque en este ejemplo no es estrictamente necesario, lo referenciamos por si el lector quiere ampliar el código de este ejemplo apoyándose en la API de nuestro CMS. El resto contiene la clase que hemos comentado anteriormente, integrando el assert assertEquals que, en todo caso, nos devolverá un resultado positivo. Ubicándonos de nuevo en el DOCUMENT ROOT de nuestro portal, ejecutamos en consola el siguiente comando: phpunit sites/all/modules/main/tdd/TddTests.php Si todo ha ido bien, el framework nos devolverá la siguiente respuesta por pantalla: PHPUnit 4.8.24 by Sebastian Bergmann and contributors. . Time: 392 ms, Memory: 42.75Mb OK (1 test, 1 assertion) En este caso, nos indica que se ha ejecutado un test con un assert, sin ningún error encontrado. Vamos a realizar ahora una modificación en nuestro archivo PHP cambiando el valor de uno de los dos argumentos, de forma que el assert nos devuelva un resultado negativo. Volvemos a ejecutar nuestro comando por consola y ahora el resultado es: PHPUnit 4.8.24 by Sebastian Bergmann and contributors. Time: 392 ms, Memory: 42.75Mb There was 1 failure: 1) TddTests::test_tdd_help Failed asserting that 0 matches expected 1. /var/www/sites/all/modules/main/tdd/TddTests.php:10 FAILURES! Tests: 1, Assertions: 1, Failures: 1.   VP1.9  15 / 20   
  • 17.     Como vemos en el ejemplo, en esta ocasión, además de informarnos de la ejecución completa del test, nos indica que ha detectado un error, y sabiendo esto, únicamente nos queda recuperar la información resultante del test para poder tratarla con alguna herramienta (¿os imagináis cual?) y poder interactuar con el flujo de despliegue en función de los resultados de los tests. Volvemos pues al punto de partida con Phing. Ahora que ya sabemos para qué sirve PHP Unit, y hemos comprobado su funcionamiento a través de un sencillo ejemplo a través de un comando por consola, estamos preparados para integrar esta funcionalidad a nuestra herramienta de integración continua, estableciendo su configuración con el apoyo de Phing. Vamos pues a crear nuestro primer archivo build.xml en el raíz de nuestro plataforma, o bien ubicarlo en algún directorio que sea accesible con posterioridad con Jenkins. El contenido del archivo es el siguiente: <?xml version="1.0"?> <project name="MyApplication" default="build"> <property name="package" value="MyApplication" override="true" /> <target name="clean"> <delete dir="../reports"/> </target> <target name="prepare"> <mkdir dir="../reports/logs"/> </target> <target name="phpunit"> <phpunit printsummary="true" haltonfailure="true" pharlocation="/usr/local/bin/phpunit"> <formatter todir="../reports/logs" type="xml"/> <batchtest> <fileset dir="../"> <include name="src/sites/all/modules/main/tdd/TddTests.php"/> </fileset> </batchtest> <formatter type="xml" todir="../reports" outfile="logfile.xml"/> </phpunit> <phpunitreport infile="../reports/logfile.xml" styledir="/usr/share/php/data/phing/etc" format="frames" todir="../reports"/> </target> <target name="build" depends="clean,prepare,phpunit"/> </project> Como hemos comentado anteriormente, no es objetivo de este manual entrar en profundidad a explicar la creación y configuración de este archivo, no obstante, pasaremos a comentar algunas etiquetas que resultan interesantes para entender su funcionamiento: ● delete dir y mkdir: le indicamos la ubicación de nuestro directorio de reportes para que lo borre antes y lo vuelva a crear de comenzar la ejecución de nuestros tests ● phpunit: le indicamos la ruta de nuestro ejecutable PHP Unit   VP1.9  16 / 20   
  • 18.     ● formatter todir: indicamos donde deberán almacenarse nuestros reportes, y en qué formato Posteriormente indicamos la ruta de nuestro test, además de especificar el nombre de nuestro archivo ‘logfile.xml’ con los resultados de nuestros tests. Como ya hicimos anteriormente con PHPUnit, es hora de probar de forma aislada la composición de nuestro archivo build.xml y comprobar que funciona correctamente antes de integrarlo directamente en Jenkins, de esta forma nos aseguraremos que la estructura de nuestro archivo XML es correcta, y como ya hemos asegurado antes que nuestro test unitario funcionaba correctamente, ahora vamos a subir un nuevo peldaño incluyendo dicha ejecución a través de Phing. Bastaría con ejecutar por consola el siguiente comando en el mismo directorio que hemos creado nuestro archivo build.xml: phing Si nuestro archivo build.xml se encuentra en una ubicación diferente, podemos establecer la ruta del archivo con el parámetro -f. Si todo ha ido correctamente, el resultado por consola debería ser similar al siguiente: Buildfile: /var/www/build.xml MyApplication > clean: [delete] Deleting directory /var/www/reports MyApplication > prepare: [mkdir] Created dir: /var/www/reports/logs MyApplication > phpunit: [phpunit] Total tests run: 1, Failures: 0, Errors: 0, Incomplete: 0, Skipped: 0, Time elapsed: 0.00471 s MyApplication > build: BUILD FINISHED Total time: 0.1681 seconds Bien. Llegados a este punto, creo que estamos suficientemente preparados para pasar la ejecución de nuestro test a través de Jenkins, nuestra herramienta de integración continua. Para ello, previamente hay que instalar los módulos ‘Phing Plugin’ para poder ejecutar nuestras tareas a través del archivo build.xml y ‘xUnit Plugin’, que nos permitirá la visualización de las métricas generadas por Phing. No vamos a entrar en más detalles sobre la instalación de Plugins en Jenkins porque ya lo hemos comentado anteriormente. Así que   VP1.9  17 / 20   
  • 19.     pasamos a crear directamente nuestra tarea, siguiendo los pasos anteriormente con el mismo origen de datos, la misma URL de nuestro repositorio, etc. Nos centraremos en la tarea específica que habrá que crear para ejecutar un script de Phing. Para ello, añadiremos un nuevo paso denominado ‘Invoke Phing Targets’. Este paso debería aparecer automáticamente si hemos instalado correctamente nuestros plugins: El único aspecto aquí a remarcar es el campo ‘Phing Build File’. Simplemente tenemos que indicar la ruta donde hemos creado nuestro archivo build.xml partiendo de nuestro DOCUMENT ROOT. Otro aspecto muy importante a tener en cuenta aquí, y que suele ser la causa de muchos problemas, es el origen de los datos. Esto quiere decir que para que Jenkins pueda leer correctamente nuestro archivo build.xml, éste debe estar versionado en nuestro repositorio, ya que, recordamos, éste es el origen de datos de nuestra tarea en Jenkins, por lo tanto cualquier cambio que hayamos realizado en nuestro archivo build.xml debe estar correctamente actualizado en nuestro repositorio para que Jenkins pueda ejecutarlo. El siguiente paso consiste, dentro de la misma tarea, en añadir una nueva acción ‘Publish xUnit test result report’. Al igual que en el paso anterior, esta acción solo estará presente si hemos instalado correctamente nuestros plugins. Pasamos a describir la configuración de esta acción:   VP1.9  18 / 20   
  • 20.     De esta acción vamos a comentar dos aspectos importantes: ● Ruta de los reportes: es importante recordar que esta ruta debe coincidir con la ruta que hemos configurado en nuestro archivo build.xml de Phing, que es el encargado de generar dichos reportes. ● Failed Tests: aunque es bastante obvio, me limitaré a comentar que aquí podemos configurar la flexibilidad de nuestros avisos, de forma que podamos configurarlo de tal modo que la tarea pueda resultar exitosa o fallida en función del número de tests que se hayan ejecutado con éxito, etc. Como comentamos en puntos anteriores, esta tarea puede ser configurada para que sea ejecutada antes o después de otras tareas en nuestro proceso de despliegue, aunque una vez conocida la práctica, creo que en este punto tenemos el conocimiento suficiente como para decidir en qué momento necesitamos ejecutar este test. Web externas ● Jenkins:​https://jenkins.io/ ● Phing: ​https://www.phing.info/ ● PHP Unit: ​https://phpunit.de/ ● Github: https://github.com/ ● xUnit Plugin: ​https://wiki.jenkins-ci.org/display/JENKINS/xUnit+Plugin ● Phing Plugin: ​https://wiki.jenkins-ci.org/display/JENKINS/Phing+Plugin ● Git Plugin: https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin ● Drupal Developer Plugin:   VP1.9  19 / 20   
  • 21.     https://wiki.jenkins-ci.org/display/JENKINS/Drupal+Developer+Plugin ● Checkstyle Plugin: https://wiki.jenkins-ci.org/display/JENKINS/Checkstyle+Plugin   VP1.9  20 / 20