How to NuGet install in .nuget folder when compiling locally - c#

I have two .Net projects:
One project is is a .Net standard project containing some DTOs; call it the "core library". This is intended to be published as a NuGet package
The other is a .Net framework project that includes the NuGet package of the core library. Call it "the app"
Using TFS we are able to compile the core library, publish the resulting NuGet library and then launch the app's build which restores the NuGet reference to the core library. Everything works as expected.
The problem is that when developing the core library + the app we have frequent compiles of the core and cannot wait for the entire core library build to finish in order to update the app's local reference. Moreover we must push complete commits of the core library (so we cannot push one DTO at the time before testing them in the app).
So I was wondering if exists a way in Visual Studio and Nuget to publish/install the core's Nuget library in the local user's .nuget folder in order to let it be visible automatically to the app's project on the next build.
Can you help me with this?

Starting from the answer of Lance Li-MSFT I made some changes for my needs. In fact, locally I do not have nuget.exe installed but only the .Net Core runtime, so I'm using the dotnet pack command instead of nuget.exe pack and dotnet nuget push instead of nuget.exe push. Moreover before pushing locally the updated NuGet package I delete the old package with the same version, else dotnet nuget push will not overwrite the package.
I accept Lance Li-MSFT's answer as it was the starting point for my solution and works for who have nuget.exe locally.
My solution is below
corelib.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<Target Name="PublishNuGetLocally" AfterTargets="Build">
<Exec Command="dotnet pack $(ProjectPath)"/>
<Exec Command="dotnet nuget delete --source $(UserProfile)\.nuget\packages $(PackageId) $(PackageVersion) --non-interactive" ContinueOnError="WarnAndContinue"/>
<Exec Command="dotnet nuget push --source $(UserProfile)\.nuget\packages $(ProjectDir)bin\$(ConfigurationName)\$(PackageId).$(PackageVersion).nupkg" />
</Target>
[...]
</Project>
As a side note, I did not have to configure the package source in Visual Studio because the global Nuget cache (at the path %UserProfile%\.nuget\packages) is automatically used as the first place where to search for the NuGet packages.

So I was wondering if exists a way in Visual Studio and Nuget to
publish/install the core's Nuget library in the local user's .nuget
folder in order to let it be visible.
Before publishing nuget package(nuget push) to one location locally, we should add the path as package source. So we need to set the path of local packages as package source firstly. The content in nuget.config file is corresponding to the Package Source UI in VS, so you have two ways to do it.
1.In VS,go Tools=>nuget package manager=>package manager settings=>package source, click the green button to define new package source.
2.Or we can find the nuget.config file for current user, see this document. The UI operation in #1 actually help define the source in the nuget.config file in C:\Users\xxx\AppData\Roaming\NuGet, see:
So we can directly edit this file to set our new package source, after that save the file and restart VS, we can see new defined source in UI.
My problem is to automatize the nuget push command to the local feed,
that in my case should be %userprofile%.nuget\packages. I cannot ask
any person in the company to manually copy the core package to the
local feed in order to see the changes in the linked app
After adding the local feed to package source, then you can use nuget push command to publish packages to the feed.
You can define a custom target similar to this in your core library project file(xx.csproj) to automatically pack and push the package automatically:
<Target Name="CustomTarget" AfterTargets="build">
<Exec Command="nuget.exe pack xx.csproj"/>
<Exec Command="nuget.exe push -source xxx path\xxx.nupkg"/>
</Target>
And you can also add Conditions to this target,<Target Name="CustomTarget" AfterTargets="build" Condition="$(Configuration)=='Debug'">. You can control in which configuration VS should run this target to pack and push for you.
In addition:
For .net core library projects, VS have a option to create. the nuget package. You can right-click the project in VS and select Pack button.So you can also define a .bat file for this project to do the nuget push. The process is build the project=>use pack option to easily get nuget package=>run the .bat to automatically push.
Hope it helps.

Related

