- Azure
- Azure DevOps
- Xamarin
Lorsque vous développez un projet, vous avez toujours plusieurs environnements, par exemple:
Chacun de ces environnements a sa propre configuration (URL du serveur, clés api …). Pour différencier une version d’environnement d’une autre, nous devons souvent:
Ce tutoriel fait partie d’une série complète de tutoriel Azure DevOps utilisant une application Xamarin.Forms comme exemple. Dans le précédent tutoriel nous avions configuré les étapes de build et de signature. Ce tutoriel peut être lu indépendamment et les concepts peuvent être appliqués à n’importe quelle technologie mobile que vous utilisez.
Si vous voulez commencer par utiliser le même azure-pipeline.yml
, il suffit de cloner le repos et de vous placer sur la branche nightly_builds
.
Pour vous aider à mieux comprendre, voici ci-dessous un schéma global de ce qui a déjà été fait dans les tutoriels précédents et où sont fait les étapes que nous allons voir dans ce tutoriel:
Il existe plusieurs façons de gérer la configuration à l’intérieur de votre application Xamarin. Vous pouvez par exemple créer votre configuration de build dans votre solution ou utiliser un fichier de configuration JSON pour le modifier.
En utilisant un fichier de configuration, votre configuration sera désérialisée au démarrage de votre application et toutes vos variables d’environnement seront prêtes à l’emploi.
Les autres avantages de l’utilisation d’un fichier de configuration dans JSON sont que vous pouvez builder votre application une fois, puis pour chaque environnement, vous modifierez le fichier de configuration et le signerez. Cela vous fera gagner beaucoup de temps de build dans vos pipelines.
Pour ce tutoriel, considérons que nous avons un dossier configurations
à la racine de votre projet de solution comme dans le répertoire Github avec plusieurs fichiers d’environnement json comme ceci:
|- configurations
|- config-debug.json
|- config-prerelease.json
|- config-release.json
Le but est de copier et coller le contenu de l’un de ces fichiers dans le fichier final config.json
à l’intérieur du répertoire Assets
sur chaque plateforme.
Pour y parvenir, créons un nouveau template appelé copy_content_file.yml
dans le dossier templates
à la racine de notre projet :
parameters:
sourceFile: ''
targetFile: ''
steps:
- task: Bash@3
inputs:
targetType: 'inline'
script: cp -fr ${{ parameters.sourceFile }} ${{ parameters.targetFile }}
Ce template est appelé avant le début de chaque build iOS et Android. Pour Android, il sera configuré comme ceci :
- template: templates/copy_content_file.yml
parameters:
sourceFile: '$(Build.SourcesDirectory)/configurations/config-$(buildConfiguration).json'
targetFile: '$(Build.SourcesDirectory)/XamarinDevOps.Android/Assets/config.json'
Pour iOS se sera comme ci-dessous :
- template: templates/copy_content_file.yml
parameters:
sourceFile: '$(Build.SourcesDirectory)/configurations/config-$(buildConfiguration).json'
targetFile: '$(Build.SourcesDirectory)/XamarinDevOps.iOS/Assets/config.json'
Si vous voulez voir comment configurer correctement un fichier config.json
dans votre application, il est vraiment recommandé de lire cet excellent article de John Thiriet à ce sujet.
Après avoir configuré la bonne configuration, examinons la version de votre application. En effet pour pouvoir pousser une nouvelle version sur les stores de votre choix, à chaque fois vous avez besoin de monter la version de votre application. Selon le type de technologies mobiles que vous utilisez, vous devez mettre à jour l’AndroidManifest.xml
ou le build.gradle
pour Android et Info.plist
pour iOS.
Pour ce faire, j’ai développé une série d’extensions pour extraire la version du tag Git et changer automatiquement la version des fichiers de configuration précédemment mentionnés pour vous.
Pour plus de détails sur ces extensions, n’hésitez pas à jeter un œil à mon précédent tutoriel pour en savoir plus.
Parce que nous utilisons Xamarin, nous devons mettre à jour les fichiers AndroidManifest.xml
et Info.plist
. Assurez-vous d’avoir au moins un tag spécifiée sur votre branche pour pouvoir exécuter les tasks suivantes. Pour ce tutoriel j’ai mis un tag v0.0.1
.
Créer un nouveau template appelé bump_android_manifest_version.yml
dans le dossier templates
comme ceci :
parameters:
androidManifestPath: ''
steps:
- task: ExtractVersionFromTag@1
- task: UpdateAndroidVersionManifest@1
inputs:
androidManifestPath: '${{ parameters.androidManifestPath }}'
Cela récupérera la version du dernier tag sur votre répertoire git et mettra à jour le AndroidManifest.xml
en conséquence. Appelez ensuite ce template avant de builder votre projet Android :
- template: templates/bump_android_manifest_version.yml
parameters:
androidManifestPath: '$(Build.SourcesDirectory)/XamarinDevOps.Android/Properties/AndroidManifest.xml'
Faisons maintenant l’équivalent pour iOS, créons un fichier et nommez-le bump_ios_version.yml
. Dans ce template, nous mettons à jour la version de Info.plist
en fonction du tag git :
parameters:
infoPlistPath: ''
steps:
- task: ExtractVersionFromTag@1
- task: UpdateiOSVersionInfoPlist@1
inputs:
infoPlistPath: '${{ parameters.infoPlistPath }}'
Utilisez ce template juste avant de builder votre projet iOS :
- template: templates/bump_ios_version.yml
parameters:
infoPlistPath: '$(Build.SourcesDirectory)/XamarinDevOps.iOS/Info.plist'
Cette partie n’est pas obligatoire, elle ne sert qu’à vous aider à distribuer plusieurs versions de votre application et à basculer facilement entre chaque version. L’idée est d’ajouter une bannière au dessus de l’icône de votre application avec le nom de votre environnement. Pour ce faire, j’ai créé une extension Azure DevOps appelée Launch Icon Badge.
Pour plus d’informations sur cette extension, n’hésitez pas à consulter mon précédent tutoriel à ce sujet.
Voyons comment l’utiliser dans un nouveau template appelé icon_banner.yml
; il est toujours ajouté dans le répertoire templates
de votre projet :
parameters:
sourceFolder: '$(Build.SourcesDirectory)'
contents: '**/*.png'
versionNamePosition: 'bottomRight'
versionName: ''
steps:
- task: LaunchIconBadge@1
inputs:
sourceFolder: '${{ parameters.sourceFolder }}'
contents: '${{ parameters.contents }}'
bannerVersionNamePosition: '${{ parameters.versionNamePosition }}'
bannerVersionNameText: '${{ parameters.versionName }}'
Une fois terminé, pour Android, il suffit d’appeler ce template avant de builder le projet :
- template: templates/icon_banner.yml
parameters:
sourceFolder: '$(Build.SourcesDirectory)/XamarinDevOps.Android/Resources'
contents: '**/icon.png'
versionName: '$(buildConfiguration)'
même chose pour iOS :
- template: templates/icon_banner.yml
parameters:
sourceFolder: '$(Build.SourcesDirectory)/XamarinDevOps.iOS/Assets.xcassets/AppIcon.appiconset'
versionName: '$(buildConfiguration)'
Dans cet exemple, le nom de la version sera la valeur de $(buildConfiguration)
qui correspond à la configuration de build en cours d’exécution. Vous pouvez le changer comme vous le souhaitez. Techniquement, il n’est pas nécessaire de créer un template pour une seule tâche comme nous l’avons fait ici, mais cela peut être utile si vous souhaitez abstraire le comportement de votre template et le mettre à jour une seule fois si nécessaire à l’avenir.
L’environnement de votre application est maintenant prêt, vous pouvez créer votre pipeline pour chaque environnement. Vous trouverez le code source complet dans ce dépôt Github dans la branche manage_environment
. Cela vous montrera un exemple complet basé sur les tutoriels précédents de la série.
Dans le prochain tutoriel de cette série, nous nous concentrerons sur la préparation à la distribution de votre application.
Happy coding!
Vous avez aimé ce tutoriel ? Laissez une étoile sur le répertoire Github associé !