Azure Pipelines populate NuGet package fields - nuget

I have a Class Library project using .net Framework 4.6.1 and I am building a NuGet package using Azure Pipelines. I have got most of the fields in the NuGet package properties populated however I'm struggling with a few.
I'm using an extension to read the AssemblyVersion from AssemblyInfo.cs and use this for the versioning.
I can also see that it extracts the below fields form AssemblyInfo.cs
AssemblyInfo.cs Field
NuGet Package Property
AssemblyTitle
Title
AssemblyDescription
Description
AssemblyCompany
Authors
AssemblyProduct
ID
AssemblyCopyright
Copyright
The NuGet fields I'm trying to populate are Release Notes, Summary & Owners but I'm not sure where to start. I've look at what other fields I can use in AssemblyInfo and none of them sound like they would relate to the mentioned fields. I've also looked in the NuGet Pack task in Azure Pipelines but theres no mention of these fields either

When we pack the nuget package with .csproj file, nuget will get the package info from the AssemblyInfo.cs file in the project. (e.g: AssemblyVersion, AssemblyDescription,AssemblyCopyright etc).
We can see this information in the package overview page after it's published to a feed.
I'm trying to populate are Release Notes, Summary & Owners
Here is the direction for your reference. We can try to add this as a description for the NuGet package, we could add the description for assembly: AssemblyDescription in the AssemblyInfo.cs:
[assembly: AssemblyDescription("Release Notes, Summary & Owners here")]
However, we need to find a way to generate the required information (Release Notes, Summary, ect) and write it to the AssemblyInfo.cs file.
Another way is using the .nuspec file. We need to create this file on local machine with the command line nuget spec "..\*.csproj", then modify the <description>$description$</description> in the .nuspec, upload this file to the repos. Please see Create the .nuspec file for details.
After that, we can expand the "Advanced" option of the NuGet Pack task, then in the "Additional build properties" specify the value you want in this way:
Description="ReleaseNotesHere"
With this way, the specified value will replace description.
Specifies a list of token=value pairs, separated by semicolons, where
each occurrence of $token$ in the .nuspec file will be replaced with
the given value. Values can be strings in quotation marks.

Related

set up build and release for two related packages in VSTS

Dears
Please help me with VSTS build configuration for linked packages
I have two projects in the solution, like Interfaces and Dto. Interfaces contains several interface definitions, Dto project implements interfaces and has reference to Interfaces. Each project has dedicated nuspec file and is available as dedicated package in the vsts package feed.
To achive this I created nuspec files that contains package dependencies according to project references defined. So Dto package depends from Interfaces like below:
<package >
<metadata>
<id>Dto</id>
<dependencies>
<dependency id="Interfaces" version="0.4.0" />
</dependencies>
Those projects are hosted in the same VSTS git source code repository (but different folders)
Right now I have simple build definition that is triggered by changes in master branch.
It builds solution, than packs and pushes all nuspec files from the solution folder.
How can I configure build definitions for two packages to build Interfaces project only if Interfaces folder content was changed? But to build Dto package if Interfaces or Dto folder content was changed?
I've thought that can create two build definition that triggers by different Path filters. However the problem is that i need to set correct dependency version reference from Dto nuspec file to Interfaces package.
To set package version I use global build definition variable $versionFromFile that contains minor and major part of version number, like 0.4 and vsts revision for third part of package version. It is parameterized in the build number format like:
$(versionFromFile).$(Rev:rr)
each package build automatically increment revision number like 0.4.1, 0.4.2. When I need to change major package version number I update build definition variable value and revision is starting to count from zero. To set package version I configured nuget pack task "Automatic package versioning" parameter to "use the build number" value.
So in case for two build definition I need to reference from Dto package to Interfaces package last version somehow. Unfortunately I have no idea how to reference from Dto package build definition to the latest Interfaces build definition version number. The only one idea that I found is to save Interfaces build version number to a file. Then read it from Dto build definition to the new variable and use it. However it looks a little bit ugly. Is there a better way to reference from one build definition to another build definition $(BUILD.BUILDNUMBER) value?
Thank you
The simple way is calling nuget update command through Command line task before build task, then pack the project through Nuget task with Include referenced projects option checked.
I've implemented solution that was suggested by #starianchen
To achieve this I had to
remove reference from dto project to interfaces and added interfaces as a package instead
create two build definitions, for interfaces and dto folders of the solution using Path filter on Triggers page
create interfaces.sln file because vsts fails to build interfaces.csproj. It needs sln file or output paths to be specified
change nuget pack to nuget custom command and write parameters manually for both interfaces and dto builds.
pack Interfaces\Interfaces.nuspec -version $(BUILD.BUILDNUMBER)
-properties "releaseNotes=$(releaseNotes)" -Verbosity Detailed -OutputDirectory $(build.artifactstagingdirectory)
and
pack Dro\Dto.csproj -version $(BUILD.BUILDNUMBER) -properties
"Configuration=Release;releaseNotes=$(releaseNotes)" -Verbosity
Detailed -OutputDirectory $(build.artifactstagingdirectory)
-IncludeReferencedProjects
Please note that i've used .csproj file that has corresponding .nuspec for Dto packing command.
- modify Dto.nuspec by removing Interfaces from dependency section and Dto.dll from Files (those elements are added by IncludeReferencedProjects option). However there are dto.xml and related assemblies
This allows me to update Interfaces package only when it changes. Dto project when packed takes dependency for the Interfaces package reference that was used when Dto project was built.
I would suggest using the BuildChain extension from the Marketplace. This extension allows you to easily chain builds and pass parameters from one build to the next.