Azure DevOps "NuGet pack" task ignores/overwrites package metadata

I have setup a simple CI pipeline in Azure DevOps for building a .NET5 NuGet package, which looks like this
The pipeline is able to successfully pack and release the project as intended, but when I go to inspect the NuGet package, I find that all of the package metadata is missing (except for the version, which is correct, and the author(s), which is incorrectly showing the name of the ADO build agent as the author). I currently have all of the package metadata located in the .csproj file.
A screenshot showing the incorrect metadata, which is also what is shown when I look at the .nuspec in the NuGet package that is generated by the pipeline. Of course, when I pack the project on my local machine, all of the metadata generates the way it should.
I've seen one other post similar to this where the author switched the pipeline to use dotnet tasks instead of MSBuild tasks. Unfortunately, this is not an option for me, as this project has COM references that are not supported by the dotnet CLI, so MSBuild is my only option.
Does anyone know why the 'NuGet pack' task in my pipeline is not using the metadata in my .csproj file?
The solution to this problem ended up being somewhat simple. The 'NuGet pack' task uses the nuget.exe CLI, which ignores metadata defined in the .csproj file. You have to create a .nuspec file, put all of your metadata in it, and add that file to the same directory that the .csproj file resides. As soon as I did this, my NuGet package was generated with the correct metadata.
Does anyone know why the 'NuGet pack' task in my pipeline is not using the metadata in my .csproj file?
According to the document Create a NuGet package using MSBuild:
The command that creates a package, msbuild -t:pack, is functionally
equivalent to dotnet pack.
Or you could add below argument in the .csproj file, which will create the package when you build the project with VS build task:
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

How to push to or query local my local .NET nuget repository

I have a C# project that makes a lib. I build it just fine with dotnet build. I'd love to publish the dll to ~/.nuget/packages (I am on a Mac, using Rider). Is there a nuget command to query the local repository?
In terms of publishing, I have <GeneratePackageOnBuild>true</GeneratePackageOnBuild> added to the csproj file of the lib. Also <IsPackable>true</IsPackable>, yet nothing is put into ~/.nuget/packages if I do dotnet pack.
dotnet build
dotnet pack
nuget add path/to/<yourProjeName>.nupkg -source ~/.nuget/packages
For Mac, brew install nuget is how you add a version of Nuget to your system. At least one that is different to the nuget built into the dotnet command that has a different syntax.
Then use ls, find, ag an wotnot for ~/.nuget file location
To publish NuGet package to your local repository you can either add the following property.
<PackageOutputPath>PATH_TO_YOUR_LOCAL_REPO</PackageOutputPath>
NOTE: Don't add the property to a csproj file, better adding it to Directory.Build.props and have it in .gitignore so you don't accidentally apply these changes to your CI build if there's any.
another way of doing it is by using dotnet cli pack via o option
dotnet pack -o PATH_TO_YOUR_LOCAL_REPO

How do I update UWP projects' nuget packages via the CLI?

All .NET framework projects that use Nuget have a packages.config per project. When I run something like:
nuget update MySolution.sln -Id PackageName -Version 1.2.3
It will update all projects in my solution that use this package to the specified version (1.2.3 in this case)
However, I'm finding that this does NOT work for UWP projects. UWP does not use packages.config and instead put the package references directly into the csproj file. As a result, this is literally what nuget update says when I run it:
Found 2 projects with a packages.config file. (A.csproj, B.csproj)
where A and B are my .NET Framework projects that still have a packages.config file. But this list doesn't include my new UWP projects.
Is there another command for nuget update that will work with UWP projects?
How do I update UWP projects' nuget packages via the CLI?
This is a known issue for the packagereference. At the moment, NuGet CLI does not support automatic package updates to the the new .NET Core .csproj format, you can refer to the below GitHub issue for details:
support for updating references into csproj from commandline(s)
Besides, as test, the workaround using following command line does not work with UWP project
dotnet add package <PackageName> --version <version>
Indeed, currently it is very inconvenient to manage packages outside of Visual Studio for UWP with packagereference.
Hope this helps.

