I am running msbuild nunit task from extension pack that has 1 test which fails:
<Target Name="Tests">
<MSBuild.ExtensionPack.CodeQuality.NUnit
Assemblies="$(DropsDir)\$(Configuration)\$(TestPrj)\$(TestPrj).dll"
ToolPath="$(NUnitPath)"
ContinueOnError="False">
<Output TaskParameter="Total" PropertyName="ResultTotal"/>
<Output TaskParameter="NotRun" PropertyName="ResultNotRun"/>
<Output TaskParameter="Failures" PropertyName="ResultFailures"/>
<Output TaskParameter="Errors" PropertyName="ResultErrors"/>
<Output TaskParameter="Inconclusive" PropertyName="ResultInconclusive"/>
<Output TaskParameter="Ignored" PropertyName="ResultIgnored"/>
<Output TaskParameter="Skipped" PropertyName="ResultSkipped"/>
<Output TaskParameter="Invalid" PropertyName="ResultInvalid"/>
</MSBuild.ExtensionPack.CodeQuality.NUnit>
</Target>
output:
How can I prevent the next target to be executed? "Zip-Projects" ?
I am using MSBuild.Extension.Pack.March.2015.zip and framework 4.0
I solved it using an Error task and reading both output variables ResultErrors and ResultFailures.
<Error Condition="$(ResultErrors) > 0 Or $(ResultFailures) > 0" Text="Unit Tests didn't pass *****" />
You don't mention what version of the MSBuildExtensionPack you're using, but looking at the source for Trunk (Line 278) It looks like you need to specify The FailOnFailures Property in order to get their failure detection to work.
Therefore
<Target Name="Tests">
<MSBuild.ExtensionPack.CodeQuality.NUnit
Assemblies="$(DropsDir)\$(Configuration)\$(TestPrj)\$(TestPrj).dll"
ToolPath="$(NUnitPath)"
FailOnFailures="True"
ContinueOnError="False">
<Output TaskParameter="Total" PropertyName="ResultTotal"/>
<Output TaskParameter="NotRun" PropertyName="ResultNotRun"/>
<Output TaskParameter="Failures" PropertyName="ResultFailures"/>
<Output TaskParameter="Errors" PropertyName="ResultErrors"/>
<Output TaskParameter="Inconclusive" PropertyName="ResultInconclusive"/>
<Output TaskParameter="Ignored" PropertyName="ResultIgnored"/>
<Output TaskParameter="Skipped" PropertyName="ResultSkipped"/>
<Output TaskParameter="Invalid" PropertyName="ResultInvalid"/>
</MSBuild.ExtensionPack.CodeQuality.NUnit>
</Target>
Related
I have a property in an MSBuild project which is a semicolon-separated-list of string values. How can I test if the list constains a particular value?
In the example listing below, I want the target DeployToServer only to be executed if the property $(DCC_Define) constains 'WebDeploy'.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DCC_Define>WebDeploy;DEBUG</DCC_Define>
</PropertyGroup>
<Target Name="DeployToServer" Condition="$(DCC_Define) constains 'WebDeploy'">
<Message Text="Do something." />
</Target>
</Project>
I've used a bit of pseudo logic in the #Condition attribute to indicate what I mean. I am using a .NET framework version of 2.0.50727.3655; and MSBuild version of 3.4.30729.1 .
How can I achieve this? I don't have the luxury of being able to upgrade to MSBuild 4.
Well, since you can't use property function you have to get creative.
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DCC_Define>WebDeploy;DEBUG;WebDeploy</DCC_Define>
</PropertyGroup>
<Target Name="DeployToServer">
<CreateItem Include="$(DCC_Define)">
<Output TaskParameter="Include" ItemName="DCC_Define" />
</CreateItem>
<!-- Not required since MSBuild doesn't execute targets twice -->
<!-- <CreateProperty Value="True" Condition="%(DCC_Define.Identity) == WebDeploy">
<Output TaskParameter="Value" PropertyName="WebDeploy" />
</CreateProperty> -->
<CallTarget Targets="_DeployToServer" Condition="%(DCC_Define.Identity) == WebDeploy" />
</Target>
<Target Name="_DeployToServer">
<Message Text="Do something." />
</Target>
</Project>
I want the $(fooAssemblyInfo.Version) to work in my BuildRepositoryZip task but it aint. Why? Do I have to move out the ItemName or something out of Target assemblyversion and in that case how is that done?
<Target Name="AssemblyVersion">
<GetAssemblyIdentity AssemblyFiles="..\Tools\Utility.dll">
<Output TaskParameter="Assemblies" ItemName="fooAssemblyInfo"/>
</GetAssemblyIdentity>
<Message Text="%(fooAssemblyInfo.Version)" />
</Target>
<!-- Zipping all *.zip to a package for repository server-->
<Target Name="BuildRepositoryZip" DependsOnTargets="AssemblyVersion">
<!-- Create a zip file based on a Path -->
<MSBuild.ExtensionPack.Compression.Zip TaskAction="Create" CompressPath="..\..\Deploy\*.zip" ZipFileName="..\..\$(fooAssemblyInfo.Version).zip"/>
</Target>
I have some msbuild code that looks something like this:
<Target Name="Build">
<MSBuild
Projects="#(UnitTestProject)"
Properties="$(BuildProperties)">
<Output TaskParameter="TargetOutputs" ItemName="TestAssembly" />
</MSBuild>
</Target>
<Target Name="Test" DependsOnTargets="Build">
<ItemGroup>
<TestAssembly Remove="*.Example.dll" />
</ItemGroup>
<xunit Assemblies="#(TestAssembly)" />
</Target>
So I am building all of my unit test projects and caputuring the built dll's using the Output task on the TargetOutputs parameter. The problem is that one of the projects is calling a task that outputs some dll's that I don't want to actually run xunit against.
What's weird though is that the Remove="*.Example.dll" appears to not have any affect at all and xunit is trying to test the assembly anyway.
Why is Remove not working?
Actually I think I figured it out. It appears that the problem resides in the way the relative path is resolved in ItemGroups in the Target vs. outside of a Target. I need to be a little more explicit with my path and then it works. Basically I did this to get it to work:
<Target Name="Build">
<MSBuild
Projects="#(UnitTestProject)"
Properties="$(BuildProperties)">
<Output TaskParameter="TargetOutputs" ItemName="UnitTestOutput" />
</MSBuild>
<ItemGroup>
<TestAssembly Include="#(UnitTestOutput)" Exclude="$(RootTestPath)\**\*.Example.dll" />
</Target>
<Target Name="Test" DependsOnTargets="Build">
<xunit Assemblies="#(TestAssembly)" />
</Target>
I am creating a buildscript, where I'm outputting the TargetOutputs of an MSBuild, then wanting to call FXCop in a separate target, and using those outputs in the TargetAssemblies.
<Target Name="Build">
<MSBuild Projects="#(Projects)"
Properties="Platform=$(Platform);Configuration=$(Configuration);"
Targets="Build"
ContinueOnError="false">
<Output TaskParameter="TargetOutputs" ItemName="TargetDLLs"/>
</MSBuild>
<CallTarget Targets="FxCopReport" />
</Target>
<Target Name="FxCopyReport">
<Message Text="FXCop assemblies to test: #(TargetDLLs)" />
<FxCop
ToolPath="$(FXCopToolPath)"
RuleLibraries="#(FxCopRuleAssemblies)"
AnalysisReportFileName="FXCopReport.html"
TargetAssemblies="#(TargetDLLs)"
OutputXslFileName="$(FXCopToolPath)\Xml\FxCopReport.xsl"
ApplyOutXsl="True"
FailOnError="False" />
</Target>
When I run this, in the FxCopyReport target, the Message of TargetDLLs in empty, whereas if I put this in the Build target, it populates.
How can I pass/reference this value?
There is a blog post by Sayed Ibrahim Hashimi (co-author of Inside MSBuild book), describing the issue you ran into, dating back in 2005. Essentially CallTarget task is behaving weird. I'm not sure if it is a bug or designed behavior, but the behavior is still the same in MSBuild 4.0.
As a workaround, use normal MSBuild mechanism of setting order of execution of targets in MSBuild, using attributes DependsOnTargets, BeforeTargets or AfterTargets.
I was able to figure this one out.
Essentially, after the MSBuild step, I created an ItemGroup, which I then referenced in the calling Target.
<Target Name="Build">
<Message Text="Building Solution Projects: %(Projects.FullPath)" />
<MSBuild Projects="#(Projects)"
Properties="Platform=$(Platform);Configuration=$(Configuration);"
Targets="Build"
ContinueOnError="false">
<Output TaskParameter="TargetOutputs" ItemName="TargetDllOutputs"/>
</MSBuild>
<ItemGroup>
<TestAssemblies Include="#(TargetDllOutputs)" />
</ItemGroup>
</Target>
<Target Name="FXCopReport">
<Message Text="FXCop assemblies to test: #(TestAssemblies)" />
<FxCop
ToolPath="$(FXCopToolPath)"
RuleLibraries="#(FxCopRuleAssemblies)"
AnalysisReportFileName="$(BuildPath)\$(FxCopReportFile)"
TargetAssemblies="#(TestAssemblies)"
OutputXslFileName="$(FXCopToolPath)\Xml\FxCopReport.xsl"
Rules="$(FxCopExcludeRules)"
ApplyOutXsl="True"
FailOnError="True" />
<Message Text="##teamcity[importData id='FxCop' file='$(BuildPath)\$(FxCopReportFile)']" Condition="'$(TEAMCITY_BUILD_PROPERTIES_FILE)' != ''" />
</Target>
How can I stop or continue a build, based on user input, using MSBuild?
I currently have this in my project file:
<Target Name="Afterbuild">
<MSBuild.ExtensionPack.UI.Dialog TaskAction="Confirm" Title="Production Deployment" Button1Text="Continue" Button2Text="Cancel" Text="WARNING !!! You are about to overwrite code on the prodution server. Please confirm!">
<Output TaskParameter="ButtonClickedText" PropertyName="Clicked"/>
</MSBuild.ExtensionPack.UI.Dialog>
<Message Text="User Clicked: $(Clicked)"/>
<Message Text="User Typed: $(Typed)"/>
</Target>
I am unsure of how to proceed.
You could use the error task with a condition :
<Target Name="Afterbuild">
<MSBuild.ExtensionPack.UI.Dialog TaskAction="Confirm" Title="Production Deployment" Button1Text="Continue" Button2Text="Cancel" Text="WARNING !!! You are about to overwrite code on the prodution server. Please confirm!">
<Output TaskParameter="ButtonClickedText" PropertyName="Clicked"/>
</MSBuild.ExtensionPack.UI.Dialog>
<Error Condition="'$(Clicked)' == 'Cancel'"
Text="Build have been canceled by user"/>
<CallTarget Condition="'$(Clicked)' == 'Continue'"
Targets="ContinueBuild"
Text="Proceed with build"/>
</Target>