I love automating processes and making things consistently repeatable.  Continuous integration is your friend, yes it can take time to setup but if you take that effort hit upfront it will pay off in an immeasurable way through your development process and during the entire lifetime of the your development.

For my continuous integration I use JetBrains TeamCity.  I love this CI system, granted I’ve not used them all but comparing them to TFS and Jenkins it is like an oasis of calm in comparison and without doubt the cleanest UX design by a very long margin.  Anyway … I digress.  If you want to automate the process of producing your ready to distribute Xamarin .apk Android application packages, this is the basic process you need to follow:

Creating Your Keystore

The first step is to create your own personal keystore that will contain the information used to digitally sign your Android package files.  You can do this with the following command:

"C:\Program Files (x86)\Java\jre1.8.0_45\bin\keytool.exe" -genkey -v -keystore myandroid.keystore" -alias myaliasdroidpub -keyalg RSA -keysize 2048 -validity 30000

Before you run this command make a note a few parameters first.  I did all of this in a batch file so I can refer to it later, this does include some sensitive data so beware what you do with this file.  The 30000 at the end of the command denote the length of validity of the certificates and Google require this to be past 2033.  You’ll need the following info:

REM — Password – <yourpassword>
REM — name —– <yourname>
REM — OU ——- <organisationunit> eg: JamSoft
REM — Orgname — <organisationame> eg: JamSoft
REM — Local —- <locality> eg: Frome
REM — State —- <state> eg: Somerset
REM — Country — <2lettercountrycode> eg: UK

Visual Studio Android Project

Now that we have our Java keystore ready and prepped for use we can look at the Visual Studio project.  In order to make this automated in the build system we need to configure the project to use our keystore credentials.  This is spreading sensitive information around but since our keystore is probably going to be checked into our repository it’s most likely going to spend it’s life being treated in a sensitive fashion anyway, so no real concerns.  I personally make lots of backups of things in large .RAR files and store these in various places but these are also password protected and treated as confidential.

In Visual Studio edit the Android application .csproj file and add another PropertyGroup element as per the code below:

  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
    <AndroidKeyStore>True</AndroidKeyStore>
    <AndroidSigningKeyStore>myandroid.keystore</AndroidSigningKeyStore>
    <AndroidSigningStorePass>yourpassword</AndroidSigningStorePass>
    <AndroidSigningKeyAlias>myaliasdroidpub</AndroidSigningKeyAlias>
    <AndroidSigningKeyPass>yourpassword</AndroidSigningKeyPass>
  </PropertyGroup>

Now our .csproj file knows how to use our keystore unattended. We can tie into the Xamarin build process from within our automated builds and produce the base Android package.

You can test that this is working using the following command:

msbuild.exe HelloWorld.csproj /p:Configuration=Release /t:PackageForAndroid

This will execute MSBuild against your Android project file and you’ll now find your .apk file in your bin\Release directory.

Signing The Package

Now that we have our packaged application we can apply the signing processes.  To sign the package created in the previous step we need to execute the following command:

"C:\Program Files (x86)\Java\jdk1.7.0_71\bin\jarsigner.exe" -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore myandroid.keystore -storepass yourpassword -keypass yourpassword -signedjar \bin\Release\packagename-signed.apk \bin\Release\packagename.apk myaliasdroidpub

This package is now digitally signed using your certificate from the keystore we made earlier. Personally I still have a couple of questions around why this needs to be done again considering that the details for this keystore are in the csproj file but I’m still waiting on a response from Xamarin on this.

ZipAligning the Signed Android Package

Now that we have a signed package we can zip align this package and then publish this as an artifact of our TeamCity build process.  This command makes use of the Android SDK zipalign.exe program.  You’ll have to find where this is on your machine as there are many potential locations.  The command you need will look something like this:

“C:\Users\<name>\AppData\Local\Android\android-sdk\build-tools\<version>\zipalign.exe” -f -v 4 packagename-signed.apk packagename-zipaligned.apk

You don’t need to follow this naming convention used here this is just for illustration purposes.

You can now set this as a published artifact of your TeamCity build configuration.  Yay!

MSBuild Project

To kick off the process in your MSBuild project you can add TeamCity Step that executes an additional Target in your build script like this:

  <Target Name="PackageAndroidApk">
    <MSBuild Projects="$(MSBuildProjectDirectory)\..\src\path\MyProject.Droid.csproj" Targets="PackageForAndroid" Properties="Configuration=Release">
    </MSBuild>
  </Target>

This target will create the base APK package that you can sign and zipalign.

Once you have all these commands working you can add all the required build steps.

Capture

And voila!  Automated.  Nice 🙂

Xamarin iOS Build Server is Too Old
TeamCity Backup Location Outside TeamCity Data Directory

Discussion

  • Commenter's Avatar
    diegoxleon — February 3, 2016 at 6:17 pm

    Really nice and easy explanation.
    I used team city before in .NET server projects, but never for Xamarin apps.
    I´m looking forward to get some time to integrate this plus a last build step that would be uploading the apk to hockeyapp. Also I need to learn how to actually write tests in client apps as I´ve never done that.
    What kind of things do you test? logic? ui?

    • Commenter's Avatar
      jammer — February 3, 2016 at 11:03 pm

      Hey Chap,

      Glad you found it useful. Team City is one of my favorite CI systems I’ve used, really a big JetBrains fan I have to say. This will get expanded upon once my Xamarin apps start to be distributed and reach a level where we start beta testing. Including the iOS application as well. I really haven’t done any much more than Debug builds in CI for iOS so far.

      As for tests at the moment they cover off mainly just the MvvmCross core project where most of the application logic and application flow resides. One of the core design goals of Mvvm when it was first devised (by John Gossman – the architect of WPF) was for unit testing. Since one of the core elements of WPF was composite UIs the idea was to achieving a design that would enable testing as much as possible, arguably any “higher” testing and you would actually start to test the .NET framework itself which is far from a “unit test”.

      I do plan on also making use of the UITesting framework from Xamarin but that is also a little way off yet.

      Best,

      Jammer

  • Commenter's Avatar
    Rohin — September 16, 2017 at 6:51 am

    Very simple to follow and straightforward explanation.
    This is the only place I could find something valuable for Xamarin.Android build automation.
    Could you please help me understand what all parameters are required and what do they exactly mean, in the MSBuild command.
    Like, /t:PackageForAndroid (Here what is the package for android and is it a required parameter.)
    Would be awesome for a novice developer like me.

    Thanks again for thr article. 🙂

    • Commenter's Avatar
      jammer — October 24, 2017 at 12:24 pm

      Thanks for the feedback, unfortunately I just don’t have the time to go over all this in detail at the moment. Maybe one day … glad it all helped.

Leave a Comment

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.