Uno de los pilares básicos de Apiumhub es nuestro compromiso con el cliente de entregar siempre software que funcione (working software) con los niveles más altos de calidad posible.
Para poder llevar a cabo trabajamos con sistemas, en este caso, de Integración continua en iOS que nos permiten tener disponible para el cliente versiones de sus aplicaciones, probadas y testeadas y que se puedan pasar a producción con la mayor rapidez posible.

Para llevar a cabo esta tarea, desarrollamos a través de una serie de plugins de Jenkins una DSL que nos permite disponer de las últimas versiones de software después de haber pasado los test de integración, test funcionales y test de QA y que estén listas y validadas para distribuirlas cuando el cliente lo requiera. Esto lo que nos permite es tener ciclos de desarrollo cortos con una entrega de valor importante y un feedback muy rápido por parte de los usuarios finales sobre cualquiera de las nuevas funcionalidades añadidas a una aplicación del cliente.

Gracias a la experiencia de varios años trabajando con varios clientes y al gran conocimiento acumulado, hemos decidido que era hora de incorporar nuevas plataformas a nuestro sistema de integración continua. En el caso que nos ocupa hablaremos de cómo hemos añadido a nuestro sistema la plataforma de iOS utilizando para ello la herramienta Fastlane y el sistema de integración continua Jenkins, Integración continua en iOS

 

Integración continua en iOS usando Fastlane

 

Fastlane es una herramienta para gestión de ciclos de integración continua (empaquetado y despliegue) tanto en iOS como en Android. Fue creada por Felix Krouse y está basada en ruby.
La necesidad de crear una herramienta de este estilo, tuvo origen en los largos, repetitivos y enrevesados procesos de empaquetado de aplicaciones para dispositivos móviles primero en iOS y después se añadiría el soporte a Android.

La base fundamental de Fastlane es que nos permite crear una especie de ‘scripts’ que denominan ‘Lanes’ donde se ejecutan una serie de ‘comandos’ preprogramados llamadas ‘Actions’. Existen una serie de actions por defecto en la herramienta, que nos permiten gestionar diferentes aspectos del ciclo de vida de las aplicaciones móviles. Las actions, como comentamos antes se pueden agrupar en lanes que nos permiten crear scripts a medida según las necesidades que queramos cubrir del ciclo de vida de la aplicación.

Ejemplo de una lane:


lane :beta do
      increment_build_number
      gym                       # Build your app
      testflight                # Upload to TestFlight
end

Esta lane se llama beta y lo que hace es: incrementar el número de la build, hace el empaquetado (genera el iPA) de la aplicación y lo envía a Testflight.
No nos vamos a extender mucho más en explicar cómo funciona Fastlane ya que toda la documentación está muy bien recogía en su web y hay muchos ejemplos por la red. 

Para poder instalar Fastlane debemos tener en cuenta algunas cosas:

1.Tener la versión adecuada de ruby, para ello ejecutaremos el comando 

                   ruby -v en un terminal

Es importante controlar la versión de ruby porque por defecto OSX trabaja con la versión 2.0 y esto provoca muchos problemas a Fastlane por lo que os recomendamos instalar el sistema de gestión de versiones de ruby rvm. En caso de que tengáis problemas con la versión de ruby podéis acudir a tutoriales como este o hacer una búsqueda rápida en Google(‘update osx ruby version’).

2. Instalar las xcode tools  

                    xcode-select –install

 

Fastlane se puede instalar a través de:

  • Home Brew (brew cask install fastlane)
  • Fabric
  • Ruby, como un gema (sudo gem install -n /usr/local/bin fastlane –verbose)

 

Una vez instalado Fastlane en la máquina, lo que tenemos que ir a la carpeta del proyecto donde queremos añadir Fastlane y ejecutar el comando:

                    fastlane init

