The dotnet pack doesn't work together with -p:NuspecProperties when multiple properties provided
When calling the
dotnet pack project.csproj -p:NuspecFile=project.nuspec -p:NuspecProperties="version=11.0.0;year=2021" --verbosity quiet --output c:/temp
command to pack a NuGet package providing multiple properties (version, year), only the first one is replaced in nuspec file with the provided value. Others are resolved as an empty string.
project.csproj file

project.nuspec file

nuspec file in resulted package

Is there anything I am missing or there might be a bug in passing the properties?
Thanks.
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
I can repro this on 5.0 and 6.0. @Forgind this isn't valid syntax, is it?
MSBuild would interpret the command line to mean that the property NuspecProperties should have the value version=11.0.0;year=2021, but it doesn't do any more parsing initially, so there's presumably some parsing afterwards that converts it to real nuspec properties.
Have you tried reversing the order of the parameters (year=2021;version=11.0.0)? Version is given a default value if one isn't found, whereas year isn't. That might mean it was looking for version, and year would have to be set separately. Also, I'd try splitting version=11.0.0;year=2021 into two properties initially and seeing if you can pass them separately.
When I reverse the order it's the same behavior - only the first parameter is replaced - the year in this case. SPlitting the properties this way:
dotnet pack project.csproj -p:NuspecFile=project.nuspec -p:NuspecProperties="version=11.0.0" -p:NuspecProperties="year=2021" --verbosity quiet --output c:/temp
doesn't help either. Unfortunately, the second argument value overrides the first one, so in this case, only the 'year' is replaced (Actually the pack fails because the version is empty since it is not replaced with the correct value).
So sadly nothing from the provided workarounds work.
This sounds to me like a problem with the parsing where it knows to look for the NuspecProperties property, and it uses that to generate metadata later used to replace properties in the project.nuspec file, but the parser looks for the first = and doesn't parse the second part. @nkolev92, does that sound right? I suspected something in NuspecCoreReaderBase, but I couldn't find a smoking gun.
Actually the problem is simpler than that :)
dotnet pack is really just a wrapper around dotnet msbuild /t:pack.
NuspecProperties is a property, similar like the SpecialProperty example:
If you try this project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<SpecialProperty>Set_In_Csproj</SpecialProperty>
</PropertyGroup>
<Target Name="SpecialTarget">
<Message Text="Special property: $(SpecialProperty)" Importance="High" />
</Target>
</Project>
And the output is:
C:\Users\Roki2\Code\packTest> dotnet msbuild /t:specialtarget Microsoft (R) Build Engine version 16.9.0-preview-20611-06+5abf1ff7b for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Special property: Set_In_Csproj
C:\Users\Roki2\Code\packTest> dotnet msbuild /t:specialtarget /p:SpecialProperty="value" Microsoft (R) Build Engine version 16.9.0-preview-20611-06+5abf1ff7b for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Special property: value
C:\Users\Roki2\Code\packTest> dotnet msbuild /t:specialtarget /p:SpecialProperty="value" /p:SpecialProperty="value2" Microsoft (R) Build Engine version 16.9.0-preview-20611-06+5abf1ff7b for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Special property: value2
C:\Users\Roki2\Code\packTest>
I completely misread the scenario. Let me take another look. I saw this comment https://github.com/dotnet/sdk/issues/15482#issuecomment-769773870 and complete focused on that.
Does it work if you specify the property in the project?
This can probably be transferred NuGet side if that doesn't fix it.
It looks like this approach works as you described.
The thing is I followed the documentation here: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#packing-using-a-nuspec.
Where there is this statement: NuspecProperties: a semicolon-separated list of key=value pairs. Due to the way MSBuild command-line parsing works, multiple properties must be specified as follows: -p:NuspecProperties="key1=value1;key2=value2".
And since the values of the properties are in my case dynamically populated (evaluated as part of the build pipeline), I wanted them to be provided as dotnet pack arguments.
For now, I use plain string replace to provide the values to the nuspec file as a workaround.
Hopefully, it makes sense.
We are running into exactly the same issue. This issue prevents us from using dotnet pack for packaging based on .nusepc files. It is a bit disappointing that this does not work as advertised on the posted link:
The thing is I followed the documentation here: https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#packing-using-a-nuspec.
Are there any plans to address this issue?
So I decided to try using a .nuspec file to work around this issue, https://github.com/NuGet/Home/issues/3891 , and I ran into this issue of not being able to pass multiple key/value pairs to -p:NuspecProperties. It is especially frustrating because the docs continue to say that this is supported. Are there any plans to fix this?
Just ran into this as well -- any plans to fix? If not, I may take a stab at opening a PR to fix this up.
I also ran into the issue (.NET 6) but found a nice way that works.
According to https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#pack-target many nuspec settings have now corresponding MSBuild properties and one can pass them directly via dotnet pack ... -p:PackageVersion=11.0.0 -p:RepositoryType=git. This may not work for all nuspec settings but it was enough for my use case.
Facing the same issue. Cannot pass multiple parameters to NuspecProperties
-p:NuspecProperties="version=5.0.3;configuration=Release"
returns
"C:\Program Files\dotnet\sdk\6.0.303\Sdks\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets(221,5): error : An error occured while trying to parse the value '5.0. 3;configuration=Release' of property 'version' in the manifest file."
There are several levels to this problem.
- There's a bug in the SDK's CLI parsing when you pass the command
dotnet build -p:NuspecProperties="a=1;b=2". The resulting command line is un-parsing the property's second value to a standalone MSBuild property:C:\Program Files\dotnet\sdk\7.0.101\MSBuild.dll --property:NuspecProperties=a=1 --property:b=2 - If you (reasonably) circumvent this by treating the property as a string, escaping the semicolon with %3B (which is the documented way of ensuring special characters round-trip on the MSBuild command line), then MSBuild interprets
dotnet build -p:NuspecProperties="a=1%3Bb=2"as a single string, instead of breaking into separate values for the backingstring[]Task parameter:
- This is a known problem, and other places in the various targets add
.Split('%3B')to the property use in their targets to handle just this scenario (see this target as an example).
Therefore, I think to finally solve this we should:
- Add the Split to the NuGet targets' PackTask NugetProperties usage
- Investigate why the CLI property parser is splitting this property up (unexpectedly?), though I fear this may have implications for other use cases we've run across already
cc : @baronfel The solution that works for me is to use either update the .csproj or create a dynamic Directory.Build.props file (good for pipeline builds) and then add the nuspec properties NuspecFile , NuspecProperties there
<Project> <PropertyGroup> ....... <NuspecFile>app.nuspec</NuspecFile><NuspecProperties>version=$(PackageVersion);dateToday=$(dateToday);releaseName=$(releaseName)</NuspecProperties> </PropertyGroup> </Project>
app.nuspec file
<version>$version$</version> ....... <description> ReleaseName :$releaseName$ date : $dateToday$ </description>
Then pass multiple parameters to csproj using below command:- dotnet pack "...\abcd.csproj" /p:PackageVersion=%version% /p:dateToday=%date:~10,4%%date:~4,2%%date:~4,2% /p:releaseName=%releaseName%
In this way I can use multiple Nuspec properties, however still not able to use it from the argument -p:NuspecProperties=.. when using dotnet pack command
I still get this issue in .NET:
.NET SDK: Version: 8.0.204 Commit: c338c7548c Workload version: 8.0.200-manifests.7d36c14f
I still get this issue in .NET:
.NET SDK: Version: 8.0.204 Commit: c338c7548c Workload version: 8.0.200-manifests.7d36c14f
I also struggeled with this problem in latest net8, but multiple properties are possible using this "style" in the project file (net sdk):
<PropertyGroup>
<NuspecFile>my.nuspec</NuspecFile>
<NuspecProperties>$(NuspecProperties);configuration=$(Configuration)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);version=$(Version)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);id=$(PackageId)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);author=$(Author)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);PackageProjectUrl=$(PackageProjectUrl)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);Description=$(Description)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);PackageReleaseNotes=$(PackageReleaseNotes)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);Copyright=$(Copyright)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);PackageTags=$(PackageTags)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);RepositoryType=$(RepositoryType)</NuspecProperties>
<NuspecProperties>$(NuspecProperties);RepositoryUrl=$(RepositoryUrl)</NuspecProperties>
</PropertyGroup>