在 TFS 2010 中的自动化团队构建之后,我正在尝试添加一个自动构建后触发器来运行 NDepend(代码度量软件)。
NDepend 的网站提供了用于集成此功能的代码,因此我已将他们的代码粘贴到我的 .csproj 文件中,他们说要这样做,但我在构建时收到错误消息。
这些错误指的是我在代码片段中拥有的三个“BuildStep”标签中的两个。以下两个片段给了我错误:
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Message="Running NDepend analysis">
<Output TaskParameter="Id" PropertyName="StepId" />
</BuildStep>
和
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Failed" />
但是,此代码段不会引发任何问题:
<BuildStep
TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
BuildUri="$(BuildUri)"
Id="$(StepId)"
Status="Succeeded" />
我只是不明白为什么一个工作正常而几乎相同布局的 BuildStep 标签却不能。我只是忽略了一些简单的事情吗?
编辑:如果这有所不同,这就是它的外观:
<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>
编辑:增加了赏金,因为我真的需要为我的团队做这件事。
编辑:包含有关错误的更多细节,出于版权原因,我用“blah”伪装了文件的位置/名称,我不确定我在技术上是否能够发布该信息,所以我犯了错误安全而不是抱歉,但如果为了解决这个问题你绝对必须知道,我会看看我能做些什么。以下错误列在失败的团队构建结果以及各种其他警告中,但这些错误是我能看到的与上面的 NDepend XML 代码有关的唯一错误。
运行团队构建时遇到的错误:
C:*Blah*.csproj (172):未找到“BuildStep”任务。检查以下内容: 1.) 项目文件中的任务名称与任务类的名称相同。2.) 任务类是“公共的”并且实现了 Microsoft.Build.Framework.ITask 接口。3.) 在项目文件或位于“c:\Windows\Microsoft.NET\Framework\v4.0.30319”目录中的 *.tasks 文件中正确声明了任务。
和
C:*Blah*.csproj (194):未找到“BuildStep”任务。检查以下内容: 1.) 项目文件中的任务名称与任务类的名称相同。2.) 任务类是“公共的”并且实现了 Microsoft.Build.Framework.ITask 接口。3.) 在项目文件或位于“c:\Windows\Microsoft.NET\Framework\v4.0.30319”目录中的 *.tasks 文件中正确声明了任务。
编辑:我以为我运行得很好,但它没有正确构建。尽管在下面模仿@Ewald 建议的 XML,但在我构建时它仍然会抛出上面的错误。我根据我认为应该工作的方式调整了所述代码的属性值,如下所示:
<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>
但是,我确实尝试将这段代码放入:
<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>
并且自动构建运行良好,没有错误,但 NDepend 并没有像预期的那样运行。
我开始怀疑(在咨询了各种其他子问题后)TFS2010 与 TFS2008 中使用的 XML 模式是否存在一些细微的差异,导致我遇到这些问题。那么,考虑到这一点,有没有人知道这些模式中的任何重大差异?
编辑:只是让大家了解我尝试过的所有内容,我现在尝试了以下代码:
<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>
它产生了不同的错误消息,如下所示:
C:*Blah*.csproj (179): 命令 ""c:\tools\NDepend\NDepend.console.exe" "C:*Blah*\Sources\Main\MyProject.ndproj" /OutDir "C:*Blah *\Binaries\Debug\NDepend" /InDirs "C:*Blah*\Binaries\Debug\"" 以代码 1 退出。
编辑:我试过的最新代码。这是(根据 NDepend 的网站)“内置的 NDepend MSBuild 任务”。
<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>
但我得到这个错误:
C:*Blah*.csproj (180):元素下面的元素无法识别。