Bitrise
CI / CD en mobile via Bitrise et Fastlane
Cet article fait suite à un atelier que j’ai animé sur la création d’un serveur de CI/CD simple sur iOS et Android. L’objectif était de sortir au bout d’une heure avec un serveur fonctionnel
C what ? Quelques rappels de base 📖
Qu’est ce qu’une CI ? Continuous Integration. Est un ensemble de pratique permettant de vérifier que le code modifié ne va pas casser le code existant. Concrètement, ça va automatiser le lancement de tests, de linter, code smells, etc.
Une CI toute simple se présente ainsi :
- build
- test
- analyse (linter, code coverage, code smell)
Et quid de la CD ? Continuous Delivery. Permet d’automatiser l’envoi sur testflight, appstore ou playstore. On peut ainsi prévoir des mises en productions régulière, et n’importe qui peut le faire, plus de dépendance direct avec quelqu’un.
Une CD toute simple sera elle ainsi :
- build
- sign
- deploy
Fastlane 🤖
Fastlane est un outils qui va permettre en mobile d’automatiser beaucoup de tâches. C’est un outil écrit en ruby, open source, ou l’on peut ajouter des scripts facilement. C’est un outil très utilisé sur iOS, qui a également été porté pour android, flutter et react.
Description des outils utilisés pour une CI sur iOS :
- cocoapods, gestionnaire de dépendance
- scan, permet de lancer les tests
- swiftlint, linter
- slather, codecoverage analyser
Voici une lane iOS pour la CI :
desc "CI"
lane :ci do
# pod
cocoapods(
clean: true
)
# test
scan(
workspace: "workshopBitriseIOS.xcworkspace",
devices: ["iPhone 6s"],
scheme: "workshopBitriseIOS"
)
# lint
swiftlint(
executable: "Pods/SwiftLint/swiftlint",
output_file: "build/swiftlint_result.json",
ignore_exit_status: true
)
# slather
slather(
use_bundle_exec: "true",
)
end
Nous avons dans un gemfile slather, fastlane et cocoapods afin que chaque devs et CI
utilisent la même version. Pour Swiftlint même combat mais cette fois dans le podfile.
Description des outils utilisés pour une CD sur iOS :
- cocoapods, gestionnaire de dépendance
- match, gestion de codesigning
- gym, permet de compiler
- pilot, envoi sur testflight
desc "CD"
lane :cd do
# pod
cocoapods(
clean: true
)
# set certificates & provisioning profile
match(
type: "appstore",
readonly: true,
output_path: "match/"
)
disable_automatic_code_signing
update_project_provisioning(
xcodeproj: "workshopBitriseIOS.xcodeproj",
target_filter: "workshopBitriseIOS",
profile: "./match/" + ENV["APP_PROVISIONING_PROFILE_IDENTIFIER"] + ".mobileprovision"
)
# increment build number
increment_build_number(
build_number: 1,
xcodeproj: "workshopBitriseIOS.xcodeproj"
)
# build for release
gym(
scheme: "workshopBitriseIOS",
include_bitcode: true,
skip_profile_detection: true,
clean: true,
codesigning_identity: ENV["APPSTORE_SIGNING_IDENTITY"],
verbose: true
)
# upload to testflight
pilot(
skip_waiting_for_build_processing: true
)
end
Nous utilisons pour le provisioning profile et le code signing un outils très
pratique nommé match. Son principe est simple, il va versionner les codes signings
et provisioning profiles dans un git, hashé. Ca permet lors par exemple de l’arrivé
d’un nouveau de directement mettre à jour partout les infos de signing. Match va également
mettre à jour les certificats invalides ou périmés.
Durant la CD, nous mettons à jour le code signing. Même si il est bien setté dans xCode,
ça nous assure que si quelqu’un le change ça ne casse pas notre CD.
On peut également voir que j’utilise des variables d’environnement pour les noms
de provisioning profile et de codesigning. La raison est que ça peut changer et nous
pourrons donc directement le modifier dans le fichier .env.
Dernier point, nous n’attendons pas le processing de testflight. En effet, il peut
mettre beaucoup de temps, qui va donc bloquer notre serveur de CD.
Bitrise 🚀
Bitrise est un serveur d’intégration et de déploiement continu spécialisé dans le mobile. Etant directement hosté et managé chez eux, il ne nécéssite que peu de maintenance (pas besoin de gérer les mises à jour d’xCode ou de macos). Il nous fait donc gagner un temps considérable et nous permet de facilement avoir un CI/CD fonctionnel.

Ici, comme on peut le voir l’unique action de Bitrise sera de lancer fastlane ci.
La première action est spécifique à Bitrise, c’est récupérer la clé ssh setté dans github.
La seconde action est de cloner le projet. La troisième d’installer la version de bundler
suffisante. La dernière action va permettre de récupérer les logs des différents linters,
codecoverages, codesmells, etc..
Pour la CD, même combat, même lane. C’est fastlane qui fera tout ce qu’il faut.
Conclusion
Il est simple aujourd’hui de débuter une CI/CD sans se casser la tête sur des process et de la maintenance lourde. Ceci était une courte introduction à la CI et la CD (l’atelier de base durait 1h). Il y a bien évidemment des choses très sympa à faire avec une CI et une CD comme l’automatisation de screenshots, la mise en place de l’internationalisation incrémentale, la génération de documentation.
Vous pouvez retrouver les slides de mon atelier ici
Voici les liens githubs de l’atelier : iOS et android
Et un dernier lien vers Bitrise si vous souhaitez le tester.