GitLab CI es un sistema de integración y entrega continua integrado en GitLab que automatiza la compilación, prueba e implementación de aplicaciones móviles mediante pipelines configurados en YAML. Según GitLab, 2024, la plataforma procesa más de 300 millones de pipelines mensualmente y admite runners en la nube y autoalojados.
Puntos clave
GitLab CI es parte de la aplicación unificada DevSecOps de GitLab, que abarca integración continua, entrega y despliegue. El sistema comenzó como proyecto independiente en 2012 pero luego se integró directamente en GitLab. El principio fundamental es la configuración como código mediante un archivo .gitlab-ci.yml en la raíz del repositorio. GitLab CI está disponible tanto en versión cloud SaaS como en instalación autoadministrada.
Para el desarrollo móvil, GitLab CI ofrece automatización de compilaciones APK e IPA, ejecución de pruebas instrumentadas, análisis estático de código, firma de aplicaciones y publicación en tiendas. La plataforma admite imágenes Docker para entornos personalizados, lo que permite preinstalar Android SDK, NDK, Xcode y otras herramientas. El Container Registry integrado simplifica el almacenamiento y la distribución de imágenes dentro del equipo.
La arquitectura de GitLab CI consta de tres componentes clave. GitLab Runner es un agente que ejecuta los jobs. Los runners pueden ser compartidos (proporcionados por GitLab), de grupo (para un grupo de proyectos) o específicos (para un proyecto). Cada runner se registra con un executor: Shell, Docker, Kubernetes o VirtualBox. GitLab Runner admite autoescalado para manejar picos de carga.
Un pipeline es un conjunto de stages ejecutados secuencialmente. Dentro de un mismo stage, los jobs se ejecutan en paralelo. Una estructura típica para un proyecto móvil es: build → test → deploy. Si un job en el stage test falla, deploy no se ejecuta. Se puede configurar la ejecución manual (when: manual) para el despliegue. También se admiten activadores de pipelines multiproyecto para escenarios CI/CD complejos entre repositorios.
El executor Docker es el más popular para CI/CD de aplicaciones móviles. Cada job se ejecuta en un contenedor Docker limpio, lo que garantiza aislamiento y reproducibilidad. Para compilaciones Android se usa la imagen android-sdk con SDK preinstalado; para iOS, un runner macOS con executor Shell.
El archivo .gitlab-ci.yml define un pipeline en formato YAML. Las secciones principales incluyen: image (imagen Docker), stages (lista de etapas), variables (variables de entorno), before_script (comandos antes de cada job) y los jobs con secciones script, artifacts, cache. GitLab CI admite include — la capacidad de incluir archivos YAML externos para reutilizar configuraciones comunes entre proyectos.
Las variables en GitLab CI pueden definirse en múltiples niveles: globalmente en la interfaz de usuario, en el archivo de configuración, en la configuración de grupo y de proyecto. La prioridad de las variables sigue una jerarquía: las variables de activador tienen la máxima prioridad, seguidas de las variables CI/CD de la interfaz y luego del .gitlab-ci.yml. Las variables pueden protegerse, haciéndolas accesibles solo para ramas y etiquetas protegidas.
image: openjdk:17-jdk-slim
variables:
ANDROID_SDK_VERSION: "35"
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
stages:
- build
- test
- deploy
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- .gradle/
El job generate-apk compila un proyecto Gradle y guarda el APK como artefacto. Los artefactos se transfieren entre stages — un job de deploy puede usar el APK de la etapa build. La retención de artefactos se configura mediante expire_in.
generate-apk:
stage: build
script:
- ./gradlew assembleRelease
artifacts:
paths:
- app/build/outputs/apk/release/
expire_in: 1 day
Al elegir entre GitLab CI y GitHub Actions para un proyecto móvil, la infraestructura del equipo es un factor clave. GitLab CI proporciona un Container Registry integrado para almacenar imágenes Docker con Android SDK. GitHub Actions depende de GitHub Packages o registros externos. GitLab también cuenta con SAST (Static Application Security Testing) integrado para análisis de vulnerabilidades de código.
GitLab CI ofrece un modelo de runners más flexible — admite executor Kubernetes, autoescalado e imágenes personalizadas. GitHub Actions gana en integración con el ecosistema GitHub y su marketplace de acciones. GitLab CI requiere más configuración manual para muchas tareas que GitHub Actions resuelve con acciones prefabricadas.
Desde la perspectiva de CI/CD móvil: GitLab CI es más adecuado para empresas que ya usan GitLab Self-Managed y necesitan runners autoalojados con Docker/Kubernetes. GitHub Actions es más conveniente para equipos pequeños en GitHub cloud que valoran las acciones listas y la facilidad de configuración.
| Característica | GitLab CI | GitHub Actions |
|---|---|---|
| Configuración | .gitlab-ci.yml | .github/workflows/*.yml |
| Runner | Autoalojado + compartido | Alojado + autoalojado |
| Executors | Docker, K8s, Shell | VM (Ubuntu, macOS, Win) |
| Marketplace de acciones | No (plantillas CI) | Marketplace (más de 15k acciones) |
| Compilación iOS | Runner macOS o K8s | Runner macOS alojado |
Un pipeline completo para Android incluye: lint, pruebas unitarias, compilación y despliegue en Firebase App Distribution. El pipeline utiliza una imagen Docker con Android SDK, almacenamiento en caché de Gradle y ejecución paralela de lint y test en la misma etapa. Este enfoque reduce el tiempo total del pipeline ya que las tareas lint y test son independientes entre sí.
Para proyectos iOS, la estructura del pipeline difiere debido a la necesidad de un runner macOS y firma de código. Un pipeline iOS típico incluye: instalación de CocoaPods o SPM, ejecución de pruebas en simulador, archivado del proyecto Xcode, exportación de IPA y carga en TestFlight. GitLab CI para iOS utiliza runners macOS — ya sean los runners SaaS de GitLab con limitaciones de tiempo o un runner autoalojado en un Mac Mini o MacStadium.
image: androidsdk/android-35:latest
stages:
- lint
- test
- build
- deploy
lint-check:
stage: lint
script: ./gradlew lint
unit-tests:
stage: test
script: ./gradlew test
assemble-release:
stage: build
script: ./gradlew assembleRelease
artifacts:
paths: [app/build/outputs/apk/release/]
deploy-firebase:
stage: deploy
script:
- firebase appdistribution:distribute
--app $FIREBASE_APP_ID
--token $FIREBASE_TOKEN
--groups testers
Optimizar los pipelines de compilación móvil en GitLab CI requiere atención al detalle. Una configuración adecuada de cache y artifacts puede reducir el tiempo de compilación varias veces. Para el análisis de rendimiento, GitLab proporciona CI/CD Analytics — un panel con métricas de duración de pipelines, carga de runners y cuellos de botella. Analice estas métricas regularmente para encontrar oportunidades de optimización. Configurar resource_group bloquea la ejecución paralela de pipelines — útil para evitar conflictos de despliegue.
La estrategia de ramas para CI también es importante. Se recomienda ejecutar el pipeline completo solo para las ramas main y release, y para las ramas feature — solo lint y pruebas unitarias. Esto ahorra minutos de runners y acelera la retroalimentación a los desarrolladores. GitLab CI admite workflow:rules — reglas condicionales para incluir o excluir jobs según la rama, archivos modificados o variables de entorno.
El almacenamiento en caché de dependencias es el método principal de aceleración. GitLab CI almacena en caché .gradle, Pods y node_modules entre ejecuciones. La clave de caché incluye $CI_COMMIT_REF_SLUG o un hash del archivo lock. El tiempo de compilación de un proyecto Android se reduce de 10–15 a 2–4 minutos con un caché adecuado. El caché puede ser distribuido — GitLab admite cache:key con fallback a claves anteriores.
Una imagen Docker con herramientas preinstaladas ahorra tiempo de instalación. Se recomienda crear una imagen personalizada con Android SDK, NDK y el nivel de API requerido. La ejecución paralela de jobs (lint, test, assemble) en diferentes stages reduce el tiempo total del pipeline. Las políticas de pull para imágenes (if-not-present) aceleran el inicio de los jobs. También se puede usar un proxy de dependencias para almacenar en caché imágenes a nivel de instancia de GitLab.
Otro aspecto importante de optimización es el uso de artefactos entre etapas. Los archivos pesados como APK e IPA deben transferirse mediante dependency en lugar de recompilarse en cada job. Para proyectos grandes con docenas de módulos, se recomienda habilitar Gradle Build Cache a nivel de pipeline y configurar un caché remoto en almacenamiento compartido. El timeout de cada job debe establecerse según el tiempo de compilación esperado — esto evita procesos colgados.
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- .gradle/
- app/build/
image:
name: registry.example.com/android-builder:3.5
pull_policy: if-not-present
Preguntas frecuentes
En GitLab.com, el plan gratuito incluye 400 minutos de CI/CD al mes y 5 usuarios. Premium ($29/mes) ofrece 10.000 minutos y más jobs paralelos. GitLab Self-Managed no tiene límite de minutos.
Use la imagen Docker preparada androidsdk/android-35 o instale el SDK mediante sdkmanager en before_script. En variables, especifique ANDROID_SDK_ROOT y ANDROID_NDK_HOME para el correcto funcionamiento de Gradle.
GitLab CI ofrece un Container Registry integrado, integración con Kubernetes y autoescalado autoalojado. GitHub Actions gana en cantidad de acciones listas y simplicidad para equipos pequeños.
Sí, pero iOS requiere un runner macOS. Puede usar los runners SaaS de GitLab para macOS (limitados) o configurar un runner autoalojado en un Mac Mini. GitLab no proporciona infraestructura macOS en la nube.
Mediante artifacts — los archivos de un job se transfieren a otro job dentro del pipeline. Mediante cache — para dependencias entre ejecuciones. Mediante variables CI/CD — para valores de cadena y tokens.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también