Continuous deployment Xamarin Forms apps with Visual Studio Team Services (VSTS) and HockeyApp
Conceptually, continuous deployment with VSTS and HockeyApp sounds like an easy task to do. But there are details that if you don’t know or can’t figure out, it will turn out to be difficult and you won’t be able to complete your task.
Before you start, you would need to have an account with Xamarin, VSTS and HockeyApp. I also assume the following:
- You already know how to write Xamarin mobile apps
- You know how to archive for publishing and deploy to HockeyApp manually
- This article only focuses on Android. I hope to write a similar one for iOS soon.
- In VSTS web interface, switch to the Build tab. We first create a Xamarin.Android build definition (even if you are using Xamarin Forms to build you app)
2. Configure all Git-related settings such as the Git host, git repository and select the git branch. Check the Continuous integration box. If you don’t, you can still run on-demand later.
4. You should get a default Xamarin.Android build definition. The steps Activate Xamarin License, Xamarin Test Cloud and Deactivate Xamarin License are shown in red initially. Fill in with email and password from your Xamarin account and other data that you can get from the Xamarin portal are self-explanatory.
5. Add a HockeyApp Deploy step. Similarly, HockeyApp data can be gotten from its portal. Now you should have something like this:
6. Save it, give it a name and go ahead and click on Queue build. If you didn’t check that Continuous integration box earlier, you can always run manually using this method.
7. It will fail in the Build step, but this is the reason why you are reading this. I will show you how to make it work.
8. That’s OK. Scroll to the very top and you will see the lines similar to the ones below:
9. Notice the second line Checking out to 1c77… to C:\a\1\s
10. Click on the Variables tab and define a variable called SolutionDir and assign C:\a\1\s\ to it (note ending slash):
11. Save and run Queue build again.
12. All the steps go green and everything seems to work. The app gets deployed to HockeyApp. We’ll get an email, download the apk and try to run but will encounter a parsing error. The problem is we didn’t sign the apk for distribution correctly.
For the next step, we will configure the Android Signing step. But to do so, we will have to first do this manually.
In Xamarin Studio, choose Archive for Publishing, then Sign and Distribute, then Ad Hoc, then Create a New Key. Note the Alias and Password of the new certificate that you’re about to create.
Fill in the rest of the form, click on OK. This will save a file with a .keystore file extension. Locate this file which will be obvious in the final screen of this process and copy it to where your Android project file .csproj is. You will need to do a git add on this .keystore file.
13. Back on VSTS web interface, in the Build definition, switch over to Variables tab and create a variable called keyStorePasswd. The value for this variable is the same as the password you entered in Xamarin Studio when you signed the certificate.
14. From Variables tab, switch over to Build tab, check the Sign the APK and Zipalign boxes. The location for KeyStore File must start with C:\a\1\s\… and looks like what is shown below. Of course, replace the part [Solution] and [Project] with the name of your project. The alias must be the same alias that you signed in Xamarin Studio.
Points of interests
- Whether you want or not, you must start with Xamarin Studio to do the Archive and Publishing because this would create a .keystore file which will be used in VSTS continuous deployment here. I recommend that at least once, you manually upload the resulting apk to HockeyApp using HockeyApp portal. When in doubt, you can always go back to this manual method.
- I didn’t show the Xamarin Test Cloud build step and have not tried that.
- Seems like a hack in step 9 when I found the folder C:\a\1\s\. That’s because I reverse engineered. I can’t find any pre-defined variable in VSTS or HockeyApp documentation and that’s the only way I could make to work.
- But having defined the variable SolutionDir that has a value of C:\a\1\s\, I expected that I could this variable when specifying the location of the keystore file in step 14, but nope, that didn’t work.
- The Xamarin password used in the Xamarin License Activate and Xamarin License Deactivate step could and should be placed in a variable too. Refer to how the $(keyStorePasswd) was defined and used.
As a result of using what I showed above, every time you commit to the master branch (or whatever branch you specify in the Repository tab), an Android build will be triggered and eventually deployed to HockeyApp which handles ad-hoc distribution of your app.