Runtime: .NET Core 2+ Naming and Versioning

Created on 3 May 2017  路  28Comments  路  Source: dotnet/runtime

.NET Core 2+ Naming and Versioning

The .NET Core product includes a set of components and files that customers are asked to understand: installer packages, NuGet packages and multiple .NET Core distributions. Some of the components version together and others don't, which causes confusion. The 2.0 release will have a coherent versioning and naming strategy for all .NET Core components and distributions, which includes web pages, installers (and associated UI) and NuGet packages.

A major version boundary is the right time to make this level of change. In fact, this change is the major reason to jump to .NET Core version to "2.0".

First Principles

  1. Version all .NET Core distributions as 2.0.0 for the first release and then move forward together.
  2. File and package names represent the component or collection and its version. Version divergence will be reconciled at minor and major version boundaries.
  3. Installers that chain multiple components should clearly communicate the high order versions somewhere in the UI.

.NET Core 2.x file name and versioning

.NET Core 2.x will use the following format for file distributions:

[product]-[component]-[major].[minor].[patch]-[previewN]-[optional build #]-[rid].[file ext]

Here are examples of this format:

dotnet-runtime-2.0.4-macos.10.12-x64.pkg            # Mac runtime installer
dotnet-sdk-2.0.4-win10-x64.exe                      # Windows SDK installer
dotnet-sdk-2.0.4-linux-x64.tar.gz                   # Portable Linux binary archive

#Ubuntu file set needed for the SDK
dotnet-hostfxr-2.0.4-ubuntu.16.04-x64.deb           # Host policy
dotnet-host-2.0.4-ubuntu.16.04-x64.deb              # Host / muxer
dotnet-runtime-2.0.4-ubuntu.16.04-x64.deb           # runtime
dotnet-sdk-2.0.4-ubuntu.16.04-x64.deb               # SDK tools

Note: See the Linux packages section below for Linux package naming conventions.

Intermediate installer filenames

There are a number of intermediate packages created which are then combined into the final installer bundle. The intermediate filenames will also need to be adjusted for consistency and to resolve final bundle name conflicts.

The scheme below appends -internal to the component portion of filenames which are not meant for direct customer usage but are part of final bundle composition.

| Intermediate packages | Intermediate pkg-only | Customer-facing |
| :-- | :-- | :-- |
| _deb/rpm_ | _pkg_ | _msi/exe/zip/tar/pkg_ |
| dotnet-host | -internal | - |
| dotnet-hostfxr | -internal | - |
| dotnet-runtime | -internal | dotnet-runtime-* |
| dotnet-sharedframework-sdk | - | - |
| dotnet-sdk | -internal | dotnet-sdk-* |

Improvements relative to .NET Core 1.x:

  1. Readability is greatly enhanced by ordering the information from broad to specific, from left to right: product->component->version->platform.
  2. The runtime package name includes 'runtime'.

Open issue: Can the host and fxr be included in the same package?

Installer UI string changes

.NET Core installers for Windows and Mac will clearly describe their contents, as you can see in the following examples.

| Installer | Window Title | Other content in installer | What is installed |
| :-- | :-- | :-- | :-- |
| SDK | .NET Core SDK 2.0 (x64) Installer | .NET Core SDK 2.0.4 | .NET Core SDK 2.0.4 + .NET Core Runtime 2.0.4 |
| Runtime | .NET Core Runtime 2.0 (x64) Installer | .NET Core Runtime 2.0.4 | .NET Core Runtime 2.0.4 |

Preview releases will differ only slightly:

| Installer | Window Title | Other content in installer | What is installed |
| :-- | :-- | :-- | :-- |
| SDK | .NET Core SDK 2.0 Preview 1 (x64) Installer | .NET Core SDK 2.0.0 Preview 1 | .NET Core SDK 2.0.0 Preview 1 + .NET Core Runtime 2.0.0 Preview 1 |
| Runtime | .NET Core Runtime 2.0 Preview 1 (x64) Installer | .NET Core Runtime 2.0.0 Preview 1 | .NET Core Runtime 2.0.0 Preview 1 |

Preview releases are typical of the first patch release, so the .4 patch in the prior example has been changed to .0 for this preview example.

In the .NET Core 1.1 release, we decided to include two runtimes in the SDK. If we choose to do that again, in the .NET Core 2.1 release, for example, the installer UX will look like the following (only the SDK is shown since the Runtime isn't relevant):

| Installer | Window Title | Other content in installer | What is installed |
| :-- | :-- | :-- | :-- |
| SDK | .NET Core SDK 2.1 (x64) Installer | .NET Core SDK and Runtime 2.1.1
.NET Core Runtime 2.0.6 | .NET Core SDK 2.1.1 + .NET Core Runtime 2.1.1 + .NET Core Runtime 2.0.6 |

It is also possible that we need to fix the .NET Core SDK but re-ship an existing runtime. In that case, we would bump the SDK version (for example, to 2.1.2) and then have the Runtime catch up the next time it shipped (for example, both the Runtime and SDK ship the following time as 2.1.3).

Improvements relative to .NET Core 1.x:

  • Installer UI will be consistent across platforms.
  • Installer UI will include complete information for SDK and Runtime versions.

Linux packages

Currently the only native Linux installers we produce are for Ubuntu but additional installers are planned. Linux package managers support chaining rather than embedding. Because of this, we release discrete packages for each component on Ubuntu which are chained by a controlling package referenced at install time. Using the name format proposed above:

dotnet-sdk                         # Latest stable version of the SDK
dotnet-sdk-2.0                     # Latest stable version of the 2.0 SDK
dotnet-runtime                     # Latest stable version of the runtime
dotnet-runtime-2.0                 # Latest stable version of the 2.0 runtime

Developers on Ubuntu would install either the SDK or runtime package, depending on their needs. The following command would install the latest SDK, a specific SDK version and a specific runtime version, respectively:

  • apt-get install dotnet-sdk-2.0
  • apt-get install dotnet-runtime-2.0

Viewing the results in the package manager after installation will show something similar to the following after installing the SDK.

dotnet-sdk-2.0/xenial,now 2.0.0-1 amd64 [installed]
dotnet-host/xenial,now 2.0.0 amd64 [installed,automatic]
dotnet-hostfxr-2.0.0/xenial,now 2.0.0-1 amd64 [installed,automatic]
dotnet-runtime-2.0.0/xenial,now 2.0.0-1 amd64 [installed,automatic]

For other Linux distros, we will make choices that satisfy the given distro requirements while aligning as closely as possible with the component naming and versioning that is defined above.

Improvements relative to .NET Core 1.x:

  • Provide two entry-point versioned packages, one for the SDK and one for the runtime.
  • Enables update functionality using Linux package managers where native installers are used.
  • Provide a top-level dotnet package, which points to the latest SDK version. This is the same as latest in Docker.
  • Rename sharedframework package to runtime.

Docker

A general Docker tag naming convention is to place the version number before the component name. This convention may continue to be utilized. The current tags include only the Runtime version as follows.

  • 1.0.8-runtime
  • 1.0.8-sdk
  • 2.0.4-runtime
  • 2.0.4-sdk
  • 2.1.1-runtime
  • 2.1.1-sdk

The SDK tags should be updated to represent the SDK version rather than Runtime.

It is also possible that we need to fix the .NET Core Tools but re-ship an existing runtime. In that case, we would bump the SDK version (for example, to 2.1.2) and then have the Runtime catch up the next time it shipped (for example, both the Runtime and SDK ship the following time as 2.1.3).

Meta-Packages

The NETStandard.Library and Microsoft.NETCore.App meta-packages are no longer an important developer concern in .NET Core 2.0. ASP.NET Core Meta-packages will continue to be a relevant part of the developer experience. They will match the ASP.NET Core version, as they have done in .NET Core 1.x.

The rationale for this change will be provided separately.

NuGet Packages

.NET Core will no longer be distributed via NuGet (for example, the System.Runtime package). ASP.NET Core will continue to be delivered as packages, and will continue to version like it was in .NET Core 1.x.

The rationale for this change will be provided separately.

.NET Core Websites and Documentation

The .NET Core websites and documentation have the important responsibility of making these releases easy to understand. It should be obvious what to download.

The .NET Core download page is the key page to improve. Changes that are made there will be straightforward to replicate on other pages. The SDK and Runtime views are quite different, so will be treated separately.

Runtime

See: https://www.microsoft.com/net/download/core#/runtime

  • The 3 part version is displayed. No change needed.
  • LTS and Current are clearly described. No change needed.
  • These is no link to release notes for the runtimes. Release note links should be provided.

SDK

See: https://www.microsoft.com/net/download/core#/sdk

  • No version is provided for the SDK. The 3 part version should be displayed.
  • Runtime versions are provided instead of the SDK version. These should be removed. The expectation should be that SDK and Runtime versions generally match.
  • These is no link to release notes for SDK. A release note link should be provided that describes everything about the SDK, most notably which runtime(s) is included.

General

  • fwlinks are used for all downloads. These should be changed to the actual download links. It is now appropriate to link to those files directly given the more intuitive link format.
  • Consider removing the word "download", which appears many times. If we need an extra word, consider "installer" and "archive", where appropriate.

Credit

Initial proposal was written by @leecow, @DamianEdwards, @richlander

Appendix:

.NET Core 1.x file name and versioning format

.NET Core 1.x uses the following format for file distributions:

[product]-[component]-[platform]-[arch].[major].[minor].[patch]-[previewN]-[optional build #].[file ext]

Here are examples of this format:

dotnet-osx-x64.1.0.4.pkg                            # Mac runtime installer
dotnet-dev-win-x64.1.0.1.exe                        # Windows SDK installer
dotnet-dev-fedora.24-x64.1.0.1.tar.gz               # Fedora 24 binary archive

#Ubuntu file set needed for the SDK
dotnet-host-ubuntu.16.04-x64.1.0.1.deb              # Host / muxer
dotnet-hostfxr-ubuntu.16.04-x64.1.0.1.deb           # Host policy
dotnet-sharedframework-ubuntu.16.04-x64.1.0.4.deb   # Runtime
dotnet-sdk-ubuntu.16.04-x64.1.0.1.deb               # SDK

This format has the following challenges:

1) It's difficult to easily scan the component / version pair
1) Nothing is obviously presented as a Runtime component
1) Naming inconsistency between sdk and dev packages across platforms.

