code formatting

martes, 10 de abril de 2012

Hook de Subversion para ejecutar un job de Jenkins

Teníamos una necesidad puntual. Necesitábamos que al hacer un tag de una versión RC de un proyecto en subversion, se ejecutara un trabajo en jenkins correspondiente a ese proyecto y que se deploye automáticamente en un servidor remoto.
Después de mucha investigación dimos con un principio de solución que obviamente iremos mejorando con el tiempo.

Paso 1: Configuración de Jenkins

Como primer punto, tenemos que configurar un trabajo de jenkins para que podamos elegir qué versión deployar. Para eso usamos el plugin de subversion y configuramos un parámetro del tipo List Subversion Tags para elegir la versión con la que queremos trabajar:

Esto lo hacemos porque tenemos mas de un subdirectorio en la carpeta de subversion y de esta manera cuando ejecutemos el job, vamos a poder elegir qué versión ejecutar de manera dinámica.


Paso 2: Configuracion de Subversion para que avise a Jenkins que tiene que ejecutar


Lo primero que hay que hacer es en el job de Jenkins habilitar que se pueda ejecutar el trabajo de forma remota:


Jenkins nos pide que pongamos un TOKEN, es una palabra cualquiera que provee aunque sea un mínimo de seguridad para que no cualquiera pueda ejecutar el trabajo de forma remota. El trabajo se puede probar poniendo en el navegador la url que nos dice Jenkins.

En el servidor donde tenemos instalado el subversion, tenemos que hacer un dos scripts: uno que en realidad es el hook de SVN, tenemos que ir a la carpeta /var/lib/svn/<repositorio>/hooks y allí hacemos

cp post-commit.tmpl post-commit
chmod +x post-commit

Esto lo que va a hacer es habilitar el script post-commit para que se ejecute despues de haberse hecho un commit en el repositorio.
Editamos el archivo post-commit y nos tiene que quedar algo así:

REPOS="$1"
REV="$2"
/home/usuario/bin/jenkins-launch-build.sh $REPOS $REV job-name

Es decir, cada vez que se haga un commit del repositorio, se va a llamar al script jenkins-launch-build y se le va a pasar como parámetro el repositorio, el número de versión que se acaba de comitear y el nombre del trabajo en jenkins.
El último paso es crear el script que se encargará de hacer la llamada remota... debería ser algo así:

#!/bin/bash
# Este script comprueba si se han hecho cambios en un directorio concreto,
# y en tal caso lanza una build en Jenkins

REPOS="$1"
REV="$2"
JENKINS_JOB="$3"
JENKINS_USER=admin
JENKINS_PASSWORD=****
JENKINS_HOST=<hostname>

for i in $(svnlook dirs-changed $REPOS --revision $REV | fgrep tags\/RC\/ | awk -F/ '{print $3}' | sort | uniq)
do
 wget --quiet --auth-no-challenge --no-check-certificate --http-user=$JENKINS_USER --http-password=$JENKINS_PASSWORD http://$JENKINS_HOST/job/$JENKINS_JOB/buildWithParameters?token=TOKEN\&SVNTAG=$i
done

exit 0

Este script lo que va a hacer es llamar a la ejecución remota de jenkins cada vez que se haya cambiado algún tag en la carpeta tags/RC del repositorio. Básicamente lo que hace es fijarse si hubo algún cambio en el repositorio con svnlook. Se filtran esos cambios si ocurrieron en tags/RC y por cada uno de esos proyectos que cambiaron, se los paso como parámetro (que habíamos configurado en el paso 1) al build remoto. Algo importante en la llamada al build remoto es que hay que llamar a buildWithParameters y para pasarle el parámetro hay que separarlo con \&

Espero que sea útil... no es tan complicado y es un primer paso para armar el pipeline de integración continua.

No hay comentarios:

Publicar un comentario en la entrada