Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
There are some really useful TeamBuild tasks whose purpose or usage is not immediate. Such is WorkspaceItemConverterTask: it allows to transform a $ path — that is the path to a file or folder in TFS Version Control — to the physical path that the file assume during the TeamBuild.
To see how it’s used, you have to look into Microsoft.TeamFoundation.Build.targets (this file is located under %ProgramFiles(x86)%\MSBuild\Microsoft\VisualStudio\TeamBuild), and it simple to use: ServerItems gets an ItemGroup to resolve and LocalItems will held the list of resolved paths. The other parameters are needed but are always the same: they represent the context of evaluation.
I found this task useful when I needed to add some post-processing to my solutions in TeamBuild: I attached some custom metadata to the Items representing the solutions to build and iterated through them in a late build step, like PackagingBinaries.
This sample code may help understand its usage.
1: <Target Name="ResolveSolutionPathsForDeploy"
2: Condition="'$(IsDesktopBuild)' != 'true'">
3: <WorkspaceItemConverterTask
4: Condition="'@(SolutionToBuild)' != ''"
5: TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
6: BuildUri="$(BuildUri)"
7: WorkspaceName="$(WorkspaceName)"
8: WorkspaceOwner="$(WorkspaceOwner)"
9: ServerItems="@(SolutionToBuild)">
10: <Output TaskParameter="LocalItems" ItemName="LocalSolutionToBuild" />
11: </WorkspaceItemConverterTask>
12: </Target>
13:
14:
15: <Target Name="LocalDeploy" DependsOnTargets="ResolveSolutionPathsForDeploy" Condition="'$(DeployLocally)'=='true'">
16:
17: <PropertyGroup>
18: <_DeployScript Condition="'%(LocalSolutionToBuild.PsDeploy)'=='true'">
19: %(LocalSolutionToBuild.RootDir)%(LocalSolutionToBuild.Directory)%(LocalSolutionToBuild.Filename).Deployment\%(LocalSolutionToBuild.Filename).Deploy.ps1
20: </_DeployScript>
21: <_UndeployScript Condition="'%(LocalSolutionToBuild.PsDeploy)'=='true'">
22: %(LocalSolutionToBuild.RootDir)%(LocalSolutionToBuild.Directory)%(LocalSolutionToBuild.Filename).Deployment\%(LocalSolutionToBuild.Filename).Undeploy.ps1
23: </_UndeployScript>
24: </PropertyGroup>
25:
26: <Powershell ScriptFile="$(_UndeployScript)" Arguments="SolutionName=%(LocalSolutionToBuild.Filename)" Condition="'%(LocalSolutionToBuild.PsDeploy)'=='true'" />
27: <Powershell ScriptFile="$(_DeployScript)" Arguments="SolutionName=%(LocalSolutionToBuild.Filename)" Condition="'%(LocalSolutionToBuild.PsDeploy)'=='true'" />
28:
29: </Target>
The solution has the appropriate metadata to activate the previous code, as follows.
1: <ItemGroup>
2: <!-- SOLUTIONS -->
3: <SolutionToBuild Include="$(BuildProjectFolderPath)/../../Sources/Services/Service1/Service1.sln">
4: <PsDeploy>true</PsDeploy>
5: </SolutionToBuild>
6: <SolutionToBuild Include="$(BuildProjectFolderPath)/../../Sources/Common/Common.sln">
7: <MsiDeploy>true</MsiDeploy>
8: </SolutionToBuild>
9: <SolutionToBuild Include="$(BuildProjectFolderPath)/../../Sources/Web/Site.sln">
10: <PsDeploy>true</PsDeploy>
11: </SolutionToBuild>
12: </ItemGroup>
Happy Build!
Comments
Anonymous
September 16, 2010
The comment has been removedAnonymous
September 16, 2010
The comment has been removedAnonymous
September 16, 2010
I tried this : <Target Name="CopyFiles"> <Copy SourceFiles="@(ConfigurationFiles)" DestinationFiles="@(ConfigurationFiles->'$(OutDir)%(RecursiveDir)%(Filename)%(Extension)')" /> </Target> Where : <ItemGroup> <ConfigurationFiles Include="$(SolutionRoot)Configuration***.*"/> </ItemGroup> I skimmed the logfile for errors, there were none. No warnings related to this as well. any other thoughts?Anonymous
September 16, 2010
I suggest to add some logging to your code so to better understand what is happening, e.g. <Target Name="CopyFiles"> <Message Text="In CopyFiles ConfigurationFiles is @(ConfigurationFiles)" /> <Copy SourceFiles="@(ConfigurationFiles)" DestinationFiles="@(ConfigurationFiles->'$(OutDir)%(RecursiveDir)%(Filename)%(Extension)')" /> </Target> This way you can determine if the target is being called, at what point in the process, and the values it gets.