CI/CD mobile avec Jenkins, GitHub Actions et Azure DevOps
Cet article présente les principaux défis de la mise en place d'un pipeline CI/CD pour les applications mobiles. Il fournit aussi des exemples de pipeline CI/CD pour des applications Android et iOS dans les outils de CI/CD mobile les plus utilisés.
85 % des équipes qui ont intégré l'analyse de sécurité à leur pipeline CI/CD respectent leur SLO de correctifs, corrigent les vulnérabilités plus rapidement, modifient le code plus souvent et déclarent mieux comprendre leur base de code.
Cet article présente les principaux défis de la mise en place d'un pipeline CI/CD pour les applications mobiles. Il fournit aussi des exemples de mise en œuvre de pipelines d'intégration continue pour des applications Android et iOS dans les outils de CI/CD mobile les plus utilisés.
Avant d'intégrer des contrôles de sécurité à nos pipelines CI/CD, nous devons nous assurer qu'ils sont correctement construits et stables, et que nous disposons de la bonne observabilité pour les réparer en cas de panne.
Voici quelques-uns des défis courants que nous observons lors de l'adoption du CI/CD pour les applications mobiles :
-
Manque d'expertise CI/CD :
La plupart des solutions DevOps exigent une expertise CI/CD avancée pour configurer, personnaliser et maintenir correctement les workflows et processus automatisés. La plupart des développeurs d'applications ont besoin de temps et d'expérience pour acquérir ces compétences. -
Responsabilités floues :
Mettre en place du CI/CD n'est pas une tâche ponctuelle. Comme tout code écrit par des humains, il peut échouer, tomber en panne ou se comporter de façon inattendue. Ainsi, une mauvaise gestion ou une mauvaise mise en œuvre du pipeline CI/CD rend souvent fastidieuse l'identification immédiate des causes d'échec. Cela complique à son tour la redirection vers les équipes concernées pour corriger les erreurs de code.
-
Se limiter aux environnements Dev et QA par rapport à la Prod :
Une application mobile se compose généralement d'un binaire client installé sur l'appareil et d'un backend avec lequel il communique via une API. Le pipeline CI/CD peut avoir des configurations et des environnements différents pour exécuter les tests. Une erreur fréquente consiste à tester avec les environnements Dev et QA, et à négliger les différences avec l'environnement Prod. Le code en production devient alors non testé et peut contenir des erreurs, des problèmes de sécurité ou des erreurs inattendues.
-
Négliger l'analyse dynamique :
De nombreuses entreprises mettent en place des pipelines CI avec uniquement de l'analyse statique. Cela s'explique surtout par la difficulté d'automatiser l'analyse dynamique de l'application. L'analyse statique vise à analyser des binaires ou du code source pour trouver des motifs de vulnérabilités connus. Cependant, elle est connue pour produire trop d'alertes sur des failles logicielles mineures et des défauts non exploités. C'est pourquoi le standard OWASP recommande de mettre en œuvre à la fois l'analyse statique et l'analyse dynamique. L'analyse dynamique est conçue pour détecter les vulnérabilités de sécurité pendant l'exécution de l'application. Elle ne couvre que le périmètre réellement utilisé dans l'application et offre un haut niveau de confiance dans le problème identifié.
-
Difficulté à exécuter l'automatisation de l'interface utilisateur :
Dans un pipeline CI/CD, l'automatisation des interactions avec l'interface utilisateur est une étape importante pour accroître la couverture de test et garantir l'évolutivité et la qualité des tests. Le défi habituel consiste à automatiser toutes les interactions avec l'interface et à s'assurer qu'elles restent stables d'une version de l'application à l'autre, d'une version d'OS à l'autre et sur de multiples appareils.
-
Limites cachées des fournisseurs de CI/CD :
Pour disposer d'un pipeline CI/CD entièrement automatisé pour une application mobile, il faut se conformer aux exigences rigides du système d'exploitation mobile, à une signature de code rigoureuse, à des SDK et outils fréquemment mis à jour, aux tests sur appareils et à la soumission à l'app store. Le choix du fournisseur de CI/CD est donc essentiel pour couvrir vos besoins et faciliter la mise en œuvre et la maintenance.
Voyons maintenant comment ajouter le build d'une application mobile (Android et iOS) à certaines des plateformes de CI/CD les plus utilisées.
Intégration continue pour les applications Android avec Jenkins
Nous allons voir comment générer un APK Android à partir du code source dans Jenkins. Je pars du principe que vous avez déjà installé Jenkins.
-
Étape 1 : installer le JDK Java :
Dans votre terminal, exécutez :
sudo apt install default-jdk
-
Étape 2 : installer le SDK Android :
Rendez-vous sur la page de téléchargement d'Android, et récupérez le lien indiqué dans le tableauCommand line tools only>Linux. Ne téléchargez rien. Copiez simplement le lien.
# here you paste the link you grabbed in the developer.android.com site
sudo -iu jenkins wget https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip
sudo -iu jenkins mkdir android-sdk
sudo -iu jenkins unzip commandlinetools-linux-8512546_latest.zip -d android-sdk
# this step is important to accept the Android SDK license
yes |sudo -iu jenkins android-sdk/tools/bin/sdkmanager --licenses
-
Étape 3 : installer le plugin Gradle :