Should I publish the nuspec file in a repository?

When creating an open source library on GitHub or another public website, should I publish the .nuspec file that describes the corresponding NuGet package?
I've done this a couple of times (since no API key or other sensitive information is included in the .nuspec file) in order to allow myself to easily publish subsequent versions without keeping private file, and to allow other people to fork it and add their own descriptions easily. However, the developers of many top packages don't seem to publish .nuspec files in their repositories (sometimes they publish NuGet.exe along with a .targets file, and so on), so I'm thinking that maybe I'm doing something wrong.
The package authoring should be considered part of the source code since it is a required asset to build the fully usable output.
Some projects use special msbuild-based tooling to create the nuspec file during the build so it seems like there is none in the repository. the new "SDK-based" projects (e.g. .NET Standard libraries) have integrated nuget tooling to be able to create a nupkg file from the csproj without the need to create a nuspec file. This tooling is also being adopted by some popular packages (e.g. Newtonsoft.Json).

Configuring Nuget pack for prerelease on VSTS

Note
If there is an easier way to create prerelease packages please let me know!
I am using Visual Studio Team Services and have setup a nuget pack and publish step.
I have a build variable called $(BuildSuffix) that allows me to tag build-specific variables onto the end of the build number format like so
$(Build.DefinitionName)_1.0.$(date:yyyy)$(date:MM)$(date:dd)$(rev:.r)$(BuildSuffix)
The idea then is that I can set $(BuildSuffix) to -beta so that my final build version might be Build_1.0.20170119.2-beta.
According to the nuget documentation here, appending -beta to a build number will create a prerelease package. The build in VSTS comes out with -beta appended but the nuget pack stage never seems to contain it. It always comes out as the exact version number but without the -beta tag.
My nuspec files look like this:
<package >
<metadata>
<id>MyCompany.Data</id>
<version>$version$</version>
My NuGet package step looks like this:
After some research and bashing my head against a brick wall I figured out how. You have to:
Configure a local Build Agent
Install Nuget CLI
On Nuget Packager Task set Path To NuGet.exe to the NuGet CLI
Set NuGet Arguments on the same screen to -suffix beta
With new NuGet task(version 2) you can specify Additional build properties and there you can pass your custom build number directly instead of using -suffix NuGet argument. Additional build properties are substituting $token$ with supplied value in nuspec and you are free to change whatever you want in there.
I also see it on your screenshot, but I never tried to use it like this with older NuGet tasks as those are deprecated now.
Maybe it will be helpful to try import NuGet Packaging Task Group definition I am using on my private projects. Check it out Here.

Keeping packages.config and nuspec in sync

I've been resorting to manually modifying my .nuspec files every time I update packages. Is there an automatic way of doing this? I'd rather not have to create an additional build step that compares both files and syncs them.
I believe MyGet does this OOB, but unfortunately I can't use MyGet for this specific package.
(FWIW, I'm using VS2015 and Xamarin Studio)
Just call the nuget pack against the csproj instead of nuspec, for example:
nuget pack X.csproj
In addition, you'll have to remove the dependencies from the nuspec, otherwise nuget will get it from there instead of from packages.config.
BTW, check the created nupkg. It may have unwanted files added to it, like, for instance, txt files, if you happen to have any in your project.
If that's the case, you'll have to invoke nuget pack with the -Exclude parameter:
nuget pack X.csproj -Exclude **.txt
I ended up creating a quick C# script (LINQPad rules) that syncs .config and .nuspec using XDocument, NuGet.Core and LINQ. If anyone's interested, I'll post it as a gist.

Multiple .nuspec files inside a project's directory?

Is it possible to have multiple nuspec files inside a single directory for the same project and still be able to merge the project and the specified nuspec file.
I wonder if something like this is possible:
nuget pack MyProject.csproj MyProject-x86.nuspec -prop Configuration=Release;Platform="x86"
nuget pack MyProject.csproj MyProject-AnyCpu.nuspec prop Configuration=Release
I need to be able to publish my project with more than one build configuration and thus I need to create different packages.
My very, very last resort will be to copy the csproj file at build time, rename it to "MyProject-x86.csproj" for example, run the nuget pack and then delete it. I would hate to do that and I am looking for alternatives.
Thanks.
When calling NuGet pack, you cannot pass more than a single csproj or nuspec file. Note the pipe in the command line help (to indicate one or the other):
usage: NuGet pack <nuspec | project> [options]
You could create another csproj stripped down to just an import element to the main csproj (i.e. the one you work from in Visual Studio), override the values of property group items as needed, and/or have matching .nuspec files.