area-Meta untriaged

Most helpful comment

Could runtime vs sdk versions be revisited?

When talking it over with devs, I constantly need to explain the difference between the SDK and Runtime versions. The recent move from 2.0.* to 2.1.* with newer MSBuild + Roslyn versions confused a lot of ppl (e.g. .NET Core 2.1 requires SDK 2.2.*) as well as how patch versions are handled.

There was a short period where a branch of the CLI produced 15.5.0-* versions, but that change was quickly reverted.

I see the following goals in versioning:

  • Be able to ship bugfixes of the runtime and CLI/SDK independently without needing to increase versions.

    • e.g. If a critical compiler bug needs to be shipped, the CLI would increase its patch version, but no change to the runtime is required.

  • Indicate feature updates via minor version increments

    • e.g. Roslyn, MSBuild and NuGet updates - like the 2.1.* CLIs that supports C# 7.2

  • Increment major version on breaking changes

    • Maybe tooling major versions will have more breaking changes than the runtime, which would be a pity to need to be delayed in the SDK until the runtime also makes breaking changes (I'm thinking of https://github.com/dotnet/cli/pull/7166 in particular)

  • Make it easier to understand why you need which version if you need to pin a version in global.json or require an update. (e.g. "You need at least version X to get support C# 7.2").

The only problem that this introduces is that the major versions looks similar to the .NET Core runtime version. They have all been 1.* or 2.*.

Proposed solutions:

  1. Align with other versions such as VS releases. Technically, it should align with MSBuild releases since that is the main component it relies on.
  2. Choose a different base major version. E.g. like year numbers to form versions like 2018.0.2. However, this may lead to SemVer inconsistencies when there was no breaking change in years and the product may seem outdated. Or it would violate SemVer by increasing the major version without breaking changes (=> marketing version instead of SemVer).

All 28 comments

.NET Core will no longer be distributed via NuGet

What exactly does this mean? Are the runtime.*.Microsoft.NETCore.* packages being done away with? If so, what will the new distribution method be?

Also wondering what that means. Is that the actual corefx libs or just the runtime and native bits?

What it really means is that you will not have to explicitly reference any packages by default to build a .NET Core application. It also means that the 100+ individual packages will not be available on NuGet. There will be a single package for the .NET Core Platform on NuGet that will be implicitly referenced when you target netcore2.0 in your project.

It also means that the 100+ individual packages will not be available on NuGet.

He means, starting with .NET Core 2.0. No existing packages on nuget.org will be harmed in the filming of this movie.

Are the runtime.*.Microsoft.NETCore.* packages being done away with?

That's a good question. @Petermarcu and @terrajobst would be better to answer that one.

In general, I did a bad thing by writing about this part of the plan in a vague and haphazard way. Sorry! @terrajobst will do a proper write-up of this soon.

As @tmds pointed out, Linux packaging was discussed and agreed on by just about every relevant party in https://github.com/dotnet/core-setup/issues/1599 and RH/MS meetings. I would like to suggest sticking to the resulting documents on Microsoft's side of packages as well, at least to some degree...

I have two questions:

  1. Could the examples be broken down to show which part of the name corresponds to which token? E.g.:

dotnet-2.0.4-preview2-123456-macos.10.12-x64-runtime.pkg

  • product = dotnet
  • major = 2
  • minor = 0
  • patch = 4
  • previewN = preview2
  • optional build # = 123456
  • rid = macos.10.12-x64
  • component = runtime
  • file ext = pkg

(I don't know if I've gotten all these right.)

  1. Would it be possible to swap previewN for the standard {alpha|beta|rc}N?

@adamralph I'm sure that someone else could explain it better, but preview is neither alpha, nor beta, nor release candidate. It's a preview...

There will be a single package for the .NET Core Platform on NuGet that will be implicitly referenced when you target netcore2.0 in your project.

I assume this would also hold true for the meta-packages when targeting netstandard2.0?

Yes.

There will also still be runtime.* packages that are hidden behind the TargetFramework and only used to build self-contained apps. They will be one flat package that contains the implementation of the TargetFramework for a given RuntimeIdentifier.

@adamralph I'm sure that someone else could explain it better, but preview is neither alpha, nor beta, nor release candidate. It's a preview...

And therein lies the problem. Most people don't know what "preview" means in terms of release quality, other than "not RTM". There is a widely recognised naming practice for "not RTM" packages, which is alpha, beta, RC. I'm proposing adopting that and dropping the "preview" approach.

@Thealexbarney We just chatted. The runtime.* packages will still be delivered via NuGet. This is needed to make this scenario work (publishing self-contained apps for another OS), for example: https://github.com/dotnet/dotnet-docker-samples/tree/master/dotnetapp-selfcontained.

I'm proposing adopting that and dropping the "preview" approach.

We would like to do that, but we have a fundamental challenge with it. We pick two things significantly in advance of shipping: the pre-release moniker and the ship-date. We are often targeting a Microsoft conference, typically Build or Connect and those dates don't move. We need the moniker in place for the engineering system to work, including branch names. In the past, we chose beta and rc monikers. We found that our quality was closer to alpha and beta, respectively, but it was much too late to change the moniker by the time that became the obvious end-point. That made everyone sad. As a result, we decided to go with a preview moniker to insulate ourselves from that problem. We don't want to mislead with moniker names that mean something specific. You could ask why we have these challenges in the first place. We have continued to make significant changes to .NET Core to make it better, which make pre-release builds rougher than is typical for a Microsoft product. Once that is done, pre-release versions will stabilize and we will consider returning to the more traditional pre-release monikers.

@richlander 馃憤 thanks for the explanation. It's good to know that you have the "standard" pre-release monikers in mind.

Are we sure -sdk is the right segment for our Linux package names? It seems to be a pretty wide industry standard to use -dev in package names:

  • lldb-3.8-dev
  • python-dev
  • mono-devel (they added a few extra characters)
  • libtbb-dev
  • libc6-dev
  • libssl-dev
  • libkrb5-dev
  • libcurl4-openssl-dev
  • zlib1g-dev

@eerhardt discussed in: https://github.com/dotnet/core-setup/issues/1599


_(A grumpy comment: I still don't like how all our effort in the above ticket is ignored by Microsoft. Not an open-source-way.)_

@richlander can you also include guidelines for 'stores'

Per @bleroy 's comment on https://github.com/aspnet/Home/issues/2033, Microsoft plans to put the ASP.NET Core store in the sdk package:

The SDK installers that Microsoft ships will include everything, including the runtime package store.

@eerhardt also I forgot to mention, the -dev suffix is from the Debian branch of Linux distributions, while the -devel with a few extra characters is coming from the Fedora branch... I imagine that there are some stray packages on both sides, but that's the origin of these suffixes.

Much welcome improvement. One suggestion I have is to make sure you use uname-compatible naming of distro/architecture, because the common pattern in deployment scripts is to use the output of uname to form the name of the package to download, i.e.

# arch name
$ uname -m
x86_64

# OS name
$ uname -s
Linux

Then I can have something portable like:

$ curl -o https://host/path/dotnet-sdk-$(VERSION)-$(uname -s)-$(uname -m).tar.gz

Thanks for the feedback @kontsevoy!

Another change which we've made in .NET Core 2 which I need to account for in this document is 'portable' Linux builds. This will take care of uname -s compatibility. Architecture might be a little tricker as the runtime contains architecture-specific files but we'll have a look to see if there are viable options.

Could runtime vs sdk versions be revisited?

When talking it over with devs, I constantly need to explain the difference between the SDK and Runtime versions. The recent move from 2.0.* to 2.1.* with newer MSBuild + Roslyn versions confused a lot of ppl (e.g. .NET Core 2.1 requires SDK 2.2.*) as well as how patch versions are handled.

There was a short period where a branch of the CLI produced 15.5.0-* versions, but that change was quickly reverted.

I see the following goals in versioning:

  • Be able to ship bugfixes of the runtime and CLI/SDK independently without needing to increase versions.

    • e.g. If a critical compiler bug needs to be shipped, the CLI would increase its patch version, but no change to the runtime is required.

  • Indicate feature updates via minor version increments

    • e.g. Roslyn, MSBuild and NuGet updates - like the 2.1.* CLIs that supports C# 7.2

  • Increment major version on breaking changes

    • Maybe tooling major versions will have more breaking changes than the runtime, which would be a pity to need to be delayed in the SDK until the runtime also makes breaking changes (I'm thinking of https://github.com/dotnet/cli/pull/7166 in particular)

  • Make it easier to understand why you need which version if you need to pin a version in global.json or require an update. (e.g. "You need at least version X to get support C# 7.2").

The only problem that this introduces is that the major versions looks similar to the .NET Core runtime version. They have all been 1.* or 2.*.

Proposed solutions:

  1. Align with other versions such as VS releases. Technically, it should align with MSBuild releases since that is the main component it relies on.
  2. Choose a different base major version. E.g. like year numbers to form versions like 2018.0.2. However, this may lead to SemVer inconsistencies when there was no breaking change in years and the product may seem outdated. Or it would violate SemVer by increasing the major version without breaking changes (=> marketing version instead of SemVer).

@dasMulli's suggestion addresses things that have been bugging me.

fyi: new proposal for CLI version numbers is in PR by @KathleenDollard: https://github.com/dotnet/designs/pull/29

This is replaced with @KathleenDollard: https://github.com/dotnet/designs/pull/29

I apologize for the delay in updating/closing this issue.

Re-opening as this document covers significantly more ground than https://github.com/dotnet/designs/pull/29. CLI section of this post can be updated as appropriate.

@leecow @KathleenDollard @richlander

I'm fine with this so long this issue gets resolved by a PR that is merged. This repo isn't meant to have designs sitting here as issues -- the designs are to be checked in and issues are to be closed, just like regular source code.

So who is on the hook for this?

Seems like the 'doc' form probably should live on /core. I'll aggregate and PR.

Many of these things were implemented already or no longer make sense because they have been superseded with other ideas. In any case, this doc is now very stale.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bencz picture bencz  路  3Comments

jchannon picture jchannon  路  3Comments

matty-hall picture matty-hall  路  3Comments

omajid picture omajid  路  3Comments

iCodeWebApps picture iCodeWebApps  路  3Comments