Lo que creará todas las dependencias y configurará el proyecto para que soporte Fastlane. Una vez terminado el proceso, en tu proyecto debería contener una carpeta llamada fastlane y dentro existen 2 ficheros importantes:

  • Appfile: que contiene los identificadores del proyecto y del equipo y del apple id usado para gestionar las credenciales y la conexión con iTunes.
  • Fastfile: aquí es donde se definen las lane. Por defecto suele traer las más comunes que son las lane de beta y release. En este fichero es donde se configuran todos los procesos del ciclo de vida y deploy de la aplicación y donde se hace toda la gestión.

En Apiumhub tenemos configuradas 2 lane, una que llamamos build que lo que hace es pasar los test usando el action scan y después usa el action gym para empaquetar la aplicación. La otra la llamamos release que lo que hace es enviar la aplicación a la Apple Store para publicar.

Lane build:


lane :build do
      scan(scheme: "Plannear")
      gym(scheme: 'Plannear', export_method: 'app-store')
end
	

Lane release
      lane :release do
      deliver(force: true)
end

Si el cliente quiere probar su aplicación internamente antes de enviarla a Apple, usamos otra lane denominada preprod que envía la aplicación a testflight y la distribuye automáticamente a todos los usuarios añadidos como testers.

 

Integración continua en iOS: configuracion Jenkins

 

Una vez que ya tenemos la herramienta de Fastlane configurada y probando que funciona en el proyecto, lo que hacemos es configurar el Jenkins para que ejecute las tareas de la herramienta de forma automática (En este ejemplo lo que hemos hecho es configurar una máquina local de un usuario como máquina de test, pero esto podría hacerse de igual forma con cualquier equipo que tuviera instalado OSX y configurado correctamente el Fastlane).

Lo primero que hicimos fue definir un nodo de ejecucion con las siguientes caracteristicas:

El nodo remoto se ejecutará a través de web start, por lo que en la máquina en cuestión tenemos que instalar java y la web start tool. En el apartado remote root directory es la carpeta donde está instalado el proyecto de iOS que contiene el Fastlane.
El siguiente paso es definir nuestra pipeline (es necesario tener instalado el plugin build pipelines) que tiene la siguiente configuración:

 

La parte en la que nos tenemos que fijar en este caso es la que pone initial Job que es donde le diremos a Jenkins que jobs queremos que ejecute en esta pipeline.
Por último llegamos a la parte más importante de la configuración de Jenkins, donde definimos el job que se ejecutará en la máquina en remoto,cada vez que se lance la tarea de la pipeline.
La configuración del job es bastante estándar de Jenkins, donde se definirá que primero se descargue el proyecto de github y después ejecute la lane de Fastlane adecuada. La configuración seria similar a esta

 

La parte más importante en este caso es el script de shell final. La particularidad de este script radica en que es necesario configurar correctamente las variables de entorno de ruby para que la ejecución remota de Fastlane trabaje correctamente.
Una vez tenemos definido el conjunto de pipeline → task → job ya tenemos automatizado todo el proceso y simplemente con configurar la ejecución mediante un schedule en jenkins podemos ejecutar cualquier proceso del ciclo de vida de la aplicación de forma automática.

En nuestro caso normalmente definimos una pipeline para build y una para release y podemos hacer un seguimiento muy rápido del proceso en Jenkins que se vería de una forma similar a esta:

Esto también ayuda a que si el cliente lo solicita podamos configurar una máquina en sus instalaciones que ejecute todo el proceso, porque en nuestro caso todas las configuraciones de jenkins se guardan en un fichero groovy que se puede versionar, lo que nos permite un rápido despliegue como de integración continua en iOS, en cualquier entorno con las mismas características.

 

Suscríbete a nuestro newsletter para estar al día de los eventos, meet ups y demás artículos!

 

Si este artículo sobre Integración continua en iOS te gustó, te puede interesar:

 

F-Bound en Scala

Tendencias en aplicaciónes móviles

Patrón MVP en iOS

Debugging con Charles Proxy en Android emulator

Por qué Kotlin?