tags:

views:

310

answers:

1

Hi All, I'm having some strange problems copying files in a custom script in TFS2008 without SP1, I have to run the build several times to get the files copied (most of the times its in the second build that i get the files), let me give you the details:

This is happening with ASP sites and VS2003 Web solutions, (vs2008 solutions are OK) In ASP I have a dummy 2008 solution, the build compiles this dummy, I override AfterCompile and in there I copy all the files to the drop location In VS 2003 i have also a dummy 2008 solution, the build first compiles the dummy, I override AfterCompile, use "Exec" and "Command" to compile the 2003 solution and then copy the files to the drop location.

As you can see both approaches are similar, I'm not having problems with the builds per se, my problem is reproducible in two ways (and yes, i do check out, update, check in and then test the build):

  1. Create a new build, configure the script, run the build the first time, some DLL's in the bin folder are not copied, run the build for the second time and i get all the files.

  2. Build already configured and running OK, add some file to the project (this mostly happens with the ASP sites), run the build, don't get this new file, run the build again and i get this new file.

Here is my build script for a VS2003 Web solution as an example

<PropertyGroup> 
<TasksPath>D:\BuildTools\</TasksPath> 
    <VS2003Devenv>D:\Archivos de programa\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.com</VS2003Devenv> 
    <VS2003VirtualFolder>CnbvPifWeb</VS2003VirtualFolder> 
    <VS2003Suba>Cnbv.Pif.Web</VS2003Suba> 
    <VS2003Project>Cnbv.Pif.Web</VS2003Project> 
    <VS2003WebSiteName>Sitio Web predeterminado</VS2003WebSiteName> 
    <VS2003Configuration>Release</VS2003Configuration> 
    <VS2003Branch>Desarrollo</VS2003Branch> 
    <VS2003RelativePath>$(SolutionRoot)\$(VS2003Branch)\$(VS2003Suba)\</VS2003RelativePath> 
    <VS2003SolutionPath>$(VS2003RelativePath)Cnbv.Pif.Web.sln</VS2003SolutionPath> 
    <VS2003LocalFolder>$(VS2003RelativePath)Sources\$(VS2003Project)\</VS2003LocalFolder> 
    <VS2003Output>$(BinariesRoot)\$(VS2003Project)\</VS2003Output> 
    <VS2003CachePath>C:\Documents and Settings\srvfoundation\VSWebCache\230-2555-CPU015\</VS2003CachePath> 
    <VS2003ProjectExtension>vbproj</VS2003ProjectExtension> 
    <VS2003CacheFile>$(VS2003CachePath)$(VS2003VirtualFolder)\_vti_pvt\$(VS2003Project).$(VS2003ProjectExtension).cache</VS2003CacheFile>
</PropertyGroup> 
<Import Project="$(TasksPath)Microsoft.Sdc.Common.tasks"/> 
<UsingTask TaskName="Microsoft.Sdc.Tasks.Web.WebSite.CreateVirtualDirectory" AssemblyFile="Microsoft.Sdc.Tasks.dll" /> 
<UsingTask TaskName="Microsoft.Sdc.Tasks.Web.WebSite.DeleteVirtualDirectory" AssemblyFile="Microsoft.Sdc.Tasks.dll" /> 
<ItemGroup> 
    <!--list of ouput files, excluding .DLL outside bin and some other files--> 
        <VS2003OutputFiles 
            Include="$(VS2003LocalFolder)**\*.*" 
            Exclude="$(VS2003LocalFolder)**\*.vb;$(VS2003LocalFolder)**\*.cs;$(VS2003LocalFolder)**\*.resx;$(VS2003LocalFolder)**\*.vspscc;$(VS2003LocalFolder)**\*.csproj;$(VS2003LocalFolder)**\*.vbproj;$(VS2003LocalFolder)**\*.scc;$(VS2003LocalFolder)**\*.webinfo;$(VS2003LocalFolder)**\*.snk;$(VS2003LocalFolder)**\*.dll;$(VS2003LocalFolder)**\*.exe;" />
    <!-- copy dll to bin folder -->
        <VS2003OutputBinFiles 
        Include="$(VS2003LocalFolder)bin\*.dll"/> 
