How to include pre-release packages with MSBuild restore target - msbuild

This question is specific to MSBuild 15.1+ (Visual Studio 2017) and to PackageReference, which is the new way Nuget is fully integrated within MSBuild.
In my continuous integration script, I've got something like:
MSBuild.exe /t:Restore MySolution.sln /p:RestoreConfigFile=NuGet.config
One of the csproj file contains:
<PackageReference Include="MyPackageA">
<Version>1.2.*</Version>
</PackageReference>
MyPackageA is an internal package and I would like nuget to resolve the reference to the latest version available, including pre-release version.
Let's take 2 examples:
Example #1
Packages available are:
MyPackageA version 1.2.7-dev1
MyPackageA version 1.2.7-dev2
MyPackageA version 1.2.7-dev3
MyPackageA version 1.2.8
I would like nuget to resolve the dependency and pick up MyPackageA version 1.2.8.
Example #2
Packages available are:
MyPackageA version 1.2.7-dev1
MyPackageA version 1.2.7-dev2
MyPackageA version 1.2.7-dev3
MyPackageA version 1.2.8
MyPackageA version 1.2.9-dev1
MyPackageA version 1.2.9-dev2
I would like nuget to resolve the dependency and pick up MyPackageA version 1.2.9-dev2.
However, it would only resolve to version 1.2.8 (the stable release) in both examples.
Is there a way to tell MSBuild or Nuget to include pre-release packages?

At the moment, prerelease versions cannot be used together with floating versions.
You can use
<PackageReference Include="mypk" Version="1.0.*" />
OR
<PackageReference Include="mypk" Version="1.0.1-*" />
But not 1.0.*-*.
See this GitHub issue where this feature request is tracked.

How to include pre-release packages with MSBuild restore target
AFAIK, there is no such option -IncludePrerelease for nuget restore, you can check the Options for restore command. And MSBuild restore also does not have this option, MSBuild restore target.
This option is used for nuget Install, Update.
As a test, I added the option -IncludePrerelease or PreRelease to the command line nuget restore, then I got the error message:
Unknown option: '-IncludePrerelease'
Besides, when we restore nuget package with nuget.exe restoe or MSBuild.exe /t:Restore, nuget will downloads and installs any packages missing from the packages folder based on the package list in the packages.config and PackageReference, the version information is indicated in the those file, like:
<package id="ExamplePackage" version="6.1.0" targetFramework="net45"/>
and
<PackageReference Include="ExamplePackage" Version="6.1" />
NuGet will download the corresponding version of the package, so we do not need give the option -IncludePrerelease.
Update:
I should have mentioned my reference includes a wildcard and I would
like that wildcard to resolve to the latest version, including a
pre-release version if it's the latest.
Indeed, this is a issue about restore pre-release packages for PackageReference:
https://github.com/NuGet/Home/issues/912
You can track this thread to get the latest status for this issue, and NuGet team already set this issue as pri 0, and try to resolve this issue ASAP.
Hope this helps.

The NuGet,version >5.6, floating version syntax allows for some pretty powerful version ranges, but it is likely that your scenario will be mostly satisfied by the following 3 floating versions:
<!-- Float everything! Latest version available including prerelease-->
<PackageReference Include="mypk" Version="*-*" />
<!-- Prefer latest 1.X version, include prerelease and stable -->
<PackageReference Include="mypk" Version="1.*-*" />
<!-- Prefer latest 1.0.X version, include prerelease and stable -->
<PackageReference Include="mypk" Version="1.0.*-*" />
Ref

Related

Package Restore Failed Microsoft.WindowsAzure.Storage

I switched my 4.8 project to SDK format and am trying to restore the Nuget packages I need.
I can see that it is available in Nuget
However when I try to install it I get
NU1101 Unable to find package Microsoft.WindowsAzure.Storage
If I have the following in my project
<PackageReference Include="Microsoft.WindowsAzure.Storage" Version="9.3.3.0" />
Then when I build I get an error.
No packages exist with this id in source(s) nuget.org
[Update]
Now I see that the package version is deprecated
However if I try installing Azure.Storage.Blobs 12.11.0 I get
Error NU1605 Detected package downgrade: Azure.Core from 1.22.0 to
1.6.0. Reference the package directly from the project to select a different version.
The following works.
<PackageReference Include="WindowsAzure.Storage" Version="9.3.3.0" />
When I right clicked the error in my source code VS2022 gave me the option of downloading from Nuget.

Is it possible to utilize OctoPack with the new PackageReference NuGet format?

