I'm building some NuGet packages that I want to be publicly visible and I wanted things like a project website URL, license, author, etc. added to the metadata without modifying the csproj file.

I'm using Azure DevOps Pipelines (yaml) for my build and deployment processes. A good portion of the metadata will be populated at build time, this would include things like the branch that was built, the commit hash and a number of other fields.

Process background

You can specify build arguments using a ; separated list of key value pairs like this -p:property1="value";property2="value". You can also specify each property individual by doing this -p:property1="value" -p:property2="value". Both ways work fine when running the dotnet pack command.

Azure DevOps

In Azure DevOps Pipelines it expects the ; separated format, the additional arguments property would look like this:

Authors="Vecc Solutions";Product="Vecc.Prometheus";PackageLicenseExpression="MIT";MaintainerEmail="edward@frakkingsweet.com";RepositoryType=git;PackageProjectUrl="$(Build.Repository.Uri)";RepositoryUrl="$(Build.Repository.Uri)";RepositoryCommit=$(Build.SourceVersion);RepositoryBranch="$(Build.SourceBranchName)

My entire yaml step looks like this:

- task: DotNetCoreCLI@2
  inputs:
    command: 'pack'
    packagesToPack: 'src/Vecc.Prometheus/Vecc.Prometheus.csproj'
    configuration: 'Release'
    nobuild: true
    versioningScheme: 'byBuildNumber'
    buildProperties: 'Authors="Vecc Solutions";Product="Vecc.Prometheus";PackageLicenseExpression="MIT";MaintainerEmail="edward@frakkingsweet.com";RepositoryType=git;PackageProjectUrl="$(Build.Repository.Uri)";RepositoryUrl="$(Build.Repository.Uri)";RepositoryCommit=$(Build.SourceVersion);RepositoryBranch="$(Build.SourceBranchName)'

There's a number of other arguments that you can specify to control the different metadata properties of the NuGet package. You can find them and additional details here: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#pack-target

You can get a list of the supported built-in variables in Azure DevOps here: https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml

Conclusion

Armed with this new information I can now build complete and nice NuGet packages containing the metadata to better support the users all without modifying the csproj file. This will make the developers happy because it's one less thing to deal with.

With Azure Pipelines supporting shared variables between projects it may be beneficial to try and put the build properties into a variable so we don't have to copy the values between each of the pipelines. But that's for another day.