BuildIt Libraries using Continuous Delivery

BuildIt Libraries using Continuous Delivery

Following my previous post I’ve been wondering how hard it would be to setup continuous delivery for the BuildIt libraries (a small collection of libraries that help with things like state management and some nice additions to Xamarin Forms). We already have a build process and releases configured for each library so I figured it can’t be that difficult. I’ve been tracking what the team over at ReactiveUI are doing (see https://reactiveui.net/blog/2018/05/moving-towards-vsts-and-continuous-deployment) and as I mentioned previously I think their model can work well, assuming there are enough automated tests to validate quality. In the case of the BuildIt libraries, we have some tests but not enough that I would consider it full tested, nor to the point where I would be comfortable relying on tests to ensure quality.

With this in mind, I’ve made some changes to the process for BuildIt:

– We now have two main branches:

master – This tracks what has been released to nuget as a stable release.  All changes have to be PR’d into this branch and PRs can only be created by designated individuals. PRs also have to be approved and the VSTS build has to pass

develop – this is the default branch, and tracks what’s released to nuget as a beta release (ie x.x.x-beta). All changes have to be PR’d into this branch and PRs can be created by anyone. PRs have to be approved and the VSTS build has to pass

– The VSTS build is setup as continuous integration based on either master or develop branches

– Releases are setup in VSTS pushing only to nuget (I’m considering using myget at some point too)

Alpha – Build artefacts are packaged and deployed to myget as a beta release. This is setup as continuous delivery from all branches

Beta – Build artefacts are packaged and deployed to nuget as a beta release. This is setup as continuous delivery, but has a condition that limits it to builds from the develop branch

Stable – Build artefacts are packaged and deployed to nuget as a stable release. This is setup as continuous delivery, but has a condition that limits it to builds from the master branch

The important thing for me was that anyone can submit code to create a feature or fix a bug and raise a PR on develop. The only thing in the way of a new package being released that can be tested is an approval on the PR. Limiting PRs to master limits adds a little bit of friction and allows for a bit more quality control when releasing stable builds.

Having spent a bit of this morning configuring this, I was amazed that I could effectively complete the whole process of releasing a beta and stable release of the libraries from my phone (of course I had already committed the code changes to github from my desktop).

Continuous Delivery for OSS Projects

Continuous Delivery for OSS Projects

Over the last couple of years the Microsoft/.NET developer community has had to suffer through a substantial amount of crap thanks to some rather reckless decision making by Microsoft. There’s no single culprit but hands down the single point of failure for the Microsoft community right now is Visual Studio, and this in turn is suffering due to the continual mismanagement of NuGet. In the recent builds of Visual Studio things are gradually improving but updating package references for a moderately complex project almost gives me anxiety it’s so bad – you can loose days at a time stuck in NuGet hell before you work out how to get a project back to a stable state. So what does this have to do with CD for OSS projects? Well let me explain….

Last week we had the great privilege of having Geoff Huntley hang our in the Built to Roam offices and we were sharing stories about maintaining OSS projects. One of the topics he’s passionate about is shifting ReactiveUI to a continuous delivery model. When I heard this my first comment was “you mean to beta packages, right”? His response was that, no, CD all the way through to release packages. What this would mean is that once a PR has been merged, a build will be kicked off and a new release packaged pushed out to NuGet. This isn’t a new concept and it’s one that I’ve heard being used in practice quite successfully by some business (eg Domain.com.au talk about it on their engineering blog) but applying it to an OSS project was new and immediately interesting to me.

Before we go into what needs to happen to make this happen, let’s look at why you’d want to do CD for an OSS project. After MvvmCross release v6 I raised an issue discussing release schedule and versioning and one of the points I made is that in order to boost community contributions we wanted to have a known release schedule, particularly for bug fixes. Currently the goal is that if you submit a bug fix via a PR, it should be available in the next patch release, which should go out at the beginning of each month. But what if you only had to wait for your bug fix to be approved and merged – imagine if that then triggered a build and release of a new NuGet package that you could pull into your application. My belief is that this would significantly increase the willingness of the community to contribute and build a more collaborative ecosystem.

Here’s the kicker – what needs to happen in order to do CD? The answer is basically the same as any release process – you need to ensure the release meets your quality bar (however you chose to measure that). Currently for MvvmCross we have a minimal set of unit tests that are run as part of a build. Beyond that, we rely on the maintainers having a good sense of the stability of the framework – this in itself is pretty concerning but unfortunately all too common. The difficulty with a project such as MvvmCross is the sheer matrix of different platforms it supports (eg iOS, Android, UWP, Xamarin Forms (iOS, Android, UWP…..), WPF, MacOS…) and having to write unit and integration tests for all of them, and then be able to run each of the tests on real devices. There are solutions out there, such as App Center Test, which allows for tests to be run on real devices, but what do we do for platforms such as Tizen which aren’t in the list of supported test devices?

So back to my introductory comments – let’s assume that we can solve the CD quality bar issue and that we’re pushing out new packages each time a PR is approved. Now let’s also assume that every package author is setup to do the same, what does that mean for the application I’m building – am I going to be suffering a heart attack every week from the continual need to upgrade package references?

One suggestion is to let Visual Studio start to do the heavy lifting for you – set you packagereferences to use Version=”*” for all packages – this will use the latest stable package and will upgrade as and when they change. Of course, there will be scenarios where you may need to intervene and set specific package versions (eg where there are incompatibilities between different package versions).

To go along with this suggestions is a massive word of caution – whilst in theory this should work well, as we move to a model where more packages are releasing more frequently, Visual Studio will need to keep pace. I don’t believe the current NuGet infrastructure within Visual Studio could handle CD for all package references (and that’s assuming NuGet itself could handle it!!!). Let’s hope that Microsoft are onto this already and have some massive improvements in the pipeline.

Update 6th May: Unfortunately it appears that I was premature in suggesting that we can set the Version in packagereference to *, specifically for cross platform development. Whilst it does appear to work for .NET Standard libraries, it does not work for legacy project types such as Xamarin Android, Xamarin iOS and UWP. Until these project types are updated to handle * versioning, you’re going to have to continue to fix the version referencing.