We recently upgraded our assemblies to use the PackageReference format instead of the packages.config for our NuGet dependencies. One of the packages, OctoPack, stopped working after doing this. Is there any way to get OctoPack to work while still using the PackageReference format?
Yes, but you have to use Octo.exe pack (same process as for ASP.NET Core applications)
Yes. Recent Nuget versions will autogenerate imports for the MSBuild tasks in the obj/xxx.csproj.nuget.g.targets file.
If it doesn't...
When using packages.config, Nuget will add something like this to your csproj.
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\OctoPack.3.6.4\build\OctoPack.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\OctoPack.3.6.4\build\OctoPack.targets'))" />
and
<Import Project="..\packages\OctoPack.3.6.4\build\OctoPack.targets" Condition="Exists('..\packages\OctoPack.3.6.4\build\OctoPack.targets')" />
The EnsureNuGetPackageBuildImports target is probably already there, even before.
If you add this to your csproj (or keep it, if you converted from packages.config) it will sort of still work. The problem is that packages are not stored in "..\packages".
This is easily fixed by replacing e.g "..\packages\OctoPack.3.6.4" with "$(NuGetPackageRoot)\octopack\3.6.4". Of course you need the PackageReference to octopack. It will be enough to make a restore operation put the package in $(NuGetPackageRoot).
YMMV, but it works for me, both locally and in CI (TeamCity)

VS2017 msbuild / nuget pack

I am having a problem with nuget (version 4.3.0.4406) and msbuild (version 15.3.409.57025). I am using VS2017 to create class library. Using the pack capability of VS2017 i can successfully create a nuget package (that i can install in another solution). Now i want to add an install.ps1 script to the package in the tools folder that runs when the nuget is installed.
In the csproj file i am specifying multiple target frameworks:
<TargetFrameworks>net45;net452</TargetFrameworks>
I cannot figure out how to do this. I've created a nuspec file using the nuget -spec command which generates a simple nuspec file. When i use the msbuild command with the /t:pack and /p:Nuspecfile=path.to.nuspec I get the following errors:
NuGet.Build.Tasks.Pack.targets(141,5): error : Value cannot be null or an empty string.
I have nuspec files from other projects (from VS2015 solutions) that work without problem, and the structure of the one i am using now is basically the same. Can anyone let me know whether i am trying something that cannot be done?
You can pack any item by updating its metadata in the csproj file:
<ItemGroup>
<None Update="install.ps1" CopyToOutputDirectory="PreserveNewest" Pack="true" PackagePath="\tools" />
</ItemGroup>
Note that the ps1 file is only run for projects using packages.config to reference the NuGet package and you should investigate alternative ways to accomplish what you are trying to do with the script as PackageReference is now more likely to be used instead.

Referencing a NuGet Package's Tools From Another Package

I have a NuGet package (MyPkg) that contains a build target which is dependent on build tasks in another package (AnotherPkg). AnotherPkg has a tools directory with that build task DLL. Following NuGet behavior, the DLL is installed to \packages\AnotherPkg.0.1.1\tools
I am wondering if there is a proper way to reference AnotherPkg's tools path and make it version agnostic. For example, I'd like the package user to be able to upgrade AnotherPkg to 0.1.2, and not have to change anything in my package.
I have some code that kind of works to try and find AnotherPkg's directory... but it seems a little flaky and the project might not load if AnotherPkg has not yet been installed.
<ItemGroup>
<AnotherPkgDll Include="$(SolutionDir)\packages\AnotherPkg.*\tools\AnotherPkg.Tasks.dll" />
</ItemGroup>
<UsingTask AssemblyFile="#(AnotherPkgDll)" TaskName="Whatever" />
Any other tips? I'm hoping I'm missing some sort of NuGet function to get this info.
The package I'm trying to use in my package is on Github. So I modified it and submitted a pull request. :)

Missing nuget packages error while using msbuild from command line

I am working on a silverlight app. We are using nuget packages but we dont check in the packages and the packages should be restored while building. The solution compiles well in visual studio.
I am trying to add a compile task in command line using msbuild
Exec { C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe $slnFile /p:OutputPath=$outputPath /p:Configuration=Release /p:SolutionDir=$rootDir\Source\ /verbosity:minimal /nologo /m:4 } "Build Failed
Before doing this step, I'm doing a nuget restore explicitly.
Exec { C:\project\nuget.exe restore $solutionFile} "restore failed"
This step passes with a message "All packages listed in packages.config" are already installed.
But when the actual build step happens the build fails with the message
This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is \Source\.nuget\NuGet.targets.
I am doing a nuget restore explicitly and I have enabled
"Allow nuget to download missing packages" in visual studio and
"Enable nuget package restore" in solution level.
My nuget.config has "disableSourceControlIntegration" value="true"
I have seen similar issues in stackoverflow and I have tried all the above solutions that were suggested. I don't have a clue why it fails in spite of all these.
You do not need to do both the nuget.exe restore and have MSBuild use NuGet.targets to restore the NuGet packages. You should choose one or the other.
I suspect the problem in your case is that $rootDir is not defined and the SolutionDir property you are passing to MSBuild is:
\Source
In my project file I have:
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
So if SolutionDir is \Source then the solution will fail to compile with the same error message.
In mine, the csproj file somehow had this:
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
Removing it had solved the problem.