MyGet Build Services - Package Versioning Explained
At MyGet, we do everything possible to reduce friction. It's in our DNA! Package versioning is currently the biggest roadblock you'll encounter when setting up a solution to automate package creation.
A NuGet package is uniquely identified by its package identifier and its version. This implicit requirement is often overlooked upfront and requires some thinking to define a proper versioning strategy. Luckily for us, some smart people already came up with something called Semantic Versioning (SemVer). We strongly believe in SemVer's pragmatic approach towards API versioning and the benefits that come with it.
Even though NuGet does not fully support the entire specification yet (the SemVer specification is still RC), it already has some features that allow you to benefit from using SemVer. An example of that is the Update-Package -Safe command option, which allows you to update your consumed packages to the latest safe package version: updates are constrained to the same Major and Minor package version. The only drawback of this feature is that you have to count on a safe versioning scheme applied by the package author. This is not guaranteed on the NuGet Gallery.
Build Source Configuration
If you set up MyGet Build Services for your feed, you'll get automatically created packages pushed to your feed. This implies automatic versioning. We've added some new capabilities to our Build Services in our recent MyGet v1.6 release. For one, we've added a UI to define the versioning scheme to be used.
You are in control
The biggest improvement is the fact that the build source now remembers the build counter for you, so you don't have to deal with maintaining a version.txt file or anything similar in your source repository. Of course, if you really want to, you still can: we're removing friction, not features! The build counter can easily be reset using the reset link. Similar to what popular build servers do (and any decent build server should do), you'll be able to define a versioning scheme using a placeholder for the build counter. You've now gained more control over the versioning "magic" we applied before.
In addition, you can gain full control by hooking into the build process. MyGet Build Services scans for the following source artifacts (in order of precedence):
- any other *.sln
- *.csproj (and *.vbproj, etc)
- *.nuspec (yep, we support packaging simple convention-based NuGet directories as well)
If you provide your own build.bat script or MyGet.sln, you specifically instruct MyGet Build Services how to act on your sources. This also means you'll need to take care of versioning yourself. That's why we provide you with the following set of parameters so you can benefit from using the versioning scheme you already defined, as well as the build-counter attached to your build source. Note that these environment variables are read-only and are reset to the initial values at the start of the build process.
|%BuildRunner%||Always "MyGet", can be used to determine if running on MyGet Build Services|
|%NuGet%||Path to a maintained-by-MyGet NuGet.exe|
|%SourcesPath%||Path to source code being built|
|%Configuration%||Build configuration (defaults to Debug)|
|%Platform%||Platform to build (defaults to blank)|
|%VersionFormat%||Version format specified in build configuration|
|%BuildCounter%||Build counter value|
|%PackageVersion%||%VersionFormat% with %BuildCounter% filled in, used as the auto-generated package version number|
|%EnableNuGetPackageRestore%||NuGet package restore enabled? Always true.|
Package Source Configuration
We've also pulled Package Sources out of beta for everyone to enjoy, including our Free users! Package sources play a key role in the MyGet Build Services workflow. By default, the NuGet Gallery is configured as an upstream package source. You could obviously also configure Chocolatey, an Orchard feed, or your own MyGet feed, or all of them! These upstream package sources allow you to reference or mirror packages onto your own feed. It also allows you to easily push packages from your feed to the the upstream package source, given you configured your API key in the package source configuration.
When you want to push a package upstream, you'll be prompted with a dialog asking you which upstream feed should be used. In addition, you'll also get the opportunity to modify the package version as it should appear on the upstream package source. Note that no compilation is happening, we're simply adjusting the package version if you changed it. Because semantically nothing changed to the package, you'll only be able to change the -PreRelease tag, or simply remove it and make your upstream package a full release.
Without enforcing them
We won't enforce you in using SemVer as this would introduce friction for those who don't want to use it. It's not up to the repository host to define your versioning approach: this is the responsibility of the feed owner. This is impossible on NuGet.org as the feed is owned by the Community, which is definitely not organized around a single common versioning scheme.
However, if you - as a MyGet feed owner - want to enforce it, then you can by simply checking the appropriate checkbox in your feed settings. We try to find a balance between removing friction and providing freedom in your choices, so we hope you like it! Don't hesitate to send us your feedback or log them on our UserVoice.