A common pattern for NuGet package versions is producing two sets of .nupkgs for every CI build. That is two sets of functionally equivalent packages produced from the same source. Two sets are:
-
CI packages: a NuGet package version that is suffixed with a build number. This allows bleeding edge consumption of the latest APIs or fixes. These packages are typically pushed to a development package feed like VSTS or MyGet. Example version numbers:
4.0.0-rc-2046
,3.5.0-rtm-1996
,3.5.0-beta2-1543
-
Release packages: a NuGet package that has no build number in the version but may still have a prerelease label. This package is intended for official release to NuGet.org or to customers. Example version numbers:
4.0.0-rc
,3.5.0
,3.5.0-beta2
These two sets of packages should be produced by two separate invocations of nuget.exe pack
or dotnet pack
. At first glance, it is
tempting to produce one set of packages based on the other by simply copying the .nupkg and editing the contained .nuspec. This manual
approach should be discouraged as it promotes error-prone munging of NuGet's implementation details and likely breaks the upcoming
package signing feature. The pack
command should be the master of producing .nupkgs.
Finally, it is convenient to produce a set of release-ready packages every time a build runs to minimize the number of infrequently excerised release processes. Any build that passes the necessary quality checks should be able to be shipped by simple selecting the associated set of release packages.
It is possible for the assemblies in these two packages to have different assembly metadata. Typically the AssemblyVersion
and
AssemblyFileVersion
share the integer part of the package version and the AssemblyInformationalyVersion
matches the NuGet package
version verbatim (for simplicity and correlation). The AssemblyFileVersion
should include the build number.
It is not required for all packages produced by a CI build to have the same version number or release label. However, the build number component of a version should match.
When packing a .csproj, a <ProjectReference>
should be converted to a <dependency>
in the output .nuspec with a version defined in the referenced project's .csproj. dotnet pack
does not behave this way today, which is a bug tracked by NuGet/Home#3874.
In general, interdependent packages produced by a single CI build should have matching package and dependency versions so that the set of resulting packages does not have any package dependencies on previous CI builds.
In NuGet client, we use Preview 2 .NET CLI tooling (1.0.0-preview2-003121) to produce our cross-platform packages and nuget.exe (3.5.0-beta2-1520) to produce our Windows-only packages.
For all packages except NuGet.CommandLine
, the assembly metadata between the CI and release package does not vary. For NuGet.CommandLine
, the AssemblyInformationalVersional
must match the package version as part of the nuget update -Self
logic.
All of our packages have the same version, release label, and build number (with the one exception of SynchronizationTestApp
... which is probably a bug).
There are two styles of how a provided version suffix behaves in tooling:
Example 1:
- Version:
1.0.0
- Version Suffix:
rc
- Result:
1.0.0-rc
Example 2:
- Version prefix:
1.0.0-beta
- Version suffix:
final
- Result:
1.0.0-beta-final
Example 1:
- Version:
1.0.0
- Version Suffix:
rc
- Result:
1.0.0-rc
Example 2:
- Version:
1.0.0-beta
- Version Suffix:
rc
- Result:
1.0.0-rc
Build operations use the version suffix when constructing the AssemblyInformationalVersion
. Pack operations use the version suffix
when constructing the NuGet package version.
Tool | Release | Version suffix style |
---|---|---|
nuget.exe pack | < 3.4.0 | not supported |
nuget.exe pack | ≥ 3.4.0 | replace |
dotnet pack | Preview 2 | append * |
dotnet pack | RTM ** | replace |
dotnet build | Preview 2 | append * |
dotnet build | RTM ** | append |
* = only happens if there is a version ending in -*
in the project.json. Otherwise, the version suffix is ignored.
** = not yet released