Azure DevOps "NuGet pack" task ignores/overwrites package metadata - c#

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>

Related

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 to NuGet install in .nuget folder when compiling locally

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.

new .net core visual studio 2017 project nuget restore in CI build definition

So currently, I am working on a .net core project in Visual Studio 2017. And I am also need to setup CI (Continuous Integration) in VSTS.
Here is my nuget restore step in my build definition
But my build is failing because it couldn't restore any packages. Here is the log of its. It said that "None of the projects in this solution specify any packages". I know that in VS2017 they changed the way nuget packages are being handled.
Anyone has an idea or experience about this?
2017-03-22T20:25:11.9517911Z MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin'.
2017-03-22T20:25:11.9674167Z Nothing to do. None of the projects in this solution specify any packages for NuGet to restore.
2017-03-22T20:25:11.9830425Z ##[section]Finishing: NuGet restore **/*.sln
I don't want to use dotnet restore because Microsoft said that
.NET Core's dotnet restore command doesn't currently support encrypted
credentials. To use VSTS NuGet feeds with dotnet restore, you'll need
to specify a Personal Access Token in plain text.
so I don't want to store my Personal Access Token.
https://www.visualstudio.com/en-us/docs/package/nuget/auth#net-core
You need to use NuGet 4.0.
Download it form the official NuGet site. https://dist.nuget.org/index.html
Put it in a folder on the machine where you have the build agent.
In the Advanced settings of the NuGet restore step set the NuGet version to Custom.
In the Path to NuGet.exe specify the path where you have put the NuGet.exe file. This is the path on the machine where the build agent is running. I tried with a relative path but was not able to get it working so in the end I have put an absolute path. This might be a problem for you if you have multiple agents with different paths so you might need to figure out how to correctly specify the relative path.
The Nuget restore task just includes Nuget.exe 3.3 and 3.5, so there isn’t the option of 4.0. You can check the files in [build agent folder]\tasks\NuGetInstaller\[version]\ node_modules\nuget-task-common\NuGet folder.
You can build a custom build/release task to include nuget.exe 4.0 and use this task instead. More information, you can refer to Add a build task.
On the other hand, you can add Nuget.exe to the source control, then map it to the build agent (Repository tab of build definition) and specify the path with built-in variable (e.g. $(build.sourcesdirectory))

Updating nuget package with and without prerelease flag in a C# project

We are using git as source control and we follow the git flow workflow.
We are using Visual Studio 2013
We are using Teamcity v8.1
We have 2 C# solutions. Solution A and solution B. Solution B uses a nuget package that solution A creates.
We are using teamcity as a build server. We have 2 build configurations that creates the Project A nuget package. One build configuration creates a prerelease version of the nuget package, the other one creates the stable version of the nuget package.
The build configuration for creating the prerelease nuget listens on the develop branch. The build configuration for the stable version listens on the master/release/hotfix branches
When we work in the develop branch we use the prerelease version of the nuget package.
But when we create a release branch we want to use the stable version of the nuget package.
What we have tried so far is:
In project B csproj file, we have added an element in the BeforeBuild target that executes nuget.exe to update the prerelease version of the nuget package. That works well, since every time we build project B we will get the latest prerelease version of the nuget package.
But when we are in the release/master/hotfix branch we don't want the prerelease version, we want the stable one.
I've created a powershell script that is executed from project B csproj file in the BeforeBuild target
In the powershell script I can find which git branch we are in, but I haven't found a way to update the nuget package to the latest stable version using nuget.exe. If I could use the nuget cmdlets in the powershell script I could run the update-package with the version flag, but that is not supportered when using nuget.exe
Do you do something similar and how have you solved this?
I while back I also tried to automate updating and installing packages with Powershell. As far as I know there is no way to use the Visual Studio cmdlets outside Visual Studio.
You could do everything yourself. Update packages.config, run nuget update, update csproj file.
It is possible your package has an install.ps1 file. This also uses the Visual Studio cmdlets. For example, the install.ps1 can add a config file to the Visual Studio project and set Copy to Output Directory to Copy if newer.
This means you would have to add these changes to the csproj as well.

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