问题
I'm trying to add an automatic post-build trigger to run NDepend (code metrics software) after an automated team build in TFS 2010.
NDepend's website provided code for integrating this capability, and so I have pasted their code into my .csproj file where they said for it to go, but I receive errors on the build.
The errors refer to two of the three "BuildStep" tags I have in the code snippet. The following two snippets are giving me errors:
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Message="Running NDepend analysis">
<Output TaskParameter="Id" PropertyName="StepId" />
</BuildStep>
and
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Failed" />
However, this code snippet is NOT throwing up any problems:
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Succeeded" />
I just don't understand why one works fine and a nearly identically laid out BuildStep tag does not. Is there something simple that I'm just overlooking?
EDIT: Here is how it looks all together, if this makes a difference:
<Target Name="NDepend" >
<PropertyGroup>
<NDPath>c:\tools\NDepend\NDepend.console.exe</NDPath>
<NDProject>$(SolutionDir)MyProject.ndproj</NDProject>
<NDOut>$(TargetDir)NDepend</NDOut>
<NDIn>$(TargetDir)</NDIn>
</PropertyGroup>
<Exec
Command='"$(NDPath)" "$(NDProject)" /OutDir "$(NDOut)" /InDirs "$(NDIn)"'/>
</Target>
<Target Name="AfterBuild">
<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Message="Running NDepend analysis">
<Output TaskParameter="Id" PropertyName="StepId" />
</BuildStep>
<PropertyGroup>
<NDPath>c:\tools\NDepend\NDepend.console.exe</NDPath>
<NDProject>$(SolutionRoot)\Main\src\MyProject.ndproj</NDProject>
<NDOut>$(BinariesRoot)\NDepend</NDOut>
<NDIn>$(BinariesRoot)\Release</NDIn>
</PropertyGroup>
<Exec
Command='$(NDPath) "$(NDProject)" /OutDir "$(NDOut)" /InDirs "$(NDIn)"'/>
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Succeeded" />
<OnError ExecuteTargets="MarkBuildStepAsFailed" />
</Target>
<Target Name="MarkBuildStepAsFailed">
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Failed" />
</Target>
EDIT: Added a bounty because I really need to get this going for my team.
EDIT: Included more specifics about the errors, I disguised the location/name of the file by "blah" for copyright reasons, I'm not sure if I'm technically able to release that info, so I am erring on the side of safe rather than sorry, but if you absolutely must know for the sake of fixing this problem, I'll see what I can do. The following errors were listed in the results of the failed team build as well as various other warnings, but these errors were the only ones that I could see that pertained to the NDepend XML code above.
The errors I get when I run the team build:
C:*Blah*.csproj (172): The "BuildStep" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with in the project file, or in the *.tasks files located in the "c:\Windows\Microsoft.NET\Framework\v4.0.30319" directory.
and
C:*Blah*.csproj (194): The "BuildStep" task was not found. Check the following: 1.) The name of the task in the project file is the same as the name of the task class. 2.) The task class is "public" and implements the Microsoft.Build.Framework.ITask interface. 3.) The task is correctly declared with in the project file, or in the *.tasks files located in the "c:\Windows\Microsoft.NET\Framework\v4.0.30319" directory.
EDIT: I thought I had it running right, but it sill isn't building properly. It's still throwing up the errors above when I build, despite mimicking @Ewald's suggested XML below. I adjusted the property values of said code according to what I think should work as follows:
<Target Name="NDepend" >
<PropertyGroup>
<NDPath>c:\tools\NDepend\NDepend.console.exe</NDPath>
<NDProject>$(SolutionDir)MyProject.ndproj</NDProject>
<NDOut>$(TargetDir)NDepend</NDOut>
<NDIn>$(TargetDir)</NDIn>
</PropertyGroup>
<Exec
Command='"$(NDPath)" "$(NDProject)" /OutDir "$(NDOut)" /InDirs "$(NDIn)"'/>
</Target>
<Target Name="AfterBuild">
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Name="CallMyTarget"
Message="Call My Target"
Condition="'$(IsDesktopBuild)'!='true'">
<Output TaskParameter="Id" PropertyName="StepId" />
</BuildStep>
<CallTarget Targets="NDepend" ContinueOnError="false"/>
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Succeeded"
Condition="'$(IsDesktopBuild)'!='true'" />
<OnError ExecuteTargets="FailStep" />
</Target>
<Target Name="FailStep">
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Failed"
Condition="'$(IsDesktopBuild)'!='true'" />
</Target>
However, I did try just putting this code in:
<Target Name="NDepend" >
<PropertyGroup>
<NDPath>c:\tools\NDepend\NDepend.console.exe</NDPath>
<NDProject>$(SolutionDir)MyProject.ndproj</NDProject>
<NDOut>$(TargetDir)NDepend</NDOut>
<NDIn>$(TargetDir)</NDIn>
</PropertyGroup>
<Exec
Command='"$(NDPath)" "$(NDProject)" /OutDir "$(NDOut)" /InDirs "$(NDIn)"'/>
</Target>
And the automated build went fine, no errors, but the NDepend just didn't run like it was supposed to.
I'm beginning to wonder (after consultation with various other sub-questions) if there's some slight difference in the XML schema used in TFS2010 vs TFS2008 that is causing me to have these problems. So, with that in mind, does anyone know about any big differences in these schemas?
EDIT: Just keeping you all up to date with everything I've tried, I now tried this code:
<Target Name="AfterBuild">
<PropertyGroup>
<NDPath>c:\tools\NDepend\NDepend.console.exe</NDPath>
<NDProject>$(SolutionDir)MyProject.ndproj</NDProject>
<NDOut>$(TargetDir)NDepend</NDOut>
<NDIn>$(TargetDir)</NDIn>
</PropertyGroup>
<Exec
Command='"$(NDPath)" "$(NDProject)" /OutDir "$(NDOut)" /InDirs "$(NDIn)"'/>
</Target>
and it produced a different error message, as follows:
C:*Blah*.csproj (179): The command ""c:\tools\NDepend\NDepend.console.exe" "C:*Blah*\Sources\Main\MyProject.ndproj" /OutDir "C:*Blah*\Binaries\Debug\NDepend" /InDirs "C:*Blah*\Binaries\Debug\"" exited with code 1.
EDIT: The latest code I tried. This was (according to NDepend's site) the "built-in NDepend MSBuild task."
<Target Name="AfterBuild">
<PropertyGroup>
<NDPath>c:\tools\NDepend\NDepend.console.exe</NDPath>
<NDProject>$(SolutionDir)MyProject.ndproj</NDProject>
</PropertyGroup>
<UsingTask AssemblyFile="$(NDPath)\MSBuild\NDepend.Build.MSBuild.dll"
TaskName="NDependTask" />
<Target Name="NDepend" >
<NDependTask NDependConsoleExePath="$(NDPath)"
ProjectFilePath="$(NDProject)" />
</Target>
</Target>
But I get this error:
C:*Blah*.csproj (180): The element beneath element is unrecognized.
回答1:
I use the following lines of code to achieve additional build steps
<Target Name="Customization">
<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)" Name="CallMyTarget" Message="Call my target" Condition="'$(IsDesktopBuild)'!='true'" >
<Output TaskParameter="Id" PropertyName="CurrentBuildStepId" />
</BuildStep>
<CallTarget Targets="MyTarget" ContinueOnError="false"/>
<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)" Id="$(CurrentBuildStepId)" Status="Succeeded" Condition="'$(IsDesktopBuild)'!='true'" />
<OnError ExecuteTargets="FailStep"/>
</Target>
<Target Name="FailStep">
<BuildStep TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)" Id="$(CurrentBuildStepId)" Status="Failed" Condition="'$(IsDesktopBuild)'!='true'" />
</Target>
回答2:
The code snippets only work when you run Team Build. They will probably fail when you run a desktop build. You can safely remove these lines because all they do is adding a line the build log if you are using Team Buid.
来源:https://stackoverflow.com/questions/4620439/tfs-2010-code-metrics-integration-automated-builds-fail-code-metrics-dont-run