NuGet Package being marked as prerelease - nuget

I have built a NuGet Package and uploaded it to a locally hosted Sonatype Nexus repository.
I have given it the version 0.1.1+251019-020007-e3baff. My understanding of sem-ver 2.0 is this should be treated as a stable/release version (because the data after the + should only be treated as metadata), but nuget seems to be getting confused and showing it only if I include prerelease versions in the search.
For example in the cli if I run Find-package <my-package-name> I get no results. But if I run Find-Package -prerelease <my-package-name> I get
Id Versions Description
-- -------- -----------
<my-package> {0.1.1} <description>
Likewise if I use the GUI in Visual Studio I have to check the "include prerelease" option, but then the version that is available is marked as "latest stable"...
In Nexus there is a flag "is_prerelease" that is being set to true by something, not sure what, Is that flag being incorrectly set and then being used in the search?
Is there something else I am doing wrong? Is my understanding of the + character in sem-ver 2.0 not correct?
I am using NuGet version 4.9.3, and nexus is version 3.19.0-01

NuGet's logic is available as packages, the versioning logic in the NuGet.Versioning package. Using this little program:
static void Main(string[] args)
{
var version = NuGetVersion.Parse("0.1.1+251019-020007-e3baff");
Console.WriteLine($"Version is prerelease: {version.IsPrerelease}");
}
I get the output
Version is prerelease: False
I tried many versions of the NuGet.Versioning package, from the latest 5.3.1, to 4.9.4, 4.3.0, 3.5.0, 3.2.0 and even the oldest release version of the package, 1.0.1. All of them say that your version is not prerelease.
Therefore, it's not NuGet that thinks your package is prerelease. Given that - is the separator for prerelease labels, my guess is that Nexus is incorrectly doing a simple check similar to version.Contains('-') to determine if it's pre-release. This is a shame, as semver.org has two regex expressions on their website which do not have this behaviour (example, I have no idea how long this link will be valid). If your Nexus installation isn't running the latest version, I suggest trying to update if you can. If it's still a problem, you could try contacting the software vendor to report a bug.
As a work around, you could try avoid using the - character in the build metadata as long as you keep using Nexus. SemVer2 is quite restricted in the characters it lets you use, so I suggest using . instead (0.1.1+251019.020007.e3baff).

Related

how to determine the current and future electron version(s) of vscode at extention build time

I'm collaborating on a vscode extension that uses a native module (#serialport) which needs to be included / pre-compiled for each platform/electron-version combination.
if we only include the current versions, it frequently breaks when vscode updates the electron version. some platforms can nativly re-compile , other can only after a (very) lengthy install of rather-complex toolchains that IMO should not be required for end-users.
So we want to include the relevant prebuilds,
and for that we need to look ahead in time ...
I'm looking for a reliable method to determine the electron versions used by vscode
- current version
- and the future (insider) version
- in addition it may be good to include a prior version to allow for backward compatibility
I have found that master/.yarnrc has the current ( or next imminent) version
today it is 4.2.7
vscode current release uses 4.2.5
prior versions can be read from the version history
master/.yarnrc
but what about the future / insider version ?
what is a good method/location to determine that programmatically ?, i.e. Which branch has the insiders version ?
Probable answer based on below hints and some more probing :
next version is in master ..microsoft/vscode/blob/.yarnrc
version 1.36.1 is in ..microsoft/vscode/blob/1.36.1/.yarnrc
version x.y.z is in ..microsoft/vscode/blob/x.y.z/.yarnrc
which only leaves the in-between versions/tags to be discovered.
intended approach:
during the build collect the relevant electron versions, ie "3.1.8","4.2.5","6.0.0-beta.0"
determine the ABI used by these versions using node-abi
var getAbi = require('node-abi').getAbi;getAbi('$version','electron')
use prebuild-install to download the relevant native prebuilds bindings, and include these as part of the extension
.\node_modules\.bin\prebuild-install.cmd --runtime electron --target $version --arch $arch --platform $platform --tag-prefix #serialport/bindings#
copy the bindings files for all ABI-arch-platform combinations to a folder, and inclide that in the vscode extension package
at load time , determine the ABI version of the running instance of vscode/electron, and dynamically load the module from the ABI/platform folder
alternative / additional approach:
- as a last ditch effort the code could try a just-in-time download of the pre-build binding file for the current platform, but this might run into permissions/malware scanner problems as that is essentially downloading downloading executable code from an external github repro.
current script code to download the bindings:
https://github.com/Josverl/pymakr-vsc/blob/fix/SerialMultiPlatform/scripts/mp-download.ps1
okay, so reverse logic then indicates that:
next version is in master https://raw.githubusercontent.com/microsoft/vscode/master/.yarnrc
version 1.36.1 is in https://raw.githubusercontent.com/microsoft/vscode/1.36.1/.yarnrc
version x.y.z is in https://raw.githubusercontent.com/microsoft/vscode/x.y.z/.yarnrc
which only leaves the in-between versions/tags to be discovered.

Nuget packages versioning/update strategy

maybe someone has a good idea for the following scenario:
I have
prerelease dev packages, like that: packagename.1.2.0.1000-dev.nupkg
and
release packages, like packagename.1.2.0.1.nupkg
My idea was: starting at a higher number range for the dev packages would always allow getting the dev packages for developers if they enable the Pre-Release option at the nuget update step. This works fine.
Then later on I would like to update the project to the latest release version. But it seems there is no option to update to the latest release version that has a lower version number than the dev/pre-release package? Also the -Safe option doesn't seem to work here.
I can't keep the build numbers in sync also since these are different builds. If I have it the other way around, so higher build numbers for the release versions, it would never update to the latest dev packages if I do a normal nuget update, even including the pre-release packages...
Any idea here?
Thanks a lot!
Any package that is publicly available is a "release package" in technical/English terms. But the software industry has bastardized the language. So lets talk about stable (no prererelease tag) and unstable releases (prerelease tag).
The publisher history should be something like this:
1.0.0 // First **stable release**
1.0.1-alpha // First **unstable release** Candidate bug fix.
1.0.1-beta // 1.0.1-alpha with a tweak to the code.
1.0.1 // Second **stable release**
If the publisher follows that pattern, then end-user clients can safely pull stable release bug fixes while developers can also pull unstable prereleases at their discretion.
You can also have something like:
1.0.0 // First **stable release**
1.0.1-a.dev.1 // Next CI build after 1.0.0
1.0.1-a.dev.2 // Etc...
1.0.1-alpha // Relabeled 1.0.1-a.dev.2.
1.0.1-beta // Relabeled 1.0.1-alpha, wider audience than -alpha.
1.0.1 // Second **stable release**
It's a good practice to have separate feeds for internal dev/test, public prerelease and public stable releases.

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

NuSpec version attribute vs assembly version

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