Search code examples
msbuildmsbuildcommunitytasks

Using XmlUpdate to set Version information from an Assembly


Using MSBuild and MSBuild Community Tasks I am trying to do something very simple:

  1. Get version information from an assembly.
  2. Update a .nuspec file with that version information.

My MSBuild target looks like this:

<Target Name="Package">
  <GetAssemblyIdentity AssemblyFiles="%(PackageDir.FullPath)\MyAssembly.dll">
    <Output TaskParameter="Assemblies" ItemName="AssemblyIdentity" />
  </GetAssemblyIdentity>
  <XmlUpdate 
     Prefix="nu"
     Namespace="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"
     XmlFileName="%(PackageDir.FullPath)\MyAssembly.nuspec"
     XPath="/nu:package/nu:metadata/nu:version"
     Value="%(AssemblyIdentity.Version)" />
</Target>

The problem I'm having is that the NuGetPack task runs TWICE: The first time, the Assembly version is missing but the paths are correct, the second time the Assembly version is correct but the paths are missing!

Here is the output:

Updating Xml Document "D:\MyProject\package\MyAssembly.nuspec".
    1 node(s) selected for update.
  XmlUpdate Wrote: "".
  Updating Xml Document "\MyAssembly.nuspec".
D:\MyProject\MyProject.build(64,9): error : Could not find file
 'D:\MyAssembly.nuspec'.
Done Building Project "D:\MyProject\MyProject.build" (Package target(s)
) -- FAILED.

I also tried using the NuGetPack task, but got similar results. Help is greatly appreciated!


Solution

  • I seem to have solved it, though I'm still not sure why the code in my original question does not work.

    Instead of specifying paths via concatenation (e.g. AssemblyFiles="%(PackageDir.FullPath)\MyAssembly.dll") I put each path into its own item:

    <ItemGroup>
    ...
      <PackageVersionAssembly Include=".\build-artifacts\package\MyAssembly.dll"/>
      <NuSpecFile Include=".\build-artifacts\package\MyAssembly.nuspec"/>
    ...
    </ItemGroup>
    

    I made the same change in the task and made the same change to references to the .nuspec file.

    The new Package target looks like this:

    <Target Name="Package">
      <GetAssemblyIdentity AssemblyFiles="@(PackageVersionAssembly)">
        <Output TaskParameter="Assemblies" ItemName="AssemblyIdentity" />
      </GetAssemblyIdentity>
      <XmlUpdate 
         Prefix="nu"
         Namespace="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"
         XmlFileName="@(NuSpecFile)"
         XPath="/nu:package/nu:metadata/nu:version"
         Value="%(AssemblyIdentity.Version)" />
    </Target>
    

    I hope this helps others!