Coming soon!

Continous integration with Xamarin, TeamCity and FAKE – Part 2

In the previous post I talked about setting up your environment with different build configurations so you can easily switch between an alpha, beta or production iOS/Android build. This time I’ll talk about creating a build script which you can use with your CI implementation. Our weapon of choice? FAKE. “FAKE – F# Make” is … Continue reading Continous integration with Xamarin, TeamCity and FAKE – Part 2 →

  • Mobile development
  • Xamarin

By Thomas Van den Bossche · 1/9/2016 1:42:21 PM (Original Post)

In the previous post I talked about setting up your environment with different build configurations so you can easily switch between an alpha, beta or production iOS/Android build.

This time I’ll talk about creating a build script which you can use with your CI implementation.

Our weapon of choice? FAKE.

“FAKE – F# Make” is a build automation system with capabilities which are similar to make and rake. It is using an easy domain-specific language (DSL) so that you can start using it without learning F#. If you need more than the default functionality you can either write F# or simply reference .NET assemblies.

Little note: there’s actually a similar project in C# called CAKE but it hasn’t the complete functionality we need at the moment (HockeyApp integration is one of the missing parts).

Our build script will have several targets.

Targets are the main unit of work in a “FAKE – F# Make” script. Targets have a name and an action (given as a code block).

We’ll cover the Android setup here, but you should be able to easily set this up for iOS yourself.
The targets of the Android project are:

  • “restore-packages-project”
  • “restore-xamarin-components-android”
  • “android-build”
  • “android-package”
  • “android-hockeyapp” (will be discussed in a future post)

Each target in the list has a dependency on the target above it.
If you execute the android-build target, it will automagically run restore-xamarin-components-android and restore-packages-project.

How do we define this dependency in FAKE?

“restore-packages-project”
==> “restore-xamarin-components-android”
==> “android-build”
==> “android-package”

Place this at the bottom of your script.
Now let’s create each target.

Target "restore-packages-project" (fun _ ->
     String.Format("../solutions/{0}.sln", projectName)
     |> RestoreMSSolutionPackages (fun p ->
         { p with
             OutputPath = "../solutions/packages"
             Retries = 4 })
)

This target will restore all NuGet packages in the given solution.
As you can see the project name is defined in a variable which allows for reuse on different projects.

Target "restore-xamarin-components-android" (fun _ ->
    Shell.Exec "mono" ("tools/xamarin-component.exe restore" + android_solution)
)

If you don’t use Xamarin Components, you can delete this step.
If you do need this, you will first need to download the xamarin-component.exe. The link provided will download a XPKG file. Change the extension to a ZIP-file and extract the contents.

Place this file somewhere where your script can access it and provide the correct path to it in the script.

Remark: You will need to run the .exe one time manually on the build server because it will ask for your Xamarin credentials. You only need to do this once.

Target "android-build" (fun () ->
    CleanDirs [buildFolder + "/android/"]

    let buildProperties = 
            [("Configuration", buildConf); ("Platform", "Any CPU"); ("VersionCode", buildcounter); ("VersionName", releaseversion)]

    MSBuild (android_buildFolder) "Rebuild" buildProperties [android_solution] |> ignore
)

This target will do the actual compiling of the project.
It first cleans the directories and then starts the compiling with the correct parameters.

The projectBuildConfiguration variable will contain our alpha, beta or production build configuration from the previous post.
The buildcounter variable is the incrementing value used when new versions are released and the releaseVersion variable is the semantic version number.

That’s it. How do we trigger this FAKE script?
We’ve used a Bash script:

#!/bin/bash

while getopts :t:p:r:c:b:n: FLAG; do
  case $FLAG in
    t)
      TARGET=$OPTARG
      ;;
    r)
      # SEMVER
      RELEASE=$OPTARG
      ;;
    c)
      # INCREMENTING BUILD COUNTER
      COUNTER=$OPTARG
      ;;
    b)
      BUILDCONF=$OPTARG
      ;;
    n)
      PROJECTNAME=$OPTARG
  esac
done

nuget install FAKE -Version 4.6.2 -OutputDirectory packages -ExcludeVersion
mono packages/FAKE/tools/Fake.exe build.fsx $TARGET release=$RELEASE counter=$COUNTER buildconf=$BUILDCONF projectName=$PROJECTNAME

This Bash script will download the F# FAKE Nuget Package and call our script with the correct parameters.
You can completely test this script on your local machine before integrating it into your CI process.

ci-build__fake__blog

As you can see in the screenshot above, there are some extra steps of compiling a common solution (which contains PCL libraries to share between Android and iOS) and some unit tests steps which were out of the scope of this blog post.

Happy integrating!


  • Mobile development
  • Xamarin

By Thomas Van den Bossche · 1/9/2016 1:42:21 PM (Original Post)

Share this blogpost

Looking for talent?

Fill in the form below and we’ll get back to you as soon as possible.

Oops. You seem to have written your full name in invisible ink. Please enter it so we can read it. Oops. You seem to have written your company in invisible ink. Please enter it so we can read it. It seems your e-mail doesn’t exist. Please enter a real one so we can contact you. Oops. You seem to have written your telephone in invisible ink. Please enter it so we can read it.