La integración continua es una técnica software en la cual se integran los cambios muy frecuentemente (generalmente horas), tratando de detectar errores lo mas pronto posible, automatizando la compilación y la ejecución de las pruebas.

Para poder desarrollar nuestra aplicación en un entorno de integración continua haremos uso de

  • Ant que se encargara de la automatización
  • Jenkins sera el encargado de la integración continua.
  • En este caso Git y Bitbucket como control de versiones.

Como punto de partida tendremos un proyecto Android con su respectivo proyecto de pruebas, para mas detalles consultar la documentación.

Configuración de Ant

Primero que nada necesitamos indicar que nuestro proyecto va a ser compilado con Ant y donde queremos despegarlo, para ello abrimos el terminal, vamos a la carpeta donde se encuentra nuestro proyecto y ejecutamos:

1
android update project --path ./ --name MyProject

Como resultado se creara el archivo build.xml

Jenkins

Hay dos posibles maneras de instalar Jenkins: desde un repositorio o desplegando un war en apache, las instrucciones las podemos encontrar en la documentación.

Una vez instalado Jenkins abrimos el navegador y entramos a localhost:8080 si vemos la pagina inicial de Jenkins es que todo esta bien, sino tendremos que iniciar el servicio.

Ahora si, ya tenemos a Jenkins ejecutándose y el siguiente paso a dar es añadir el soporte de Git (o el repositorio escogido), lo cual puede hacer fácilmente instalando el plugin Jenkins Git plugin.

Creación de la tarea

Jenkins se encarga de ejecutar tareas, por lo tanto todo lo que queramos hacer tendrá que ser definido como tal. En el panel izquierdo tendremos la opción de crear una tarea, y a continuación nos mostrara una serie de opciones. Para nuestro proyecto Android tendremos que elegir Free-style Project. Ya en la pantalla de creación de la tarea tendremos que configurar lo que queremos hacer, en este caso compilar e instalar la aplicación.

Repositorio

Esta parte no tiene mucho misterio, simplemente es especificar los datos de nuestro repositorio.

Ignoren los posibles errores que surjan al indicar la web de repositorio, mas adelante se explicara como solucionarlo.

Planificación

Jenkins tendrá que saber cuando se compilara la aplicación, para integración continua lo más adecuado es que se haga ni bien se detecta un cambio en el código, es decir cada vez que se haga un commit. Por lo que en Build Triggers tendremos que marcar Poll SCM, para que Jenkins consulte el repositorio cada cierto tiempo en busca de cambios, la frecuencia de la consulta se define siguiendo el formato de cron. Por ejemplo “15 comprobara el repositorio pasados los 15 minutos de cada hora, es decir 12:15, 13:15, 14:15, etc.

Bitbucket brinda un servicio en el cual es el propio Bitbucket el que notifica a Jenkins de que hubo algún cambio en el código, pero para esto se necesita una url publica para Jenkins.

Compilación e InstalaciónA esta altura Jenkins ya sabe de donde obtener el código y cada cuanto comprobar si hay algún cambio, nos faltaría definir como compilar y que hacer después de compilar. La compilación se hará mediante Ant para ello añadiremos dos pasos clean debug para limpiar el proyecto y compilar en modo debug; y debug install para instalar el .apk generado.

Para poder instalar la aplicación tendremos dos opciones usar un dispositivo real o el emulador, en este caso usaremos el emulador. Para ello dependeremos de Android Emulator Plugin podemos hacer el propio plugin cree el emulador en tiempo de ejecución o definirlo nosotros mismo. Si decidimos crearlo a mano en el documento Managing AVDs from the Command line esta muy bien explicado.

Dentro de las opciones avanzadas de compilación encontraremos un campo llamado Properties, en el cual tendremos que indicar donde se encuentra el SDK de Android y la plataforma sobre la que trabajaremos.

1
2
sdk.dir=/opt/android-sdk-linux
target=android-8

Si queremos conservar los .apk generados en cada compilación, tendremos que ir a la sección Post-build Actions, la opción que nos interesa es Archive the artifacts. Especificando la ruta donde queremos guardarlo, por ejemplo para guardarlo en la ruta asignada por defecto y agregando “-debug” al final del nombre del fichero seria: */-debug.apk

Ya tenemos la tarea configurada, pero si compilamos ahora mismo fallara. Viendo el log generado veremos que se debe a que no tenemos los permisos necesarios para acceder al repositorio, obviamente si es un repositorio publico esto no pasara.

Dando permisos a Jenkins

Una vez creada la tarea realizar la configuración necesaria para que el usuario Jenkins (desde le cual se ejecuta la aplicación) tenga los permisos necesarios para acceder al repositorio. No sera necesario crear un nuevo usuario en Bitbucket exclusivo para Jenkins ya que se puede configurar una clave ssh otorgando acceso de solo lectura mediante una Deployment Key. El primero paso sera iniciar sesión con el usuario Jenkins, pero por defecto viene desactivado así que tendremos que habilitar el inicio de sesión modificando el fichero /etc/passwd

Una vez tengamos ubicada la linea del usuario Jenkins, cambiaremos /bin/false por /bin/bash para poder iniciar sesión con dicho usuario.

1
2
3
4
5
sudo su - jenkins
cd .ssh
ssh-keygen -t rsa -C "jenkins-ci@nuestro-host.com"
git config --global user.email "jenkins-ci@nuestro-host.com"
git config --global user.name "Jenkins CI"

Por ultimo queda asegurarnos que Jenkins tiene permisos para acceder a las herramientas proporcionadas por el SDK de Android, es decir que tiene permisos de lectura en Android-SDK/tools/

Ya terminamos con la configuración en el lado del cliente, solo queda agregar la clave creada en Bitbucket para eso accedemos al panel de administración de nuestro proyecto en Bitbucket creamos una Deploymente key nueva y pegamos el contenido del fichero /var/lib/jenkins/.ssh/id_rsa.pub
Si el repositorio no esta en la lista de host conocidos (.ssh/known_hosts) debemos clonar el repositorio manualmente en una carpeta temporal y cuando se nos pregunte si queremos añadirlo a la lista de host conocidos tendremos que decir que si, ya que Jenkins no es capaz de gestionar dicho escenario.

Y por hoy eso es todo, en el próximo articulo veremos como crear pruebas automatizadas con Jenkins.