Photo par Jakub Skafiriak

Gérez votre application par environnement avec Azure DevOps

Différenciez votre environnement

Posted by Damien Aicheh on March 12, 2020 · 10 mins

Lorsque vous développez un projet, vous avez toujours plusieurs environnements, par exemple:

  • Développement
  • Pré-prodution
  • Production

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:

  • Changer le fichier de configuration
  • Incrémenter la version de votre application
  • Ajoutez une bannière au-dessus de l’icône pour afficher le nom de l’environnement

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:

Global overview

Fichier de configuration

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.

Montée de version

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.

Android

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'

iOS

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'

Différencier l’icône de l’application

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.

Touche finale

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.

Et après ?

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é !

N'hésitez pas à me suivre sur pour ne pas rater mon prochain tutoriel !