Silly mistakes using MSBuild

The last couple of months I've been working as part of .Net team again. It might not be Clojure, which is what I would like to do right now; but it could be worse, it could be Java, at least .Net has LINQ.

At the moment I've been struggling with MSBuild. The team doesn't have a very good build pipeline setup, so I've been working to create a more reliable build pipeline in Jenkins. Not being very familiar with Jenkins or MSBuild has been a slow process. The latest of which was around item groups.

I had a couple of basic tasks setup - clean, compile, publish to a local folder. What I was then trying to do was copy these files that were published. The .build looked a little something like this -


<Project DefaultTargets="Compile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>  <FilesToCopy Include="$(PublishLocation)\*.*"/></ItemGroup>

<Target Name="Compile">  Do some stuff to make it compile</Target>

<Target Name="PublishLocally">  do some stuff to publish files to $(PublishLocation)</Target>

<Target Name="CopyLocalFiles">  <Copy    SourceFiles="@(PublishLocation)"    DestinationFolder="c:\MyProject\Destination"  />
</Target>
</Project>

However, I started getting some weird behaviour if I were to run msbuild setting the target to be 'Compile;PublishLocally;CopyLocalFiles;'. If I were to delete everything from the folder 'PublishLocation', the task 'PublishLocally' would recreate them however the task 'CopyLocalFiles' wouldn't pick them up. In fact it wouldn't copy anything. However if I were to run the same task again, right after this it would work.

I found that the problem seems to be due to the fact that the ItemGroups is defined prior to the files existing. So I changed the file to look more like this -
<Project DefaultTargets="Compile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<Target Name="Compile">  Do some stuff to make it compile</Target>

<Target Name="PublishLocally">  do some stuff to publish files to $(PublishLocation)</Target>

<Target Name="CopyLocalFiles">
  <ItemGroup>    <FilesToCopy Include="$(PublishLocation)\*.*"/>  </ItemGroup>
  <Copy    SourceFiles="@(PublishLocation)"    DestinationFolder="c:\MyProject\Destination"  />

</Target>
</Project>

This seemed to fix my problem.

My naive understanding is that the ItemGroup isn't just a reference to whatever is in that folder but it will actually go and resolve what files actually make up the ItemGroup when MSBuild is run not when the ItemGroup is used.

This is one of those things that is really frustrating to try to fix. It was clear that the problem was something I was doing wrong however that didn't make it any easier to find the problem.

Comments