.nuget folder why solutions have it?

at work we do not use nuget and even though in my personal projects i use it ,i dont understand why many solutions I download all have it,typically with 3 files
Nuget.config,exe and target.
Can somebody explain why people add this folder to their solutions?
thanks
That folder was a key player in NuGet package restore in the good old days (NuGet.targets is the proof). But since the new restore mechanism is in place, only the NuGet.exe is useful.
You might read more from NuGet.org,
https://docs.nuget.org/consume/package-restore/migrating-to-automatic-package-restore
Update:
The linked article was updated and moved to Microsoft
Docs.
MSBuild 15 also adds NuGet package restore support if you read the above carefully.
As of nuget 2.7+, this folder is no longer needed and can be safely deleted. Futhermore, if you use the Visual Studio command line prompt, you should be able to access nuget.exe from there, as well as, within Visual Studio from the Package Manager.
To enable automatic package restore in projects that used nuget 2.6 or before, you might need to manually delete the following from the bottom of your *.csproj files:
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<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'))" />
<Error Condition="!Exists('..\..\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\MSBuildTasks.1.5.0.214\build\MSBuildTasks.targets'))" />
</Target>
I'd like to add something to Lex Li's answer. Another important file in the .nuget folder is the nuget.config file, especially if you are using nuget packages from other feeds other than nuget.org
Let's suppose that you have configured another package source as follows:
When you are adding or restoring packages on your local machine everything will work fine because nuget knows where to get the packages. When you're compiling your solution as part of a build on a Continuous Integration (CI) server (such as Visual Studio Team Services) the restore/install of the nuget packages could fail because the CI server doesn't know where to get the packages from!
So if you add the package sources to .nuget/nuget.config:
You can then use the config file to restore/install the nuget packages - this is how I do it in Visual Studio Team Services:

How to add a nuget package to the package.config the proper way?

For my C# project I am maintaining a packages.config which includes all the dependencies my project requires. Over the time I have been copy-pasting the entries manually using a regular text editor, checking in the version number I found on the NuGet website and so on. To restore the package upon a checkout, I use nuget -o nuget-packages install packages.config which worked good so far (I am using Xamarin Studio on non-windows systems, so no VS available).
I was just realizing that messing with the packages.config in a text editor couldn't be the intended way. I know from npm and bower that a npm install --save-dev <pkg-xy> will to the job and write the package version back to the config. Is there an equivalent of this in NuGet.exe?
From the command line this not supported. You will have to edit the packages.config file manually, or write a utility to do this work for you, or extend NuGet.exe with this feature.
There is no equivalent in NuGet to NPM's npm install -save
Currently the only way to have the packages.config file automatically updated when you want to install a new NuGet package to your project is to use an IDE, such as Visual Studio or Xamarin Studio, and actually install the package. Using NuGet.exe from the command line does not have an option to add/remove entries in to/from the packages.config file when installing a new package.
NuGet.exe does have an update command which will update the package to the latest version. Whilst this would update your packages.config file it also updates your project file by adding any assembly references that the NuGet package needs.
You really shouldn't be editing packages.config. Package Restore doesn't do what you think it does. It simply downloads any missing packages that are listed in packages.config.
You might think this is what you want, but Package Restore does NOT add references to your project. It also doesn't do any of the other things the package creator had intended like running an install.ps1 script.
When installing a package, NuGet handles all of this, so your project files have added references, content, etc. This and the packages.config file is what you would commit to source control. You can leave out the actual packages folder, so you don't have to commit large binary files.
When you open the solution and build, NuGet will see that the packages are missing and will download them as if you had checked them in. The actual "install" was already done (and committed). That is all that Package Restore does: no more, no less.
If you are using Xamarin Studio, you can install NuGet by following the instructions here:
https://github.com/mrward/monodevelop-nuget-addin

Categories