Configuration driven Mobile DevOps

Posted by: Hardik Mistry , on 9/8/2019, in Category DevOps
Views: 24783
Abstract: This tutorial explains how to achieve end-to-end Mobile DevOps with Azure AppCenter to help build apps, manage the distribution, execute custom scripts to handle scenarios such as automagic version update or replace values from environment variables.

Shipping 5-star apps is easier said than done!

While there are tools that allow us to configure and setup a CI/CD (Continuous Integration/Continuous Deployment) pipeline, there are times where you as a developer would want to be able to tune these configurations on the fly, either before the build starts, or after the build succeeded/failed.

Pre-requisites for Mobile DevOps

Things you’ll need to get going:

We usually focus on writing and building an app, but we do not really bother much to figure out how to distribute it. With too many options in the market, it gets quite abstract and ambiguous.

Think of each of these options as choosing between a BMW or a Mercedes, they both are performance vehicles with equal level of commitment to quality and luxury. Both can very well take you from point A to point B. However, there are subtle differences between the two which makes them different and a strong contender in their own segment/rights.

We’ll explore one such tool to help you with your Mobile DevOps journey. This tool is App Center (previously known as Visual Studio Mobile Center).

Signing up to App Center is a breeze. You can start with a free account here: While you can get started for free, you may want to choose a paid plan to obtain more build time (in minutes per month) or other additional services. Explore the pricing and plans here:

Once you are logged in, you need to define an app. If you are working across customers or have a large team, you can define an organisation to group the apps you would be working on.


Figure 1: Appcenter default home page

At this point of time, I will click the Add app button and configure it as an iOS app developed using the Xamarin platform, as illustrated in Figure 2. Notice that you could pick any other flavour of OS and platform as well.


Figure 2: Appcenter Add new app options

Now click the build menu (on the left, the play icon) to configure our repository which contains the solution/project we intend to build.

As you can see, at the time of writing this post, App Center supports: Azure DevOps, GitHub and BitBucket as your repository providers.

In my case, I will connect using GitHub, by clicking the GitHub button (see that icon in Figure 3 on the right-hand side of the screen).


Figure 3: Connect Repository Source

I will have to login using my GitHub account to allow access to use my repository for builds via App Center. (you will have to grant permission when prompted to allow and access your repository).

Alright, once that is in place, we can see the branch(es) available under the repository we selected. I will click on the development branch to be able to configure the build steps.

In your case this could be different. If you fork my repository, you too should see development as a branch option as shown in Figure 4.


Figure 4: Appcenter Branch view

I will click the Configure Build button (the blue button on right hand side of the screen as seen in Figure 5).


Figure 5: Appcenter configure build for development

Next depending upon the app target, you need to choose from a variety of settings.

Figure 6 shows the settings I have used to build a Xamarin.iOS project. This will vary depending upon which target platform you choose to build.

build- configuration

Figure 6: Appcenter build configuration

You need to select .csproj to build Xamarin.iOS projects.

If you are building native iOS apps, you would need to define shared scheme in your workspace settings using XCODE.

Once we are set without desired configuration, click Save if you do not plan to run the build right now, or Save and Build to save your configuration and trigger the build immediately.

I have clicked Save & Build.

Ok, after a few minutes, we will observe that the build was successful. If that’s not the output for you, interestingly you should be able to see the cause for the failed build and make changes in your repository to fix them.

What we would want to do now is be able to update the version number to the next one. So, say the current version number is 1.0, we would want to update it to 1.1.

To be able to do that, we will be wiring the build with some custom build scripts.


Custom Build Scripts

Build scripts are bash scripts which you can execute post clone, pre-build and post- build in App Center. You’ll need to name the file appropriately for App Center to recognise that your code includes a build script as well. Click here to explore more about appcenter build scripts.


If you are trying to build a native iOS app (app built using Objective C or Swift instead of Xamarin as talked about here), keep the .sh script files in the same directory level as where you have the .xcworkspace file.


Figure 7: iOS workspace directory

If you’re trying to build native Android app (app build using Java or Kotlin), keep the .sh script files in the /app directory.


Figure 8: Android app directory

The script will do some housekeeping stuff such as downloading some utility on to the build agent and installing it or setting up configuration etc. We will require to parse and edit a .json file, and for that we will install a utility called jq. To perform addition or other arithmetic operation, we will use a utility called bc.

#!/usr/bin/env bash -e


# Attempt to update node
curl -O
sudo installer -pkg node-v8.11.3.pkg -target /

# Install jq, more information here:
brew install jq

# Install bc, more information here:
brew install bc

npm install

The script will actually parse the Info.plist file or the AndroidManifest.xml file to read the current version information. Then we will convert the .plist into a temporary json file with the help of another utility called plist . Similarly for the .xml file, we will convert it to a temporary json file with help of utility called grep and make use of the bc utility we installed in the post-clone step to increment the version information by 0.1




Sample scripts


# The following is test script to execute in pre build process

#!/usr/bin/env bash
# For Xamarin Android or iOS, change the package name located in AndroidManifest.xml and Info.plist.

