Treat all warnings as errors
MSBuild warnings (all start with MSB*) as opposed to CSC warnings cannot be suppressed nor promoted to errors. For the reason the ResolveAssemblyReference
task prints its messages on the fly and does not aggregate any of them.
The only feasible solution is reading the MSBuild log files created during the TFS build.
I think the most elegant solution is to implement a custom Build CodeActivity
. The following is a simple activity that will output to results any files containing a given SearchString
:
using System;
using System.Activities;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;
namespace MyBuildActivities.FileSystem
{
[BuildActivity(HostEnvironmentOption.Agent)]
public sealed class ReadStringFromFile : CodeActivity
{
[RequiredArgument]
public InArgument<IEnumerable<string>> Files { get; set; }
[RequiredArgument]
public InArgument<string> SearchString { get; set; }
public OutArgument<string> Result { get; set; }
protected override void Execute(CodeActivityContext context)
{
var files = context.GetValue(Files);
var searchString = context.GetValue(SearchString);
var list =
(files.Where(file => File.ReadAllText(file).Contains(searchString))
.Select(file => string.Format("{0} was found at {1}", searchString, file))).ToList();
if(list.Count > 0)
Result.Set(context, string.Join(Environment.NewLine, list));
}
}
}
Declared in the build process template like so:
xmlns:cfs="clr-namespace:MyBuildActivities.FileSystem;assembly=MyBuildActivities"
Invoked just at the end of the Compile and Test for Configuration
sequence:
<Sequence DisplayName="Handle MSBuild Errors">
<Sequence.Variables>
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="logFiles" />
<Variable x:TypeArguments="x:String" Name="readStringFromFileResult" />
</Sequence.Variables>
<mtbwa:FindMatchingFiles DisplayName="Find Log Files" MatchPattern="[String.Format("{0}\**\*.log", logFileDropLocation)]" Result="[logFiles]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<cfs:ReadStringFromFile Files="[logFiles]" SearchString="MSB3245" Result="[readStringFromFileResult]" />
<mtbwa:WriteBuildMessage DisplayName="Write Result" Message="[readStringFromFileResult]" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" />
<If Condition="[readStringFromFileResult.Count > 0]" DisplayName="If SearchString Was Found" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Throw DisplayName="Throw Exception" Exception="[New Exception(readStringFromFileResult)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
</Sequence>
I've tested this on TFS 2012 though it should work for TFS 2010 as well.
MSBuild 15 now supports a /warnaserror
flag, which forces MSBuild warnings to be treated as errors.
MSBuild 15 is intalled with Visual Studio 2017 but can also be downloaded from GitHub
This GitHub issue explains why it cannot be set via an MSBuild property (tl;dr a property is too late)