NuSpec version attribute vs assembly version - nuget

When creating a nuget package, the version in the file name of the nuget package seems to come from the AssemblyInfo file in the web application project. I have also created a version attribute inside the nuspec file.
What is the relationship between these two version numbers and are there any conventions attached?

With regards to convention, the NuGet software itself, and the semantics it applies to packages in the gallery, does versioning as described by SemVer.
Specifically you can designate beta versions by suffixing your nuspec version number with "-beta.4" or something. For example, see how the gallery displays the latest version of AutoFac, and compare how it displays an old release (note the text "This is not the latest version of Autofac available." Edit: The gallery no longer seems to provide any special message for non-current versions) and an old PRE-release version (with the text "This is a prerelease version of Autofac.").
Unfortunately, the AssemblyVersion in AssemblyInfo.cs may not contain letters or hyphens, so it can't be used in this way. However the AssemblyInformationalVersion MAY have letters and hyphens in it and, if you provide it, NuGet will use that instead of the AssemblyVersion to replace the $version$ token in your nuspec file. What's more, the AssemblyInformationalVersion (also called the "Product Version" if you check a DLL's details in windows explorer), at least to me, better represents what the NuGet version should match.
I have a slight concern with this approach in that I'm expected to leave the AssemblyVersion the same through various beta iterations and a final production iteration of the AssemblyInformationalVersion, which means I'm allowing several different versions of my DLL into the wild that may behave differently or incorrectly, yet are all identical as far as the CLR is concerned (the CLR only cares about AssemblyVersion). In practice, though, this happens frequently (including with the AutoFac packages described above) and it doesn't seem to cause a problem.
See the two excellent highest-voted answers to What are differences between AssemblyVersion, AssemblyFileVersion and AssemblyInformationalVersion? for more info on AssemblyInformationalVersion and friends.

There doesn't need to be a relationship between the assembly version and the nuget package version. By convention, many maintainers use the same number for both.
The convention for using the same number is also the nuget.exe default if you have no nuspec, or you use nuget.exe spec to create a tokenized nuspec file. However, if you replace the $version$ token with a value, then that value will take precendence and will be used in the package file name.
You can also set the version on the command line, which takes precedence over all of the above.
More info on Xavier's blog: NuGet $version$ token explained

Related

Mix existing and AssemblyInfo patcher generated version info in TeamCity builds

I've enabled a "Build Feature" called "AssemblyInfo patcher" to tweak the version of DLLs generated by my TeamCity builds. I've remixed info from this other question and came up with this Assembly version format setting:
1.0.%build.vcs.number%.%system.build.number%
Now the final thing I would like to achieve is have the Major (1) and Minor (0) come from the original files, instead of hard coding them into TeamCity.
How can I do that?
I've guessed / tried:
{1}.{0}.%build.vcs.number%.%system.build.number%
But this gives an error. I've tried:
%build.vcs.number%.%system.build.number%
But this generates the vcs.number and build.number as major/minor instead of build and revision number, so e.g. 1234.21.0.0.
I've read the AssemblyInfo patcher documentation but it doesn't explain much at all.
I've skimmed the available variables (with the icon to the right of the input field) but found no relevant variables.
How can I set up the "AssemblyInfo patcher" so that:
Major and Minor are kept as they are in the source files;
Revision is the VCS revision number;
Build is the TeamCity build number.
If it's possible at all?
You can use File Content Replacer. It provides the ability to reference capturing groups of the regular expression and change only specific parts of AssemblyVersion attribute.

LocalPackageRepository returns IsLatestVersion=true for all packages

I've created a folder on my C:\packages. Inside I've created two packages with identical Ids but have different versions. I the use Nuget.Core to create a LocalPackageRepository pointing to this directory.
When I query for the packages using respository.FindPackages("myId")both packages are correctly returned by the service. However, the IsLatestVersion is true for both packages, even though their versions are clearly different.
Things I've tried:
I know these packages dicovered as OptimizedZipPackages looking through the source here, I cant find anything relevant to suggest an issue with the implementation.
I added the local repository to my Visual Studio NuGet feed manager. When I query that service, the latest version is shown.
Something seems to be wrong with how I've either created the packages, instantiated the repository, or its a bug in the library.
Using NuGet Core v2.8.60318.667
Looking at the source code the LocalPackage always returns true for IsLatestVersion if the NuGet package is not a pre-release.
In Visual Studio what happens is that the list of packages is further filtered by removing all but the latest version in the list so you only ever see the latest version. One way to do this is to use extension methods included in NuGet:
packages.DistinctLast<IPackage>(PackageEqualityComparer.Id);
The DistinctLast method assumes that the same NuGet package id will appear together in the list otherwise it will not filter them correctly.
I believe you could also use the AsCollapsed extension method which is similar to the above. It basically does:
packages.DistinctLast<IPackage>(PackageEqualityComparer.Id, PackageEqualityComparer.Version);

How to create a NuGet package which will not be picked up automatically by Update-packages

I am making a change to some code which I need for one component of my application but which I do not wish to release to the rest of my application due to concern that it might have an unintended side effect.
We currently name our packages major.minor.hotfix.buildnumber with our system on say 1.4.9.600 I'd like to release a package along the lines of 1.4.9-branch.601 which can only be chosen manually and wouldn't be picked up with the Update-packages command.
http://docs.nuget.org/docs/reference/versioning
You want the section labeled:
Prerelease Versions
//Quote//
Additionally, prerelease versions of your API can be denoted by appending an arbitrary string to the Patch number separated by a dash. For example:
1.0.1-alpha
1.0.1-beta
1.0.1-Fizzleshnizzle
Note that the actual string applied doesn't matter. If there's a string there, it's a prerelease version.
When you’re ready to release, just remove the dash and the string and that version is considered “higher” than all the prerelease versions. For example, the stable version 1.0.1 is larger than 1.0.1-rc
//End Quote
and then the "how to get it" command-line argument
Install-Package CoolStuff -IncludePrerelease

How to update nuget without changing version

I just published a package to nuget but realize I forgot to include a css file. My versioning is tied to the library I'm packaging (which I don't own) so I can't really increment it.
How do I force a re-push or what's the recommended thing to do in this scenario?
Found out an answer to my own question.
There is apparently no limit on how many version places there are so you can simple append yet another version place.
So for example if the package you're packaging is 0.0.1 you can upload another one 0.0.1.1

Fetching DLLs from NuGet if Deleted

I've done a fair bit of reading on NuGet, and I can't seem to find what I want. Essentially, I'm hoping that it will work like Apache Ivy, where you can just check in your config file (without any binaries) and tell NuGet to fetch all the DLLs -- thus saving you from versioning tons of DLLs.
Hence: is there a command in NuGet to fetch and configure all dependencies mentioned in packages.config?
Again, the case for this is that I only checked packages.config into source control, not the actual DLLs, and I need to re-fetch everything. (Preferably without fetching packages one by one by name).
This has been covered recently in blog posts:
Inbuilt functionality for this is coming in a future version of NuGet: http://feeds.haacked.com/~r/haacked/~3/x8g_kFzD4eA/feedback-request-for-using-nuget-without-committing-packages.aspx
(Linked from above) How to do this today using command line NuGet.exe (available from the NuGet pages on CodePlex): http://blog.davidebbo.com/2011/03/using-nuget-without-committing-packages.html
EDIT: Now also covered on NuGet's Documentation Pages