.1 Ouvrez Jenkins : Manage Jenkins >> Manage Plugins >> Available
.2 Recherchez Gradle

.3 Cliquez sur Install

-
Étape 4 : configurer Jenkins :
.1 Ouvrez Jenkins : Manage Jenkins >> Configure System >> Global properties >> Environment variables

.2 Ajoutez les variables :
# depending on your local paths
ANDROID_HOME : /var/lib/jenkins/android-sdk
JAVA_HOME : /usr/lib/jvm/java-11-openjdk-amd64

-
Étape 5 : créer le job de build Android :
.1 Ouvrez Jenkins : New Item
.2 Saisissez le nom du job
.3 Choisissez un Freestyle project et cliquez sur OK
.4 Allez dans Source Code Management -> cochez Git et renseignez :
-
Repository URL : l'URL Git de votre dépôt. Récupérez cette URL sur GitHub. Elle doit avoir le format git@github.com:{username}/{repo}.git
-
Credentials : sélectionnez vos identifiants ou créez-en de nouveaux dans le menu des identifiants.
-
Branches to build : branch_name
.5 Dans la section Build, sélectionnez Invoke Gradle script

.8 Renseignez le nom de vos tâches
.9 Dans Post-build Actions, renseignez Archive artifacts : **/*.apk
.10 Cliquez sur Save
-
Étape 6 : lancer le build :
Depuis le tableau de bord du job, cliquez sur Build Now, et vous verrez le job s'exécuter. Une fois le build terminé avec succès, vous pouvez voir l'application Android générée dans les informations du projet.

Intégration continue pour les applications iOS avec Jenkins
-
Étape 1 : installer Jenkins avec le plugin XCode (nécessite macOS) :
.1 Ouvrez Jenkins : Manage Jenkins >> Manage Plugins >> Available
.2 Recherchez Xcode integration

.3 Cliquez sur Install
-
Étape 2 : créer une équipe de développement depuis la configuration globale de Jenkins :
.1 Ouvrez Jenkins : Manage Jenkins >> Configure System
.2 Allez dans la section Xcode builder
.3 Allez dans la section Apple Development Teams et cliquez sur le bouton Add
.4 Renseignez les deux champs Team Name et Development Team ID

.5 Ajoutez une section Keychain
.6 Renseignez les valeurs de Keychain Name et de Keychain password (le chemin du trousseau est déjà renseigné)

.7 Cliquez sur Apply puis Save
-
Étape 3 : configurer le job Jenkins pour cloner le dépôt :
.1 Allez dans le chemin du projet dans l'espace de travail Jenkins (/Users/Shared/Jenkins/Home/workspace)
.2 Ouvrez le projet avec Xcode
.3 Dans l'onglet General de Xcode, vérifiez que le Provisioning profile et toutes les informations sont corrects
.4 Vous pouvez essayer de compiler le projet avec Xcode pour vous assurer que toutes les informations sont correctes
.5 La case Automatically manage signing ne doit pas être cochée
.6 Notez le Team Name et le Bundle Identifier, car nous les utiliserons dans la configuration de Jenkins
-
Étape 5 : configurer le build dans Jenkins :
.1 Ouvrez Jenkins, allez dans votre projet et cliquez sur configure
.2 Dans la section Build, cliquez sur le bouton d'étape build et sélectionnez l'option Xcode. Cela ajoute les champs liés à Xcode.
.3 Dans General build settings, cliquez sur le bouton Settings
.4 Sélectionnez le Development Team que vous venez d'ajouter à la configuration globale de Jenkins
.5 Renseignez le Schema File de Xcode :
.6 Sélectionnez l'option Pack application, build and sign .ipa?.

.7 La méthode d'export de l'.app pour générer le fichier .ipa. Elle doit être l'une des suivantes : ‘development’, ‘ad-hoc’, ‘enterprise’ ou ‘app-store'.
.8 .ipa filename pattern : un motif pour le nom du fichier IPA. Vous pouvez utiliser ${VERSION} et ${BUILD_DATE} (yyyy.MM.dd) dans cette chaîne.
.9 Allez dans les options Code signing & OS X keychain
.10 Sélectionnez Manual signing
.11 Renseignez le Bundle ID et le Provisioning profile UUID (vous le trouverez dans le fichier .mobileprovision de votre profil de provisionnement)
.12 Sélectionnez Unlock Keychain
.13 Sélectionnez la valeur du Keychain que vous venez de créer dans la liste déroulante
.14 Allez dans la section d'options Advanced Xcode build
.15 Renseignez les champs Xcode Workspace File : Xcode Project Directory : $WORKSPACE
.16 Cliquez sur Apply puis Save
-
Étape 6 : lancer le build :
Depuis le tableau de bord du job, cliquez sur Build Now et regardez le job s'exécuter.
Une fois le build terminé avec succès, vous pouvez voir l'application IPA générée dans les informations du projet.
Intégration continue pour les applications Android avec GitHub Actions
Les runners proposés par GitHub Actions permettent d'exécuter votre build sur Linux, Mac et Windows.
Tous les runners ont Java et Android déjà installés et configurés (la liste des logiciels préinstallés est assez longue). Les workers peuvent compiler la plupart des projets Android sans configuration supplémentaire.
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout the code
uses: actions/checkout@v2
- name: Build the app
run: ./gradlew build
Intégration continue pour les applications iOS avec GitHub Actions
Pour le build de l'IPA, nous utiliserons la tâche yukiarrr/ios-build-action. Cette action compile un projet iOS et peut l'exporter en fichier IPA.
Vous pouvez consulter la documentation complète dans le dépôt GitHub
name: Build and sign Ipa file
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Build and export iOS
uses: yukiarrr/ios-build-action@v1.5.0
with:
project-path:
workspace-path: ".xcworkspace path"
scheme: "project name"
export-method: "Choose app-store, ad-hoc, package, enterprise, development"
configuration: "Choose Debug or Release"
output-path: artifacts/output.ipa
p12-base64: ${{ secrets.P12_BASE64 }}
certificate-password: ${{ secrets.P12_PASSWORD }}
mobileprovision-base64: ${{ secrets.ADHOC_MOBILEPROVISION_BASE64 }}
code-signing-identity: ${{ secrets.CODE_SIGNING_IDENTITY }}
team-id: ${{ secrets.TEAM_ID }}
Intégration continue pour les applications Android avec Azure DevOps
-
Étape 1 : préparer le pipeline :

.1 Ouvrez votre projet et rendez-vous dans la section Pipelines du panneau de gauche
.2 Cliquez sur Create Pipeline
.3 Sélectionnez votre dépôt Git
Un pipeline Yaml vide est généré. Nous devons maintenant compiler le fichier binaire avec Gradle.
-
Étape 2 : compiler le fichier APK avec une tâche Gradle :
.1 Cliquez sur show assistant

.2 Recherchez Gradle

.3 Vous pouvez désactiver Publish to Azure Pipeline dans la section JUnit Test Results
.4 Définissez le nom de votre tâche pour compiler le fichier
.5 Cliquez sur le bouton Add
.6 Cliquez sur Save pour enregistrer notre pipeline CI
Vous pouvez aussi ajouter les tâches 'Copy files' et 'Publish build artifacts' pour injecter le fichier généré dans le pipeline si vous souhaitez exécuter d'autres jobs sur ce fichier.
Intégration continue pour les applications iOS avec Azure DevOps
-
Étape 1 : préparer le pipeline :
.1 Ouvrez votre projet et rendez-vous dans la section Pipelines du panneau de gauche
.2 Cliquez sur Create Pipeline
.3 Sélectionnez votre dépôt Git
Un pipeline Yaml vide est généré. Nous devons maintenant compiler le fichier binaire avec Gradle.
-
Étape 2 : compiler le fichier APK avec une tâche Gradle :
Nous avons besoin du profil de provisionnement et du certificat iOS pour signer le fichier IPA.
Pour les téléverser dans notre pipeline, nous utiliserons la section Secure files :
.1 Allez dans pipelines -> Library -> Secure files

.2 Téléversez votre fichier de provisionnement. Dans mon cas, je l'appellerai my_provision_profile_ostorlab
.3 Exportez la certificate public key (.p12) et téléversez-la. Je l'appellerai my_certificate.p12
.4 Retournez dans votre pipeline et ajoutez trois variables :
p12FileName = my_certificate.p12
p12Password = my_certificate_password
provisioningProfile = my_provision_profile_ostorlab

.5 Cliquez sur show assistant
.6 Recherchez install apple provisioning

.7 Renseignez provProfileSecureFile avec la variable $(provisioningProfile)
.8 Cliquez sur Add
.9 Cliquez sur show assistant
.10 Recherchez install apple certificate

.11 Renseignez le nom du fichier et le mot de passe avec le contenu des variables
.12 Cliquez sur Add
-
Étape 3 : compiler et signer le fichier IPA :
Pour compiler le fichier .ipa, nous devons utiliser macOS comme vmImage.
.1 Nous devons ajouter la build configuration comme variable. Vous pouvez définir la valeur sur Debug ou Release.
.2 Nous devons ajouter la variable SDK. Depuis l'application Terminal de macOS, exécutez xcodebuild -showsdks pour afficher la liste des SDK valides.
.3 Cliquez sur show assistant
.4 Recherchez Xcode

.5 Dans Signing style, sélectionnez Manual signing
.6 Renseignez Signing identity avec la valeur $(APPLE_CERTIFICATE_SIGNING_IDENTITY). Cette variable correspond à ‘Install Apple Certificate’ que nous avons ajouté précédemment
.7 Renseignez Provisioning profile UUID avec la valeur $(APPLE_PROV_PROFILE_UUID) définie par la tâche Install Apple Provisioning Profile’.
.8 Cliquez sur Add
.9 Cliquez sur save pour enregistrer notre pipeline CI.
Si vous exécutez votre build pour la première fois, il échouera en vous demandant d'accorder l'accès aux variables et aux secure files. Cliquez sur Authorize resources et relancez votre build.
Dans cet article, nous avons passé en revue quelques défis de la mise en place de pipelines CI/CD. Nous avons également abordé la compilation d'applications mobiles APK et IPA sur les plateformes de CI les plus utilisées. La mise en œuvre du CI doit être complétée par un pipeline CD pour automatiser le déploiement après le processus de revue. Comme l'écosystème des applications mobiles compte de multiples frameworks pour développer et compiler l'application, la mise en œuvre du CI peut varier selon les outils du framework.
Le prochain article portera sur le framework Flutter et sur la façon d'automatiser le build dans ces plateformes de CI/CD.