Montando un entorno de integración continua local para Apps mobile (iOS,Android)

0
1610

Índice de contenidos

  1. Introducción
  2. Entorno
  3. Configuración
  4. Xcode bots
  5. Jenkins
  6. Android SDK
  7. Configurando Jenkins
  8. Conclusiones

1. Introducción

Hoy en día existen muchas soluciones para proveer a los desarrollos mobile de un entorno de integración continua. En muchos casos, lo más fácil, menos costoso, más mantenible y más rápido es utilizar servicios de terceros (SaaS) como puedan ser Bitrise, Buddybuild, etc, que se conectan con nuestro repositorio en la nube.

Para bien o para mal, en función del cliente con el que nos toque trabajar, es posible que no podamos usar ninguno de estos servicios, bien porque el propio cliente no lo apruebe o a consecuencia de sus propias restricciones de seguridad (un repositorio privado sin acceso exterior y sin permiso para conectar vía VPN por ejemplo). Ante ese panorama tenemos dos opciones:

  • No tener integración continua (opción mala)
  • Montar nuestro propio entorno de integración continua (opción menos mala)

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Mac mini (2018) (3 GHz Intel Core i5, 16 GB 2667 MHz DDR4)
  • Sistema Operativo: Mac OS X Catalina 10.15.3
  • Jenkins 2.204.5
  • Fastlane 2.143.0
  • Xcode 11.3.1
  • Android SDK (command line tools) latest

3. Configuración

En el caso del desarrollo backend no es tan inusual que los equipos monten sus propios entornos de integración continua (en adictos tenemos unos cuantos tutoriales al respecto sobre Jenkins), pero en el caso del desarrollo mobile hay alguna que otra limitación.

Nuestra App tiene versiones nativas en iOS y Android. Para poder compilar la App de Android, necesitaremos tener instalado el SDK en nuestro servidor. En el caso de iOS, además necesitamos sí o sí que nuestro servidor ejecute macOS, es imposible a día de hoy compilar cualquier App de iOS desde otro sistema operativo. Así pues, se decidió un Mac Mini como servidor de integración continua tanto para la App de Android como la de iOS. Para ello en nuestro Mac Mini necesitamos lo siguiente:

  • Xcode: Se encargará de la compilación de la App de iOS y actuará como Xcode server para pasar los tests.
  • Android SDK: Necesario para poder compilar la App de Android
  • Jenkins: Se utilizará para pasar los tests de Android y en general para automatizar cualquier otra tarea, como la generación de betas nightly.
  • Fastlane: Utilidad muy conocida en el mundo mobile, sobre todo en iOS para ayudar a realizar tareas. En nuestro caso la utilizamos para generar las betas de iOS y Android y desplegarlas a nuestra plataforma de distribución de betas.

4. Xcode Bots

Para pasar los tests de iOS, en nuestro caso hemos optado por utilizar bots los bots de Xcode. Los bots de Xcode tienen un comportamiento peculiar, por una lado el server (en nuestro caso el Mac Mini) se encargará de compilar y ejecutar los tests pero el Bot se crea desde nuestro equipo.

Lo primero que debemos hacer es habilitar Xcode server en nuestro servidor, para ello abrimos Xcode -> Preferencias -> Server & Bots, y ahí activamos el server.

"XcodeServer"

Una vez activado Xcode Server, en local configuramos Xcode para que se conecte con nuestro server en Xcode -> Preferences -> Accounts

"XcodeServer"

Con esto ya podemos crear el bot desde nuestra máquina local en Product -> Create bot, en el que un asistente nos guiará paso a paso. Nos preguntará que si queremos añadir el servidor como miembro del equipo para gestionar el firmado, el repositorio, el esquema, las acciones a realizar (tests, cobertura, etc) y las acciones posteriores.

5. Jenkins

Para simplificarnos la vida, lo más fácil es en el caso de macOS es instalar Jenkins con brew.

brew install jenkins

Podemos cambiar la configuración (ip, puerto, etc) desde el fichero:

/usr/local/Cellar/jenkins/2.x.x/homebrew.mxcl.jenkins.plist (reemplazar 2.x.x por la versión que corresponda)

Si además queremos que se ejecute al iniciar sesión también podemos añadirlo como daemon con:

brew services start jenkins

Una vez instalado deberíamos poder acceder a Jenkins desde nuestro navegador (por defecto http://localhost:8080).

La primera vez que arrancamos Jenkins tendremos que seguir los pasos que nos indique para completar la instalación.

6. Android SDK

Antes de que Jenkins pueda pasar los test de Android, debemos instalar el SDK de Android. No es necesario descargar Android Studio completo, solo nos interesa el SDK. Para ello accedemos a https://developer.android.com/studio#downloads, y en «Download options», bajo «Command line tools only» podremos descargar el zip correspondiente para macOS.
Una vez descargado lo descomprimimos donde más nos convenga (en nuestro caso lo hemos dejado en el home de jenkins ~/.jenkins). Tendremos que aceptar las licencias, para ello abrimos una terminal, nos desplazamos hasta el directorio del SDK, en nuestro caso:

~/.jenkins/android_sdk/tools/bin

Y ejecutamos:

./sdkmanager –licenses

Nos preguntará si aceptamos las condiciones. Esto es necesario o si no fallará cuando intentemos compilar nuestra App Android desde Jenkins. Con esto ya deberíamos ser capaces de crear nuestros jobs de Jenkins para pasar los tests.

7. Configurando Jenkins

Empezaremos creando la variable global ANDROID_HOME. Para ello desde Manage Jenkins -> Configure System, bajo Global properties creamos una variable ANDROID_HOME apuntando a nuestro SDK.

"Jenkins"

Tambien nos aseguramos de tener instalados los plugins de Gradle, HTML Publisher Plugin y Text-finder desde Manage Jenkins -> Plugins. Adicionalmente también podemos instalar algún plugin para notificar sobre los resultados de los jobs en función a nuestras preferencias/recursos (por ejemplo, el de Slack).

Con esto ya deberíamos poder crear nuestro job, para ello desde el dashboard principal de Jenkins, pulsamos New Item -> Freestyle Project. Configuramos el repositorio, los build triggers, y pulsamos Add build step -> Invoke gradle script. Marcamos Use Gradle Wrapper e indicamos el task de Gradle con el que pasar los tests.

"Jenkins"

Para visualizar los resultados de una forma más cómoda, en Post-build actions, añadimos Publish HTML reports, indicando la carpeta de nuestro proyecto en la cual se almacenan los resultados de los tests.

"Report"

Por último, en nuestro caso para que pase todos los tests y no se interrumpa al primer fallo, en nuestro fichero build.gradle tenemos configurado lo siguiente:

testOptions {
   unitTests.returnDefaultValues = true
   unitTests.all {
       setIgnoreFailures(true)
   }
}

Esto aunque por una parte permite que el job de Jenkins pase todos los tests y nos diga cuales pasan y cuales no hace que el job se marque como estable a pesar de que fallan tests. Como solución rápida optamos por utilizar el plugin de Jenkins «Text-finder» para identificar cuando no han pasado todos los tests.

"Finder"

Con esto ya seríamos capaces de pasar los tests en nuestra App Android

8. Conclusiones

El tener que configurar uno mismo su propio entorno de integración continua es un proceso bastante arduo, complicado y además requiere armarse de paciencia y un mantenimiento periódico. En la parte positiva es que ofrece mucha flexibilidad, ya que puedes utilizar cualquier herramienta que tengas a tu alcance para automatizar aquellas tareas que uno se proponga.

Si para colmo de males el cliente cuenta con un proxy esa dificultad se eleva al cuadrado, aunque se puede paliar con herramientas como SquidMan para no tener repartidos las credenciales por varios scripts diferentes.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad