Table of Contents
CI y CD es una práctica de desarrollo de software que la mayoría de los desarrolladores de móviles en proyectos de equipo utilizan a diario, sin embargo, la mayoría de las veces las prácticas de control de versiones (o estrategia de ramificación de git), así como las pruebas automatizadas / despliegue ya está establecido y sólo requerirá pequeños cambios, si acaso. Por otro lado, cuando se trabaja en proyectos individuales o personales la configuración de nuestros propios pipelines de CI y CD puede parecer excesiva si no es con un motivo de aprendizaje o requisito del cliente.
Como resultado, muchos desarrolladores móviles pueden sentir que la CI y la CD quedan fuera de su campo de experiencia, y tal vez sin el uso de una plataforma DevOps móvil este podría ser el caso, pero la automatización de la CI y la CD móvil nunca ha sido más fácil a través del uso de estas plataformas.
Este artículo no se centrará en el CI y CD como concepto, sino en una visión general de la implementación del CI y CD a través de una plataforma DevOps móvil, haciendo uso de su simplicidad pero múltiples características configurables.
CI (Integración Continua)
Cuando hablamos de CI nos referimos a integrar o empujar regularmente el código en un repositorio de código compartido, y ejecutar automáticamente pruebas contra los cambios para detectar cualquier problema antes de ser fusionado en el repositorio compartido del equipo.
CD (Entrega/despliegue continuo)
En cuanto a la CD en un contexto de desarrollo de aplicaciones móviles, nos referimos a la construcción automática de nuestras aplicaciones y a su entrega a grupos de interés como QA, clientes, probadores… etc, o a su despliegue en una tienda de aplicaciones, cuando se dispara una determinada acción de CI.
Plataformas DevOps
Hay plataformas de control de fuentes muy populares como GitHub y Gitlab, y ambas proporcionan sus propias integraciones de tuberías de CI/CD. Estas son definitivamente soluciones viables, especialmente cuando su proyecto ya está siendo alojado allí, pero debido a su naturaleza multipropósito y multiplataforma, son más difíciles de entender cuando se trata del único aspecto de la integración y desarrollo continuo móvil.
El producto final de un archivo de configuración CI/CD es un archivo YML con las instrucciones que debe realizar una máquina externa. Las plataformas DevOps móviles nos permiten utilizar sus interfaces y una gran variedad de características para personalizar nuestro pipeline, de forma segura, ya que genera dicho archivo YML sin que tengamos que editar ninguna línea de código en el archivo. Asimismo, al modificar manualmente el YML también se actualizan los pasos de la UI que vemos en los flujos de trabajo. También proporciona informes de construcción e información más clara para el usuario, ya que la plataforma se centra únicamente en la integración CI/CD.
Dentro de CI/CD y más concretamente de las plataformas DevOps hay algunos conceptos comunes que conviene explicar:
Workflows – La herramienta principal que utilizaremos para personalizar la automatización. Los flujos de trabajo son un conjunto de pasos que la plataforma realiza para que implementemos un pipeline de CI/CD. Pueden incluir la construcción, las pruebas o el despliegue de una aplicación.
Steps – Los steps son las diferentes acciones que nuestra plataforma puede ejecutar dentro de un flujo de trabajo, estas pueden incluir acciones del repositorio git, ejecutar builds, desplegar un apk, modificar un archivo gradle o simplemente un script… etc. Hay varias posibilidades.
Triggers – Estas son las condiciones que activarán un flujo de trabajo. Lo más probable es que estén relacionados con empujes y solicitudes de fusión de una rama a otra.
Environment variables – Al igual que las variables de entorno estándar, estas variables se pueden almacenar en el espacio del proyecto para que estén ampliamente disponibles dentro de los flujos de trabajo. Los ejemplos podrían incluir directorios apk, nombres de paquetes, módulos de aplicaciones o variantes.
Secrets – similares a las variables de entorno, pueden ser necesarias en algunos pasos del flujo de trabajo, pero los secretos contienen información confidencial segura, por ejemplo, un token para acceder a las API de Play Store.
Code signing – Esto incluirá cualquier archivo necesario al liberar, como los archivos de almacén de claves, sus alias y contraseñas. Bitrise los almacenará y manejará de forma segura por usted.
YML file – Este es el archivo de configuración que has configurado a través de la interfaz de la plataforma. Está siempre accesible para que usted pueda leerlo y editarlo. Actuará como una guía de instrucciones para la máquina que ejecuta el pipeline. Este archivo debe ser almacenado en el repositorio de la aplicación (Bitrise puede gestionar esto por ti). Esto es útil en caso de que alguna vez se encuentre con problemas de configuración de CI, ya que puede revertir fácilmente a una versión anterior y actualizar el archivo YML en Bitrise.
Introducción a Bitrise
Hay muchas plataformas de desarrollo, pero Bitrise es un proveedor de móviles y podría decirse que es una de las plataformas más sencillas pero capaces de configurar. Además, obtienes unos cuantos créditos gratuitos para configurar tu pipeline y ejecutar unas cuantas compilaciones. Usted puede encontrar Bitrise en la parte superior de muchas listas de plataformas DevOps móviles.
Para casi todas las acciones de CI/CD de Android que quieras ejecutar, los documentos de Bitrise tienen una plantilla para ese flujo de trabajo, explicando qué pasos deberías añadir y por qué. Algunos pasos podrían considerarse repetitivos, ya que podrían ser necesarios en el flujo de trabajo independientemente de la plataforma o el objetivo, como por ejemplo: conectarse a nuestro VCS, clonar el repositorio del proyecto, extraer/pulsar cachés desde Bitrise para acelerar los tiempos de compilación, o desplegar los resultados de la compilación de vuelta a Bitrise. La mayoría de los otros pasos, sin embargo, serán definidos por el objetivo y la plataforma.
CI y CD en la práctica
Para integrar pipelines, primero necesitamos definir una estrategia de control de versiones o de ramificación en git. A continuación, describiremos una estrategia de muestra común* que nos ayudará a definir nuestros flujos de trabajo.
Este estará compuesto por las siguientes ramas y sus funciones:
- Desarrollo – Esta es la rama base con un código compartido estable para los desarrolladores del equipo. Cada vez que queremos añadir código, revisamos esta rama y empujamos o solicitamos los cambios de vuelta al desarrollo, activando pruebas unitarias y pruebas de interfaz de usuario que, cuando se superan, permitirán que el MR o el empuje tengan éxito.
- Staging – Cuando queramos que nuestro código pase un chequeo de QA fusionaremos el desarrollo en staging, los QAs solo deben usar esta rama para pasar sus pruebas. Esta etapa podría generar una compilación apk sin firmar para ser desplegada en una plataforma como firebase para que los probadores y/o clientes la prueben. No se requiere ninguna prueba en este flujo de trabajo ya que estaríamos repitiendo las mismas pruebas contra el mismo código base del flujo de trabajo de desarrollo.
- Release – Cuando nuestra aplicación está lista para ser desplegada podemos fusionar el staging con el release. Esto puede desencadenar un lanzamiento a la Play Store, pero aunque algunos podrían preferir actualizar manualmente la aplicación y omitir este desencadenante, también se puede utilizar para lanzarla a un canal alfa o beta, no necesariamente de producción.
*Esta estrategia es sólo un ejemplo y no la mejor práctica, proporciona una buena base y comprensión para que CI/CD se implemente a través de una plataforma de DevOps móvil. La mejor o más óptima estrategia puede depender de muchos factores y variará de un proyecto a otro.
Nuestros flujos de trabajo
A continuación, veremos cómo serían los tres flujos de trabajo diferentes de la estrategia de desarrollo, puesta en marcha y lanzamiento de la VC que hemos descrito anteriormente, y cómo se activan.
Flujo de desarrollo:
Role → Fusionar en esta rama significa añadir cambios al código que requieren que las pruebas pasen antes de la fusión, para asegurar que el nuevo código no rompa nada.
Trigger → Empujar o hacer una solicitud de fusión desde una rama de desarrollo/características (o cualquier otra) a la rama de desarrollo.
Specific Steps → Este flujo de trabajo ejecutará todos los pasos de Android necesarios para ejecutar Unit Tests y UI Tests si tenemos alguno. Para ello, podemos leer los documentos de Bitrise y averiguar qué pasos necesitamos y configurarlos en consecuencia. Por ejemplo, cuando realizamos pruebas para tests UI podríamos necesitar un paso AVD Manager, y si estamos usando un Emulador necesitamos un paso Wait for Android emulator.
Flujo del staging
Role → Fusionar en esta rama podría significar que un APK debe ponerse a disposición de un grupo de interés, como QA, o de un cliente.
Trigger → Empujar a la rama de staging
Specific steps → Este flujo de trabajo no incluye ningún paso de prueba, ya que no ha habido cambios en el código desde la base de código en desarrollo. Este flujo de trabajo se caracteriza por tener un paso de Android Build que genera un APK sin firmar y otro paso que lo distribuye a Firebase.
Para mostrar algunas características interesantes también hemos añadido pasos para modificar automáticamente el versionCode y el versionName de nuestra aplicación. Para ello necesitamos ejecutar un script que modificará el archivo Gradle dinámicamente, sin embargo, requiere que el nombre de la rama contenga el nombre de la versión deseada, y el versionCode sólo puede ser actualizado al número de compilación de Bitrise por lo que tiene limitaciones obvias.
Flujo de release
Role → Fusionar en esta rama significa que un APK debe desplegarse en la playstore, en un canal o canales.
Disparar → Empujar a la rama de release
Specific steps → Este flujo de trabajo se caracteriza por añadir un paso de Android Sign a la compilación (requerirá información de App Signing como el archivo JKS de Keystore y la clave y contraseña de alias) y otro paso para distribuir a la play store (requiere una cuenta de servicio de consola de play store configurada, así como un archivo con las notas de la versión si se desea, y otras especificaciones como canal, apk o bundle… etc)
Configuración de los triggers
Ahora que hemos definido nuestros flujos de trabajo, podemos configurar los desencadenantes, lo que significa especificar qué acciones desencadenarán cada flujo de trabajo. Bitrise tiene una pestaña para que podamos especificar estas acciones fácilmente.
Para el flujo de trabajo de desarrollo, establecemos un desencadenante para los pull requests (o pushes), en el que establecemos que cualquier rama que haga un PR en desarrollo iniciará el flujo de trabajo de desarrollo (llamado development_tests en la captura de pantalla):
La próxima vez que hagamos un PR, nuestra página web de VC mostrará un mensaje indicando que se está ejecutando un pipeline de Bitrise. Dependiendo del éxito de la construcción, mostrará un signo de visto verde o un error.
Para los flujos de staging (llamado staging_deploy_firebase_apk en la captura de pantalla) y release (llamado release_deploy en la captura de pantalla), tenemos disparadores similares. Ambos se activarán cuando haya una acción push en sus respectivas ramas:
¡Todo listo!
Una vez que hemos definido los flujos de trabajo y los triggers, hemos construido esencialmente nuestros pipelines, y lo único que debemos hacer es respetar la estrategia de ramificación para que el CI/CD se implemente correctamente.
No nos sumergimos en los detalles de cada paso de configuración y característica de la plataforma para mantenerlo corto y dulce, pero esperamos que este artículo proporcione una idea de cómo puede ser el simple CI/CD en un proyecto Android y las capacidades de las plataformas DevOps móviles.
Author
-
Problem solver, rather than engineer or Android developer. Like to engage me in challenges and the satisfying feeling they leave when completed. Although he specializes in Android development, ergo Java and Kotlin, he uses other languages and technologies on a daily basis, which for him is an opportunity to learn and better understand the industry he works in.
Ver todas las entradas
More to Explore