views:

39

answers:

1

I have a very odd issue, where I've created a custom MSBuild task that would move all files I need for my MVC project to a specific location so that we can publish it. This works fine when I trigger the script localy on my machine but as soon as I check this changes in and Teamcity runs the script, it copies everything except from the Bin folder. However, if run MSbuild directlly from the command line (same script), it does copy the bin folder. I don't understand why this isn't working when TeamCity is building it.

Does anyone have an idea why this is happening and how to solve it?

<Target Name="AfterBuild">
   <CallTarget Targets="Move" />
</Target>
<Target Name="Move">
    <Copy SourceFiles="@(BinFolder)" DestinationFolder="$(ArtifactsDir)\Webproject.Web\bin" />
    <Copy SourceFiles="@(ContentFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Content" />
    <Copy SourceFiles="@(ImagesFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Images" />
    <Copy SourceFiles="@(ScriptsFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Scripts" />
</Target>


<ItemGroup>
   <BinFolder Exclude="*.cs" Include="$(ProjectDir)bin\**\*.*"/>
   <ContentFolder Exclude="*.cs;*.svn-base" Include="$(ProjectDir)Content\*.css"/>
   <ImagesFolder Exclude="*.cs;*.svn-base" Include="$(ProjectDir)Images\*.*"/>
   <ScriptsFolder Exclude="*.cs;*.svn-base" Include="$(ProjectDir)Scripts\*.js"/>
</ItemGroup>

$(ArtifactsDir) is a paramanter I'm passing in from Teamcity & manually in the command line.

/p:ArtifactsDir="%system.agent.work.dir%\WebProject\trunk\Website"
+1  A: 

I think it's a problem of items evaluation. Your "BinFolder" item is interpreted at the first time MsBuild read your build file, i.e. before the build. And I think that $(ProjectDir)bin**. is empty before the build. To avoid this you can declare your binfolder within your target as shown :

<Target Name="AfterBuild">
   <CallTarget Targets="Move" />
</Target>
<Target Name="Move">

    <ItemGroup>
      <BinFolder Exclude="*.cs" Include="$(ProjectDir)bin\**\*.*"/>
    </ItemGroup>

    <Copy SourceFiles="@(BinFolder)" DestinationFolder="$(ArtifactsDir)\Webproject.Web\bin" />
    <Copy SourceFiles="@(ContentFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Content" />
    <Copy SourceFiles="@(ImagesFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Images" />
    <Copy SourceFiles="@(ScriptsFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Scripts" />
</Target>

<ItemGroup>
   <ContentFolder Exclude="*.cs;*.svn-base" Include="$(ProjectDir)Content\*.css"/>
   <ImagesFolder Exclude="*.cs;*.svn-base" Include="$(ProjectDir)Images\*.*"/>
   <ScriptsFolder Exclude="*.cs;*.svn-base" Include="$(ProjectDir)Scripts\*.js"/>
</ItemGroup>

Or else you could try using CreateItem task :

<Target Name="Move">

    <CreateItem Exclude="*.cs" Include="$(ProjectDir)bin\**\*.*">
      <Output TaskParameter="Include" ItemName="TheFiles"/>
    </CreateItem>

    <Copy SourceFiles="@(BinFolder)" DestinationFolder="$(ArtifactsDir)\Webproject.Web\bin" />
    <Copy SourceFiles="@(ContentFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Content" />
    <Copy SourceFiles="@(ImagesFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Images" />
    <Copy SourceFiles="@(ScriptsFolder)" DestinationFolder="$(ArtifactsDir)\SchrodersFundEngine.Web\Scripts" />
</Target>

You can find more information here :

Benjamin Baumann
Really interesting answer. I thought it might be something along that line, but never thought of the actuall decleration of the bin folder location. I'll try it straight away.
MrW
The decleration of "@(BinFolder)" inside the target (your first example) solved the issue. Thanks so much!
MrW
Yeah this issue is 100% related to the fact that items outside of targets are evaluated before any target executes. FYI this issue has nothing to do with the CallTarget bug, and for MSBuild 4 you shouldn't need to use CreateItem. Putting ItemGroup inside target is pretty much the same.
Sayed Ibrahim Hashimi