Configuration driven Mobile DevOps
Tags: xamarin, devops, appcenter
Published: 2019-06-08 13:41:08

### The challenge

Shipping 5 star apps is what most of us aspire to do, however, if you are reading this, probably, you have realised by now that only the right piece of technology does not cut through.

> You can try and follow the post using this GitHub repository: https://github.com/mistryhardik/ms-workshops

Writing and building an app is an area we focus on but we do not really bother much to actually figure out how to distribute it. With too many options in the market, it gets quite abstract and ambigious. 

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, they both can very well take you from point A to point B. However there are subtle differences between the two which make them different and strong contender in their own segment/rights.

We'll explore one of such tools to help you with your Mobile DevOps journey, the tool is AppCenter (previously known as Visual Studio Mobile Center).

Signing up to AppCenter is a breeze (you start with a free account here: https://appcenter.ms) and later configure the billing to avail additional build minutes or test runs on actual devices. Check out more here: https://docs.microsoft.com/en-us/appcenter/

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 as well to group the apps you would be working on.
![](https://thepracticaldev.s3.amazonaws.com/i/23td9a1wfcwhcr0c4eez.png)

Alright, so we are logged in and now, we have defined an app which is configured as a Xamarin app, notice that you could pick any other flavour of tech as well.
![](https://thepracticaldev.s3.amazonaws.com/i/gnytzrmnucieuhff37pz.png)

Following which, we click the build menu (on the left, that play button kinda guy) and that would require us to configure our repository which contains the solution/project we intend to build. As you can see, at the time of writing this post, AppCenter supports: Azure DevOps, GitHub and BitBucket as your repository providers. In my case, I will connect using GitHub.
![](https://thepracticaldev.s3.amazonaws.com/i/vuzdmaugq964wulsbo1v.png)

Alright, once that is in place, we see the branch(es) available under the repository we selected. Let me click and select development in my case and then I will click the Configure Build button (that guy in the blue 
shirt :)
![](https://thepracticaldev.s3.amazonaws.com/i/8clah78bc0bhfu3yc6fa.png)

![](https://thepracticaldev.s3.amazonaws.com/i/e539qaltv2coas5lrqqw.png)


Next depending upon the app target, you need to choose from variety of settings, here are mine cause we are trying to build Xamarin.iOS project. This will vary depending upon what you're trying to build.
![](https://thepracticaldev.s3.amazonaws.com/i/8clw5lt3fikcmwgkykg9.png)

> 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 with out desired configuration, click Save (if you do not plan to run the build right now) or Save and Build and that will save your configuration and trigger the build immediately. I have clicked `Save & Build`

Ok, after a few minutes we see the build was successful, if not, interestingly you should be able to get the cause for why the build failed and can make changes in your repository to fix them.

Well that was the easy part, now comes the real challenge. You did notice, we have the ability to specify Environment variable(s) as key-value pair. How do we replace that with a value in a file in the project or what can we do to update the version number when we trigger a build for master, say for example the version for development is `1.0`, we would want that version to increment by `0.1` and hence the version to release via master should be `1.1` or may be you want to replace a value in the Info.plist file. How could we do all that? 

### The solution
The answer is `build scripts`.

`build scripts` are bash scripts which you can execute `post clone`, `pre build` and `post build` during your build in AppCenter. You'll need to name the file appropriately for AppCenter to recognise that your code includes a build script as well. [Click here to explore more about appcenter build scripts](https://docs.microsoft.com/en-us/appcenter/build/custom/scripts/)

`appcenter-post-clone.sh` and `appcenter-pre-build.sh` are the files we already have in our project directory.

> In case of iOS projects, keep the .sh script files in the same directory level as where you have the __.xcworkspace__ file.

> In case of Android projects, keep the .sh script files in the __/app__ directory

### appcenter-post.clone.sh
The `appcenter-post-clone.sh` 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 `.json` file and for that we will install an utility called [jq](https://stedolan.github.io/jq/download/) and to perform addition or other arithmetic operation we will use an utility called [bc](http://www.gnu.org/software/bc/).

{% gist https://gist.github.com/mistryhardik/16fa0d92996fbb48d48a7c8594fa7944
%}


### appcenter-pre-build.sh
The `appcenter-pre-build.sh` script will actually parse the Info.plist file or the AndroidManifest.xml file to read the current version information and to than we will convert the .plist into a temporary json file with the help of another utility called [plist](http://scriptingosx.com/2016/11/editing-property-lists/) or the .xml file to a temporary json file with help of utility called [grep](https://www.geeksforgeeks.org/grep-command-in-unixlinux/) and make use of the `bc` utility we installed in the `post-clone` step to increment the version information by __0.1__

#### iOS
{% gist https://gist.github.com/mistryhardik/b253827833b6b2e6c8afa546152e7a0e 
%}

#### Android
{% gist https://gist.github.com/mistryhardik/f12198a5ff377c84db17f57f95a68309 
%}

Alright so we the scripts already in place and if we re-run the build manually right now or every time a new build runs in AppCenter, 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 check if that branch is `master`, if yes, update the version or else, only display the version.
![](https://thepracticaldev.s3.amazonaws.com/i/5g6yzhasi6a7rgpmi45p.png)

### Summary
I have explored and use other alternate tools as well such as `Jenkins`, `bitrise` etc. `Jenkins` was too much overhead for me to administer the server and manage while `bitrise` was too much overwhelming to manage the steps of build etc. This does not mean that those options are not worth trying, it is just my personal opinion and those options might be the best fit for your scenario.

`AppCenter` did it just right (at least for me ;)

In this post we explored only one of the few abilities AppCenter has to offer, check out their [product blog](https://devblogs.microsoft.com/appcenter/) 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](https://twitter.com/mistryhardik05)

Happy building!