Jonathan Holland
Jonathan Holland

Reputation: 1281

Strange behavior with NuSpec $version$ replacement for pre-release packages

I have a project that is comprised of a core nuget package, and then several additional extension packages.

The core package has a nuspec that looks like this:

<?xml version="1.0"?>
<package>
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>The Core Package</title>
    <authors>$author$</authors>
    <owners>$author$</owners>    
    <description>$description$</description>
  </metadata>
</package>

And, in each extension package, I have a nuspec like this:

<?xml version="1.0"?>
<package>
  <metadata>
    <id>$id$</id>
    <version>$version$</version>
    <title>A Extension Package</title>
    <authors>$author$</authors>
    <owners>$author$</owners>
    <dependencies>
      <dependency id="The.Core" version="$version$"/>
    </dependencies>
  </metadata>
</package>

I use the same $version$ token to rev all packages at once when a release build is ran. This makes the dependency on the core move forward whenever I do a release.

Now, I've been using this as on a private nuget feed and it has been working great. However, I wanted to release these packages to public nuget as a prerelease. I setup the Assembly Version attributes to look like this on ALL of the assemblies:

[assembly: AssemblyFileVersion("1.0.1")]
[assembly: AssemblyInformationalVersion("1.0.1-alpha")]

However, when I run nuget pack (From my build server), it doesn't seem to be picking up 1.0.1-alpha as the version for the package:

[pack] Starting NuGet.exe 2.7.40906.75 from C:\TeamCity\buildAgent\tools\NuGet.CommandLine.DEFAULT.nupkg\tools\NuGet.exe
[14:21:46][pack] WARNING: Option 'Verbose' has been deprecated. Use 'Verbosity' instead.
[14:21:46][pack] Attempting to build package from 'The.Core.csproj'.
[14:21:46][pack] Packing files from 'C:\TeamCity\buildAgent\work\857bd09f14af8e44\src\The.Core\bin\Release'.
[14:21:46][pack] Using 'The.Core.nuspec' for metadata.
[14:21:46][pack] 
[14:21:46][pack] Id: The.Core
[14:21:46][pack] Version: 1.0.1
[14:21:46][pack] Authors: Jonathan  Holland
[14:21:46][pack] License Url: http://www.apache.org/licenses/LICENSE-2.0
[14:21:46][pack] Dependencies: None
[14:21:46][pack] 
[14:21:46][pack] Added file 'lib\net40\The.Core.dll'.
[14:21:46][pack] 
[14:21:46][pack] Successfully created package 'C:\TeamCity\buildAgent\work\Publish\The.Core.1.0.1.nupkg'.
[14:21:46][pack] Process exited with code 0

You can see that it picked up 1.0.1 as the version, and not 1.0.1-alpha like I expected.

Things get weirder when the build server attempts to pack the first extension:

[pack] Starting NuGet.exe 2.7.40906.75 from C:\TeamCity\buildAgent\tools\NuGet.CommandLine.DEFAULT.nupkg\tools\NuGet.exe
[14:21:46][pack] WARNING: Option 'Verbose' has been deprecated. Use 'Verbosity' instead.
[14:21:46][pack] Attempting to build package from 'The.Core.Extension.csproj'.
[14:21:46][pack] Packing files from 'C:\TeamCity\buildAgent\work\857bd09f14af8e44\src\he.Core.Extension\bin\Release'.
[14:21:46][pack] Using 'The.Core.Extension.nuspec' for metadata.
[14:21:46][pack] Found packages.config. Using packages listed as dependencies
[14:21:46][pack] A stable release of a package should not have on a prerelease dependency. Either modify the version spec of dependency "The.Core (ò 1.0.1-alpha)" or update the version field.
[14:21:46][pack] Process exited with code 1

So, here we have a failure because $version$ in the dependancy section of the nuspec was properly replaced with "1.0.1-alpha", however in the version node, it was replaced with 1.0.1.

This is really bizarre behavior, so I have to be doing something totally wrong. I assumed it was as simple search and replace token for nuspecs, but there must be some sort of context to how the token behaviors work.

I want the <version> node on both nuspecs to use the version from AssemblyInformationalVersion, and they should as far as I can tell from the docs.

Upvotes: 4

Views: 1936

Answers (2)

Steven Yates
Steven Yates

Reputation: 2480

I am attempting to do the same thing and it's been behaving weirdly.

The replacement token $version$ was getting replaced correctly inside the <version></version> tag but not in any of the dependencies

<dependency id="Norse.Core.Exceptions" version="$version$" />

end up like

<dependency id="Norse.Core.Exceptions" version="1.0.0" />

I add a new Build Feature, File Content Replacer and setup it up as follows,

Process files list: **/*.nuspec *.nuspec

Find what: \$version\$

Replace with: %system.build.version%

The system.build.version is my parameter I've defined earlier on in the process, you can set this to whatever you like.

Hope it helps someone.

Thanks

Steve

Upvotes: 0

Jonathan Holland
Jonathan Holland

Reputation: 1281

After a considerable amount of spelunking, I found that the issue was from the TeamCity Nuget Build Runner:

enter image description here

This box has %build_number% populated in it, and somehow this was conflicting with nugets own reflection on the assembly attributes.

Setting it blank fixed it.

Upvotes: 1

Related Questions