if [ ! -n "$INFO_PLIST_FILE" ]
    echo "You need define Info.plist in your iOS project"


# Check branch and run commands if so:
if [ "$APPCENTER_BRANCH" == "master" ]; then

    # Convert .plist file to .json
    plutil -convert json $INFO_PLIST_FILE -o temp.json

    jq '.' temp.json

    VERSION=$(jq -r '.CFBundleShortVersionString' temp.json)
    BUILD=$(jq -r '.CFBundleVersion' temp.json)

    echo "Current version: " $VERSION
    echo "Current build: " $BUILD

    # Actually increment the version in this line
    UPDATED_VERSION=$(bc <<< "$VERSION + 0.1")

    echo "Updated version: " $UPDATED_VERSION

    echo "Updating Build to $APPCENTER_BUILD_ID in Info.plist"
    plutil -replace CFBundleVersion -string $APPCENTER_BUILD_ID $INFO_PLIST_FILE

    echo "Updating Version to $UPDATED_VERSION in Info.plist"
    plutil -replace CFBundleShortVersionString -string $UPDATED_VERSION $INFO_PLIST_FILE


if [ "$APPCENTER_BRANCH" == "development" ]; then

    # Convert .plist file to .json
    plutil -convert json $INFO_PLIST_FILE -o temp.json

    jq '.' temp.json

    VERSION=$(jq -r '.CFBundleShortVersionString' temp.json)
    BUILD=$(jq -r '.CFBundleVersion' temp.json)

    # Print the values
    echo "Current version: " $VERSION
    echo "Current build: " $BUILD


echo "Info.plist file content:"


# The following is test script to execute in pre build process

#!/usr/bin/env bash
# For Xamarin Android or iOS, change the package name located in AndroidManifest.xml and Info.plist. 

# This path will vary depending upon your project structure

    echo "You need define AndroidManifest.xml in your Android project"


# Check branch and run commands if so:
if [ "$APPCENTER_BRANCH" == "master" ]; then

    VERSIONCODE=`grep versionCode $ANDROID_MANIFEST_FILE | sed 's/.*versionCode="//;s/".*//'`
    VERSIONNAME=`grep versionName $ANDROID_MANIFEST_FILE | sed 's/.*versionName="//;s/".*//'`

    echo "Current VersionCode: " $VERSIONCODE
    echo "Current VersionName: " $VERSIONNAME

    # Actually increment the version in this line

    echo "Updating versionCode to $APPCENTER_BUILD_ID and versionName to $UPDATED_VERSIONNAME in AndroidManifest.xml"
    sed -i '' 's/versionCode="[0-9.]*"/versionCode="'$APPCENTER_BUILD_ID'"/; s/versionName *= *"[^"]*"/versionName="'$UPDATED_VERSIONNAME'"/' $ANDROID_MANIFEST_FILE


if [ "$APPCENTER_BRANCH" == "staging" ]; then

    VERSIONCODE=`grep versionCode $ANDROID_MANIFEST_FILE | sed 's/.*versionCode="//;s/".*//'`
    VERSIONNAME=`grep versionName $ANDROID_MANIFEST_FILE | sed 's/.*versionName="//;s/".*//'`

    # Print the values
    echo "Current VersionCode: " $VERSIONCODE
    echo "Current VersionName: " $VERSIONNAME


echo "Manifest file content:"

If you now (after pushing the scripts, if you tried to create your own repository and project) try and check the configuration, notice that in Figure 9, it shows the post-clone and pre-build scripts.

Note: As of today, you cannot specify the scripts directly from this configuration screen, you will have to put the files in the right directory in with the correct file name.


Figure 9: Verify the scripts in configuration

Alright, so the scripts are already in place. If we re-run the build manually right now or every time a new build runs in App Center, these scripts will be executed and that means that the content will be executed every time. To fail safe ourselves, if you read the scripts again, I have included a condition to check if that branch is master, update the version, or else, only display the version.


Figure 10: Build log view


I have explored and used other alternate tools as well such as Jenkins, Bitrise etc. While these are options worth trying, it is my personal opinion that Jenkins had an overhead while administering and managing the server, whereas in the case of bitrise, it got overwhelming to manage the steps of build etc.

Again, this does not mean that these and the other options available in the market are not worth trying, it is just my personal opinion and the other options might just be the best fit for your scenario.

App Center did it just right, at least for me 😉

In this post we explored how we could customize the default build experience using the custom build scripts in App Center. You can review more exciting features at, and also check out their product blog for latest and greatest updates.

I would love to hear from you, be it thoughts around the post or any other help you might need with AppCenter, tweet me @mistryhardik05

Happy building!

This article was technically reviewed by Gerald Verslius.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Hardik Mistry is a Consultant for .NET, Azure, Xamarin and DevOps scenarios and workloads. He is a Microsoft MVP with proven experience of 7+ years of engineering mobile-first and cloud-first scenarios for select startups and enterprise customers. You can reach out to him via twitter @mistryhardik05.

Page copy protected against web site content infringement 	by Copyscape

Feedback - Leave us some adulation, criticism and everything in between!