</ItemGroup> 
<Target Name="AfterCompile"> 
<Message Text="Deleting cache file" /> 
    <Microsoft.Build.Tasks.Delete 
        Condition="Exists('$(VS2003CacheFile)')" 
        Files="$(VS2003CacheFile)" /> 
    <Message Text="Creating virtual folder $(VS2003VirtualFolder) in IIS in local path $(VS2003LocalFolder)" /> 
    <Web.WebSite.CreateVirtualDirectory 
        VirtualDirectoryName="$(VS2003VirtualFolder)" 
        Path="$(VS2003LocalFolder)" 
        WebSiteName="$(VS2003WebSiteName)" /> 
    <Message Text="Compiling $(VS2003Project) in $(VS2003Branch)" /> 
    <Exec 
        Command="&quot;$(VS2003Devenv)&quot; &quot;$(VS2003SolutionPath)&quot; /build $(VS2003Configuration) /out &quot;$(VS2003LocalFolder)$(VS2003Project).log&quot; "/> 
    <Message Text="Eliminando la carpeta virtual $(VS2003VirtualFolder) en IIS" /> 
    <Web.WebSite.DeleteVirtualDirectory 
        WebSiteName="$(VS2003WebSiteName)" 
        VirtualDirectoryName="$(VS2003VirtualFolder)" /> 
    <MakeDir Condition="!Exists('$(VS2003Output)')" Directories="$(VS2003Output)" /> 
    <Message Text="Copying output files @(VS2003OutputFiles)" /> 
    <Copy 
        SourceFiles="@(VS2003OutputFiles)" 
        DestinationFiles="@(VS2003OutputFiles->'$(VS2003Output)%(RecursiveDir)%(Filename)%(Extension)')" 
    /> 
    <MakeDir Condition="!Exists('$(VS2003Output)bin\')" Directories="$(VS2003Output)bin\" /> 
    <Message Text="Copying DLL to bin folder @(VS2003OutputBinFiles)" /> 
    <Copy 
        SourceFiles="@(VS2003OutputBinFiles)" 
        DestinationFiles="@(VS2003OutputBinFiles->'$(VS2003Output)bin\%(Filename)%(Extension)')" 
    /> 
    <OnError ExecuteTargets="VS2003Fail" />
</Target>
    <Target Name="VS2003Fail"> 
<Message Text="Copying log file $(VS2003RelativePath)$(VS2003Project).log" /> 
    <Copy Condition="Exists('$(VS2003RelativePath)$(VS2003Project).log')" SourceFiles="$(VS2003RelativePath)$(VS2003Project).log" DestinationFolder="$(DropLocation)\$(BuildNumber)" /> 
    <CallTarget ContinueOnError ="true" Targets ="CreateWorkItemWhenPartialSucceed" /> 
</Target> 
<Target 
        Name="CreateWorkItemWhenPartialSucceed" 
        Condition=" '$(SkipWorkItemCreation)'!='true' and '$(IsDesktopBuild)'!='true' "> 
        <Message Text="ejecutando work" /> 
        <PropertyGroup> 
            <WorkItemTitle>$(WorkItemTitle) $(BuildNumber)</WorkItemTitle> 
            <BuildLogText>$(BuildlogText) &lt;ahref='file:///$(DropLocation)\$(BuildNumber)\BuildLog.txt'&gt;$(DropLocation)\$(BuildNumber)\BuildLog.txt&lt;/a &gt;.</BuildLogText> 
            <ErrorWarningLogText     Condition="!Exists('$(MSBuildProjectDirectory)\ErrorsWarningsLog.txt')"></ErrorWarningLogText> 
        <ErrorWarningLogText Condition="Exists('$(MSBuildProjectDirectory)\ErrorsWarningsLog.txt')">$(ErrorWarningLogText) &lt;a href='file:///$(DropLocation)\$(BuildNumber)\ErrorsWarningsLog.txt'&gt;$(DropLocation)\$(BuildNumber)\ErrorsWarningsLog.txt&lt;/a &gt;.</ErrorWarningLogText> 
        <WorkItemDescription>$(DescriptionText) %3CBR%2F%3E $(BuildlogText) %3CBR%2F%3E $(ErrorWarningLogText)</WorkItemDescription> 
    </PropertyGroup> 
        <CreateNewWorkItem 
        TeamFoundationServerUrl="$(TeamFoundationServerUrl)" 
  BuildUri="$(BuildUri)" 
  BuildNumber="$(BuildNumber)" 
  Description="$(WorkItemDescription)" 
  TeamProject="$(TeamProject)" 
  Title="$(WorkItemTitle)" 
  WorkItemFieldValues="$(WorkItemFieldValues)" 
  WorkItemType="$(WorkItemType)" 
  ContinueOnError="true" /> 
</Target>

When I see the ouput of this message in the log

<Message Text="Copying DLL to bin folder @(VS2003OutputBinFiles)" />

the first time i see just the name of one file, the second time it prints all the correct files, and the same happens with the ASP sites, if I add a file i see the file in the output in the second build.

I hope you can help me out figuring this out, thanks a lot.

Juan Zamudio

A: 

this was the answer in the tfs forum by OsirisJakob

The problem is that you define your item groups at the root level. This means that they are evaluated immediately when the project file loaded. What you want is for them to be evaluated when the AfterCompile target is executed.

Since you are running TFS 2008, you can solve this problem by moving the item groups into the AfterCompile target (a.k.a. Dynamic item groups). This will cause the item group to be evaluated by the time the AfterCompile target is executed, and will give you the correct result.

Juan Zamudio