GitLab CI è un sistema di integrazione e consegna continue integrato in GitLab che automatizza la compilazione, il test e il deployment di applicazioni mobile tramite pipeline configurate in YAML. Secondo GitLab, 2024, la piattaforma elabora oltre 300 milioni di pipeline mensilmente e supporta sia runner cloud che self-hosted.
Punti chiave
GitLab CI è parte dell'applicazione unificata DevSecOps di GitLab, che comprende integrazione continua, consegna e deployment. Il sistema è nato come progetto separato nel 2012 ma è stato poi integrato direttamente in GitLab. Il principio fondamentale è la configurazione come codice tramite un file .gitlab-ci.yml nella radice del repository. GitLab CI è disponibile sia in versione cloud SaaS che in installazione self-managed.
Per lo sviluppo mobile, GitLab CI offre automazione di compilazioni APK e IPA, esecuzione di test strumentati, analisi statica del codice, firma delle app e pubblicazione negli store. La piattaforma supporta immagini Docker per ambienti personalizzati, consentendo la preinstallazione di Android SDK, NDK, Xcode e altri strumenti. Il Container Registry integrato semplifica l'archiviazione e la distribuzione delle immagini all'interno del team.
L'architettura di GitLab CI si compone di tre componenti chiave. GitLab Runner è un agente che esegue i job. I runner possono essere condivisi (forniti da GitLab), di gruppo (per un gruppo di progetti) o specifici (per un progetto). Ogni runner viene registrato con un executor: Shell, Docker, Kubernetes o VirtualBox. GitLab Runner supporta l'auto-scaling per gestire i carichi di punta.
Una pipeline è un insieme di stages eseguiti sequenzialmente. All'interno di uno stage, i job vengono eseguiti in parallelo. Una struttura tipica per un progetto mobile è: build → test → deploy. Se un job nello stage test fallisce, deploy non viene attivato. È possibile configurare l'attivazione manuale (when: manual) per il deployment. Sono supportati anche trigger di pipeline multi-progetto per scenari CI/CD complessi tra repository.
L'executor Docker è il più popolare per il CI/CD di app mobile. Ogni job viene eseguito in un contenitore Docker pulito, garantendo isolamento e riproducibilità. Per le build Android si utilizza l'immagine android-sdk con SDK preinstallato; per iOS, un runner macOS con executor Shell.
Il file .gitlab-ci.yml definisce una pipeline in formato YAML. Le sezioni principali includono: image (immagine Docker), stages (elenco delle fasi), variables (variabili d'ambiente), before_script (comandi prima di ogni job) e i job con sezioni script, artifacts, cache. GitLab CI supporta include — l'inclusione di file YAML esterni per riutilizzare configurazioni comuni tra progetti.
Le variabili in GitLab CI possono essere impostate a più livelli: globalmente nell'interfaccia utente, nel file di configurazione, nelle impostazioni di gruppo e progetto. La priorità delle variabili segue una gerarchia: le variabili di trigger hanno la priorità più alta, seguite dalle variabili CI/CD dell'interfaccia, poi dal .gitlab-ci.yml. Le variabili possono essere protette, diventando accessibili solo a branch e tag protetti.
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/
Il job generate-apk compila un progetto Gradle e salva l'APK come artefatto. Gli artefatti vengono trasferiti tra stages — un job di deploy può utilizzare l'APK dello stage build. La conservazione degli artefatti è configurata tramite expire_in.
generate-apk:
stage: build
script:
- ./gradlew assembleRelease
artifacts:
paths:
- app/build/outputs/apk/release/
expire_in: 1 day
Nella scelta tra GitLab CI e GitHub Actions per un progetto mobile, l'infrastruttura del team è un fattore chiave. GitLab CI fornisce un Container Registry integrato per archiviare immagini Docker con Android SDK. GitHub Actions dipende da GitHub Packages o registry esterni. GitLab dispone anche di SAST (Static Application Security Testing) integrato per l'analisi delle vulnerabilità del codice.
GitLab CI offre un modello di runner più flessibile — supporta executor Kubernetes, auto-scaling e immagini personalizzate. GitHub Actions eccelle nell'integrazione con l'ecosistema GitHub e il marketplace di azioni. GitLab CI richiede più configurazione manuale per molti compiti che GitHub Actions risolve con azioni pronte.
Dal punto di vista del CI/CD mobile: GitLab CI è più adatto per aziende che già utilizzano GitLab Self-Managed e necessitano di runner self-hosted con Docker/Kubernetes. GitHub Actions è più conveniente per piccoli team su GitHub cloud che apprezzano le azioni pronte e la facilità di configurazione.
| Caratteristica | GitLab CI | GitHub Actions |
|---|---|---|
| Configurazione | .gitlab-ci.yml | .github/workflows/*.yml |
| Runner | Self-hosted + condiviso | Hosted + self-hosted |
| Executor | Docker, K8s, Shell | VM (Ubuntu, macOS, Win) |
| Marketplace di azioni | No (template CI) | Marketplace (15k+ azioni) |
| Build iOS | Runner macOS o K8s | Runner macOS hosted |
Una pipeline Android completa include: lint, test unitari, compilazione e deployment su Firebase App Distribution. La pipeline utilizza un'immagine Docker con Android SDK, caching di Gradle ed esecuzione parallela di lint e test nello stesso stage. Questo approccio riduce il tempo totale della pipeline poiché le attività lint e test sono indipendenti tra loro.
Per i progetti iOS, la struttura della pipeline differisce a causa della necessità di un runner macOS e della firma del codice. Una tipica pipeline iOS include: installazione di CocoaPods o SPM, esecuzione di test sul simulatore, archiviazione del progetto Xcode, esportazione IPA e caricamento su TestFlight. GitLab CI per iOS utilizza runner macOS — sia i runner SaaS GitLab macOS con limiti di tempo, sia un runner self-hosted su 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
Ottimizzare le pipeline di compilazione mobile in GitLab CI richiede attenzione ai dettagli. Una configurazione adeguata di cache e artifacts può ridurre il tempo di compilazione più volte. Per l'analisi delle prestazioni, GitLab fornisce CI/CD Analytics — una dashboard con metriche di durata delle pipeline, carico dei runner e colli di bottiglia. Analizza queste metriche regolarmente per trovare opportunità di ottimizzazione. Configurare resource_group blocca le esecuzioni parallele di pipeline — utile per prevenire conflitti di deployment.
Anche la strategia dei branch per CI è importante. Si raccomanda di eseguire la pipeline completa solo per i branch main e release, e per i branch feature — solo lint e test unitari. Questo risparmia minuti dei runner e accelera il feedback agli sviluppatori. GitLab CI supporta workflow:rules — regole condizionali per includere o escludere job in base al branch, ai file modificati o alle variabili d'ambiente.
Il caching delle dipendenze è il metodo principale di accelerazione. GitLab CI memorizza nella cache .gradle, Pods e node_modules tra le esecuzioni. La chiave di cache include $CI_COMMIT_REF_SLUG o un hash del file lock. Il tempo di compilazione di un progetto Android passa da 10–15 a 2–4 minuti con un caching appropriato. La cache può essere distribuita — GitLab supporta cache:key con fallback alle chiavi precedenti.
Un'immagine Docker con strumenti preinstallati fa risparmiare tempo di installazione. Si raccomanda di creare un'immagine personalizzata con Android SDK, NDK e il livello API richiesto. L'esecuzione parallela di job (lint, test, assemble) in diversi stage riduce il tempo totale della pipeline. Le politiche di pull per le immagini (if-not-present) accelerano l'avvio dei job. È possibile utilizzare anche un proxy di dipendenze per memorizzare nella cache le immagini a livello di istanza GitLab.
Un altro importante aspetto dell'ottimizzazione è l'uso degli artefatti tra le fasi. I file pesanti come APK e IPA dovrebbero essere passati tramite dependency invece di essere ricostruiti in ogni job. Per progetti grandi con decine di moduli, si consiglia di abilitare Gradle Build Cache a livello di pipeline e configurare una cache remota su storage condiviso. Il timeout per ogni job dovrebbe essere impostato in base al tempo di compilazione previsto — questo previene i processi bloccati.
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- .gradle/
- app/build/
image:
name: registry.example.com/android-builder:3.5
pull_policy: if-not-present
Domande frequenti
Su GitLab.com, il piano gratuito include 400 minuti di CI/CD al mese e 5 utenti. Premium ($29/mese) offre 10.000 minuti e più job paralleli. GitLab Self-Managed non ha limiti di minuti.
Usa l'immagine Docker pronta androidsdk/android-35 o installa l'SDK tramite sdkmanager in before_script. Nelle variabili, specifica ANDROID_SDK_ROOT e ANDROID_NDK_HOME per il corretto funzionamento di Gradle.
GitLab CI offre un Container Registry integrato, integrazione Kubernetes e auto-scaling self-hosted. GitHub Actions eccelle per numero di azioni pronte e semplicità per i piccoli team.
Sì, ma iOS richiede un runner macOS. Puoi usare i runner SaaS GitLab macOS (limitati) o configurare un runner self-hosted su Mac Mini. GitLab stesso non fornisce infrastruttura cloud macOS.
Tramite artifacts — i file di un job vengono trasferiti a un altro job nella pipeline. Tramite cache — per le dipendenze tra esecuzioni. Tramite variabili CI/CD — per valori stringa e token.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche