In general, when people install packages from NuGet, they want the latest “stable” release of that package, whatever that means to the package owners.

However, sometimes, developers want to be able to grab the latest pre-release version of the package. We call these developers who live on the bleeding edge, daredevils!

User experience

In general, users should never see pre-release packages unless they explicitly ask for them. Thus:

  1. Pre-release versions of packages do not show up in the Add Package dialog.
  2. Pre-release versions of packages do not show up in response to the Install-Package command nor the  Get-Package –ListAvailable command (unless the –Prerelease flag is specified).

Note that Get-Package, which shows installed packages, will show all installed packages regardless of whether they a pre-release or not.

For this next release, we’re not planning to expose pre-release packages to the dialog in any way, unless they are already installed in which case they would be listed in the Installed tab. Instead, they’ll be exposed to the Package Manager Console via the –IncludePrerelease flag (we've added an alias so you can type –Pre and it’ll work too), which is geared towards power users.

Another thing a user should be able to do is update to and from pre-release packages.

Scenarios

The following is a list of scenarios we want to support:

  1. Semantic versioning
  2. Filtering out pre-release packages/package versions.
  3. Explicitly viewing pre-release packages.
  4. Upgrading from pre-release to release.
  5. Upgrading from release to pre-release (including when other packages have a dependency on that package).
  6. Release package taking a dependency on a pre-release package.

Semantic versioning

To support pre release packages. we're updating the version field in the nuspec to support a versioning scheme that is a superset of the scheme described at http://semver.org. We continue to allow 2-4 digit versions and additionally an optional special field as described by semver. Examples for valid version values include 1.0beta, 2.3.0, 1.3.878.23rc-2 etc.

Installing stable and pre-release packages

Let’s look at a sample scenario. Suppose Elmah 1.1 is the latest stable release, but there’s a beta of Elmah 1.1.1 in the feed as well as an old 1.0 beta.

Command Result
Install-Package elmah As before, installs the latest stable release, Elmah 1.1
Install-Package elmah –IncludePrerelease Installs the latest pre-release version, Elmah 1.1.1alpha
Install-Package elmah –IncludePrerelease –version 1.0beta Installs the Elmah 1.0 beta.

Newer Stable Release

Suppose in the scenario above, Elmah 1.1.1 is released as a stable release. Install-Package elmah –Prerelease will still install 1.1.1 because it’s a later release than the pre-release version. But if 1.1.2beta is in the feed, we’ll install that one. –Prerelease is a flag that includes pre-release packages into consideration. Without the flag, we exclude all pre-release.

 

Upgrading a package

Packages can be upgraded to and from pre-release versions. Thus, assuming Elmah 1.1 is installed:

Command Result
Update-Package elmah As before, upgrades to the latest stable release, Elmah 1.2
Update-Package elmah –IncludePrerelease Upgrades elmah to the latest version, pre-release or not. In this case, Elmah 1.2 even though it's not pre-release because it's the latest.

Assuming Elmah 1.1.1Beta is installed

Command Result
Update-Package elmah Upgrades to the latest stable release, Elmah 1.2

Version Tab Completion

When specifying a version for commands like Install-Package, the list of versions will by default only show stable versions. However, when the –Prerelease option is specified, the list of versions will only show pre-release versions.

For example, using the above example where we’ve added 1.2 to the feed:

Install-Package –Version {tab} Shows versions 1.1 and 1.2

Install-Package –Prerelease –Version {tab} shows versions 1.0 and 1.1.1

Design/Implementation Notes

ID/Version

The combination of ID/Version is still a "primary key" and must be unique for packages. Thus "Foo v1.0.0.0" and "Foo pre-release v1.0.0.0" will be treated as two distinct packages.

NuSpec

The version field supports 2-4 digit versions as before and additionally a special version to denote pre release packages. As described at http://semver.org, the special version must immediately follow the regular version portion, must start with a alphabet and can only contain alphabets, numbers and dashes. Internally, NuGet would treat all unspecified version components as 0 therefore 1.2alpha, 1.2.0alpha and 1.2.0.0alpha are equivalent.

Filtering pre release packages on the OData Feed and local repositories

The semantics of the IsLatest property in the package would be changed to be true only for stable releases. An addition IsAbsoluteLatest has been introduced to represent the latest package regardless of release type. For queries that pull down more than one version of a package, filtering would be done on the client. We could consider changing this behavior to filter on the server instead by adding an additional IsStable field to the OData feed.

NuGet.org

We’ll need to update the website to show pre-release versions called out in some manner (for example, in a manner similar to deleted versions of a package). We’ll also want to remove from NuGet.org to specify “Recommended” versions. Instead, the latest stable release will always be the “recommended” version. Pre-release packages that are uploaded should never obtain the “recommended” version status. With these UI changes, Recommended version is really a pre-computed value equivalent to “latest stable release”.

Dependencies

Suppose A (RTM) –> B (prerelease). Installing A will fail unless you specify the –Prerelease. The general principle is that we only allow prerelease installs when –prerelease is specified.

Building packages from projects

To support building packages from projects using semantic versioning, we would allow package authors to specify versions using the AssemblyInformationalVersion attribute.

Last edited Nov 18, 2011 at 5:49 PM by Haacked, version 12