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.