Continuos integration for Universal Windows Apps
We at DreamTeam extremely value continuous integration and other automation tools that allow you focus more on the sole business of the application rather than spending time on trivial things.
This is why one of the first things configured on each project is CI. Here are some tips how to do it right for UWP apps (Windows 10)
Why and how CI?
There are several goals that the team achieves with CI:
1. Providing quick feedback on the compilation status of the code.
Extremely valuable at those moments when sometimes you forget to push missing file or merge was done incorrectly.
Knowing about that right after the change allows developer fix the problem while still being in the context.
Configuring compilation CI build solves that.
Compilation build should be as fast as possible. Having compilation build running 15 minutes is not going to work.
For UWP application CI compilation build there is a special switch that makes build way faster (.
msbuild solution.sln /p:Configuration=$CONFIGURATION;AppxBundle=Always;AppxBundlePlatforms=\"ARM\" /p:BuildAppxUploadPackageForUap=true /p:UapAppxPackageBuildMode=CI /p:Platform=\"ARM\"
Since our project is targeting mobile side of UWP only, we’re building CI in the ARM configuration to keep it as close as possible to the release build.
2. Providing fresh build from dev branch to QA and everyone in the project to be able to check out project status and specific things at once and have access to the freshest code.
3. Providing iteration builds from master branch or maybe from any other branch (depends on your git strategy).
These builds we usually want to run once in a while so that the customer (either it’s our team itself or external entity) is not overwhelmed with number of notification and versions and updates.
Also brings clarify when you see all the changes done during iteration in the release notes.
Goals 2 and 3 are achieved with the same build configuration and different schedule or triggers.
Correct parameters to have MSBuild prepare you a installable and ready package that you can later upload to HockeyApp (for example) are following
msbuild solution.sln /p:Configuration=$CONFIGURATION;AppxBundle=Always;AppxBundlePlatforms=\"ARM\" /p:BuildAppxUploadPackageForUap=true /p:Platform=ARM
Here, if you want to have multiple platforms, you can specify AppxBundlePlatforms parameter in format “x86|x64|ARM” and have final package with all 3 platform-specific packages inside.
Since we have mobile app, we decided to drop x86/x64 builds to save time. This cut build time from 15 minutes to 5 minutes.
Another important moment is to enable “Compile with .NET Native tool chain” option for the target configuration(s) (i.e. for Release). Make sure you’re also selecting “All Platforms”, not just x86 as on the screenshot below.
Crash reporting for UWP apps
Right now only platform that supports crash reporting for UWP and is able to analyze crashes based on .NET Native symbols is HockeyApp. This makes choice obvious.
For the HockeyApp integration, you want to make sure you upload correct .pdb files since there are many of them in the output folder. Some are generated by .NET itself, some by .NET Native. You’re looking for the latter.
Usually, you will find them at the following location:
To upload them to the HockeyApp, please compress them and specify as @dsym parameter (symbols).
After the build we upload to the HockeyApp two files. AppxBundle and native pdb zip
This allows users with Windows 10 Mobile devices download the package from the HockeyApp and install it by double tapping downloaded file on the phone.
There are also few articles on integrating HockeyApp SDK into UWP apps, strongly recommended to read (Crash reporting for UWP, How to instrument UWP applications for crash reporting).
One takeaway from the documentation is that you have to use VS 2015 Update 2 if you want to get your crashes right. We had it outdated (Update 1) on the build server.
Another common task in CI is injecting values from the build configuration into C# code. There are ways to do that (using msbuild and xml transformation, then reading xml at runtime, echo-ing values to the C# code).
For this project we decided to skip the XML part and use C# code generation based on T4 templates. We’ll explain that in a separate article.
We’d love to hear about your experience with UWP apps and continuous integration. Please let us know in the comments or through email http://dreamteam-mobile.com/#contact