Uno de los principales problemas con los que se suele encontrar un equipo de desarrolladores que trabaja en un mismo proyecto es el hecho de que, al funsionar el código de cada uno de ellos, se puedan dar conflictos entre código de los diferentes desarrolladores, errores… lo que hace que este proceso sea lento. Para solventar este punto entra en acción la Integración y distribución continua para automatizar el despligue de aplicaciones. En este artículo vamos a var cómo automatizar el despliegue de aplicaciones iOS con Bitrise.

Introducción

En un artículo anterior ya vimos qué es la Integración Continua (CI, Continuous Integration), la Distribución Continua (CD, Continuous Delivery) y la Implementación Continua (CD, Continuous Deployment), y cómo se podía realizar con una nueva herramienta de GitHub: GitHub Actions.

A modo de resumen:

  • Integración Continua. La Integración Continua (CI) permite que los diferentes desarrolladores suban y fusionen los cambios del código en una misma rama del repositorio de forma frecuente. Una vez subido el código, se procede a su validación de forma automática mediante pruebas unitarias y de integración (tanto el código subido como del resto de componentes de la aplicación). En caso de que se produzca algún error, este se puede corregir de forma más sencilla.
  • Distribución Continua. En la Distribución Continua (CD) el código nuevo introducido y que ha pasado el proceso de Integración continua se publica automáticamente en un entorno de producción (esta implementación puede requerir la aprobación manual). Lo que se pretende, es que el código del repositorio esté siempre en un estado que permita su implementación en un entorno de producción.
  • Implementación Continua. En la Implementación Continua (CD), todos los cambios en el código que han pasado por las dos etapas anteriores se implementan automáticamente en producción.

Uso de Bitrise

Tal como se vio en el artículo ue hemos comentado antes, existen numerosas herramientas para configurar y realizar todo el proceso de integración y distribución continuas (Jenkins, CircleCI, Visual Studio App Center…). En este caso vamos a ver el funcionamiento de Bitrise.

Lo que me ha gustado de Bitrise es:

  • Esta diseñada específicamente para aplicaciones.
  • La experinecia de usuario en la página web es muy buena.
  • Permite configurar fácilmente los flujos de trabajo.
  • Permite desplegar las compilaciones a Testflight y a la App Store.

Bitrise es una herramienta de pago, pero hay una versión gratuita para que podamos probarla:

Bitrise princing

Registro en Bitrise

El registro en Bitrise es sencillo. Simplemente accedemos a su página web, y seleccionamos ‘Get Started for Free‘:

Acceso Bitrise

En la página de registro podemos utilizar diferentes opciones, empezando por utilizar cuentas en GitHub, Bitbucket o GitLab.

Registro Bitrise Github

En este caso utilizaremos el registro mediante GitHub, ya que será el repositorio que relacionemos con Bitrise.

Registro Bitrise Github

Una vez registrados, nos aparecerá una pantalla en la que se nos indica que no hemos añadido ninguna aplicación todavía y nos invita a hacerlo.

Añade App

Añadir una aplicación a Bitrise

Para poder probar Bitrise, en primer lugar creamos un proyecto en Xcode (al que denominaremos BitriseTest) y que subimos a un repositorio (en este caso, a GitHub). Es importante editar el esquema y activar la opción ‘Shared‘, lo que evitará problemas de validación más adelante al añadir la aplicación a Bitrise. Además, al crear el proyecto seleccionaremos la casilla de tests unitarios, que nos permitirá probar el flujo de trabajo con Bitrise cuando falla algún test.

Cuando seleccionamos añadir una aplicación, se nos mustran una serie de pasos que hay que ir realizando para añadir y configurar el flujo de trabajo.

Privacidad. En primer lugar seleccionamos el tipo de privacidad para el proceso de la aplicación (público o privado). En este caso seleccionamos privado.

Bitrise select project

Repositorio. El siguiente paso es seleccionar el repositorio que contiene la aplicación. Como tenemos la cuenta enlazada con GitHub, aparecen todos nuestros respositorios (si tenemos muchos proyectos en el repositorio, podemos hacer una búsqueda):

Bitrise project selection

Configuración de acceso al repositorio. Cuando pregunta si queremos añadir un repositorio adicional (Cocoapods, submódulos, etc.), seleccionaremos ‘No, auto-add SSH key‘, ya que se trata de un proyecto simple. En caso contrario, deberemos copiar la clave SSH suministrada por Bitrise y añadirla en Github, en el apartado SSH and GPG Keys.

Bitrise SSH Key

Selección de la rama del repositorio. El siguiente paso es indicar la rama del repositorio que contiene la configuración del proyecto (en este caso, master).

Bitrise branch selection

Validación. Una vez añadida la rama del repositorio, Bitrise realiza un proceso de validación (la validación fallará si no hemos activado la opción Shared en el proyecto de Xcode). Durante este proceso Bitrise busca sus archivos de configuración y configura la aplicación en función de estos (en el caso de una aplicación iOS, busca los ficheros .xcodeproj o .xcworkspace.

Bitrise app validation

Configuración de la construcción. Una vez validado el proyecto, seleccionamos la configuración de construcción del proyecto. En este caso el proyecto es BitriseTest.xcodeproj, el nombre del esquema es BitriseTest, como método de exportación de la .ipa utilizamos development y como sistema de construcción, Xcode 11.4.x en macOS 15.4 (Catalina). Se recomienda seleccionar un entorno que sea igual al que utilizamos para desarrollar la aplicación.

Adición de un icono. En este paso podemos añadir un icono a la aplicación en Bitrise.

Bitrise select icon

Configuración de Webhook. Finalmente, podemos añadir un webhook. Los webhook son procesos (callbacks) definidos por el usuario que se activan por algún evento, como enviar código a un repositorio. En este caso utilizaremos la opción ‘Register a Webhook for me!‘.

Primera compilación. Una vez acabado todo el proceso de configuración, Bitrise lanza la primera compilación.

Bitrise ending process

Tal como se observa, la compilación de ha producido sin errores, ya que se trata de un proyecto simple al que no se había añadido tests unitarios. Vamos a ver que ocurre ahora si añadimos un par de tests unitarios simples.

Pruebas con tests unitarios

Vamos a realizar un par de tests sencillos, que se basarán en testear un modelo de datos. Para ello creamos un nuevo fichero en el proyecto al que llamaremos BitriseModel.swift, y que contendrá el siguiente código:

Es decir, un modelo de datos con tres parámetros: username y repository de tipo String, y numberOfProjects, de tipo Int.

Ahora accedemos al fichero BitriseTestTests.swift que se ha creado al generar el proyecto, y que nos permitirá añadir algunos test unitarios.

En primer lugar creamos una instancia de nuestro modelo de datos con algunos datos:

A continuación, añadimos un par de tests sencillo, en los que comprobaremos que la instancia del modelo que hemos creado contiene un username (no está vacío) y que su valor es ‘user‘. Esto lo hacemos a continuación de la función tearDownWithError():

Si ejecutamos los tests unitarios en Xcode (command + U), vemos que no se produce ningún error.

Xcode no error test

Ahora lo que hacemos es subir estos cambios al repositorio. Simplemente accedemos al directorio del proyecto en el terminal y escribimos (también se puede usar cualquier otro tipo de herramientas que permitan la gestión de repositorios):

Si tras el último paso accedemos a la consola de Bitrise observamos cómo se está ejecutando un proceso de compilación.

Bitrise compiling

Cuando finaliza, vemos que la compilación del proyecto no ha dado errores y que se han pasado todos los tests.

Tests fallidos

Vamos a ver qué pasa ahora si uno de los test unitarios da error, para ello modificamos el primero de los test, y en vez de comprobar que el campo username no está vacío, comprobaremos que está vacío (eliminamos el signo ! delante de model.username.isEmpty. Ejecutamos los tests en Xcode y observamos que, efectivamente, ese test falla:

Ahora, volvemos a subir este código nuevo al repositorio, para ver cómo se comporta Bitrise. En la consola de Bitrise vemos que se está compilando la aplicación:

Pero que al final se ha producido un error (está en rojo):

Si ahora seleccionamos la compilación se despliega el registro del proceso, donde podemos observar, entre otras muchas cosas, qué test ha fallado:

Revisión del flujo de trabajo (workflow)

Pero, ¿qué ha ocurrido durante este flujo de trabajo? Para comprobarlo, nos desplazamos al final de la página que nos muestra el log del proceso, y seleccionamos del botón Open Workflow Editor, que se encuentra a la izquierda.

En este punto nos aparece una interfaz en la que podemos observar numerosas opciones.

Workflow bitrise page

En primer lugar observamos a la izquierda la opción WORKFLOW y un pequeño menú que nos permite seleccionar entre primary y deploy (son los flujos de trabajo por defecto):

  • primary. Se trata de un flujo de trabajo predeterminado que presenta una serie de pasos que incluyen, por ejemplo, clonar la aplicación desde el repositorio, ejecutarla y realizar los test unitarios o de UI.
  • deploy. Este flujo es bastante similar al anterior, salvo que se añade el proceso de despliegue de la aplicación en iTunes Connect (TestFlight o App Store), en este caso.
workflows

Podemos modificar cualquiera de estos procesos simplemente seleccionando los botones con el signo ‘+’ que aparece entre cada uno de los pasos del flujo de trabajo. Esto hace que se despliegue una ventana a la derecha, con numerosas posibilidades de modificación:

Bitrise workflow customization

En esta página, además de modificar los flujos de trabajo existentes podemos crear otros nuevos.

Despliegue de aplicaciones con Bitrise

Acabamos de ver que, por defecto, hay dos tipos de flujo de trabajo: el primario (que es el que nos ha serido para hacer las pruebas de los tests unitarios) y el de despliegue. Vamos a centrarnos en este último y ver cómo podemos desplegar una aplicación en iTunes Connect de forma automática.

Si nos fijamos, en el flujo de trabajo deploy, podemos observar un paso denominado ‘Certificate and profile installer‘. Tal como indica la documentación de Bitrise, este paso no requiere que lo configuremos, solo hay que subir un certificado .p12 y, en el caso de que que este certificado tenga contraseña, crear una variable de entorno (Secret Env Var) con la contraseña.

Pero, y si como en la mayoría de mis proyectos utilizamos la firma automática de código (Autommatically manage signing). Entonces hemos de sustituir este paso del flujo de trabajo por el paso denominado iOS Auto Provision:

Bitrise workflow ios auto

Una vez añadido, el apartado Distribution type indicamos, del menú desplegable que aparece, app-store (también tenemos las opciones de development, ad-hoc y enterprise).

Seguidamente hemos de añadir un paso que permita incrementar automáticamente el número de la compilación, para evitar problemas a la hora de subir la aplicación a iTunes Connect. Para ello añadimos el paso Set Xcode Project Build Number:

Bitrise workflow ios build number

Aquí, en el apartado Info.plist file path indicamos dónde se encuentra el archivo Info.plist del proyecto. En este caso es:

Luego, en nuestro proyecto hemos de cambiar el campo CFBundleVersion por:

Ahora, el siguiente paso solo es necesario en el caso de que nuestro proyecto tenga dependencia de CocoaPods o Carthage. Si es el caso, hemos de añadir y configurar, según el tipo de dependencia Run CocoaPods Install y/o Carthage:

Bitrise workflow cocoapods
Bitrise workflow Carthage

Finalmente, añadimos el paso Deploy to iTunes Connect – Application Loader, en el que se subirá el ichero .ipa a iTunes Connect.

En este paso habremos de añadir las credenciales de nuestro proyecto, como el Apple ID y la contraseña, que es información sensible (aunque el propio proceso nos indica cómo ocrear variables de entorno secretas).

El proceso de despliegue queda de la siguiente forma:

Adición de los certificados

Una vez que hemos moficado el flujo de trabajo para el desplieque de la aplicación, pasamos a la pestaña Code Signing (que se encuentra al lado de la de Workflows). En este punto deberemos añadirlos certificados; simplemente habremos de seguir los pasos que nos indica Bitrise.

Secretos y Variables de entorno

En estas dos pestañas encontramos (y podemos editar o crear nuevas) auqquelas variables que utilizamos en el proceso.

Disparadores (triggers)

Aunque en Bitrise se pueden ejecutar flujos de trabajo de forma manual, los disparadores (triggers) son los desencadenantes de que se ejecuten de forma automática flujos de trabajo. Por ejemplo, un disparador puede ser hacer push a una rama determinada de un repositorio. En Bitrise se pueden difinir disparadores para eventos de push, pull request o tag.

Así, por ejemplo, en el proyecto que hemos hecho de muestra, podríasmo definir un disparador para cuando hagamos push a la rama devel se ejecute el flujo de trabajo primary, mientras que si el push es a la rama de release, se ejecute el flujo de trabajo deploy.

Push trigger example

De la misma forma podemos establecer disparadores para eventos de pull request (en este ejemplo, de devel a release):

O de etiquetado (tag) de ramas:

Tag trigger example.

Stack

En esta sección podemos ver (y modificar) la máquina virtual que se utilizará para ejecutar la aplicación. Incluso podemos seleccionar configuraciones diferentes para los diferentes flujos de trabajo.

Bitrise stack configuration

bitrise.yml

Es el fichero de configuración de Bitrise, que podemos descargar y modificar si queremos utilizarlo en nuestra propia máquina gracias a Bitrise CLI. Bitrise CLI es la versión open source y offlne de Bitrise para ejecutar flujos de trabajo en nuestra propia máquina.

Fitrise bitrise.yml file

Conclusiones

En este artículo solo se ha visto como realizar de forma sencilla la automatización del despliegue de una aplicación iOS. Bitrise contiene numerosas posibilidades de configuración y trabajo (por ejemplo, podemos enlazar los flujos de trabajo a una cuenta de Slack para que nos informe cuando acaba un flujo de trabajo y su estado).

Tras realizar algunas pruebas con Bitrise algunos de los puntos a favor y en contra que he encontrado son:

Puntos a favor

  • Facilita la automatización de los procesos de integración y despliegue de las aplicaciones.
  • Muy configurable.
  • Gran biblioteca de bloques para la construcción de flujos de trabajo.
  • Buena documentación.
  • Específico para mobile (iOS, Android).

Puntos en contra

  • A veces la configuración puede ser un poco complicada.
  • Lentitud en algunas compilaciones (el proyecto del ejemplo, extremadamente simple, tarda unos 3 min en ejecutarse). Esto puede ser un problema para grandes proyectos si se tienen cuentas Free o Developer, que tienen un límite de 45 min.

Categorías: CI/CDSwift

0 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Sígueme en Feedly
shares