Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for a build activity which breaks a build when new warnings are introduced

We're attempting to clean up a big bunch of brown field code, while at the same time a team is adding new functionality. We'd like to make sure changed and new code is cleaned from any compiler/code analysis or other warnings, but there's too many of them to begin by cleaning up the current solution.

We're using TFS 2010.

So the following was proposed:

  • Write/select a build activity which compares the list of warnings in the build against the lines of code that changed with that check-in.
  • If the warning provides a line number, and that line number was changed, fail the build.

I understand this will not find all new warnings and things introduced in other parts of the code will not be flagged, but it's at least something.

Another option that was proposed:

  • Compare the list of warnings of the previous known good build against the list of this build. If there are new warnings (track on file name level), fail the build.

Any known Actions out there that might provide said functionality?

Any similar Actions that can act on Code Coverage reports?

like image 481
jessehouwing Avatar asked Mar 07 '12 18:03

jessehouwing


1 Answers

This following activity is just a basic approach, that returns false if your current build has less or equal warnings than your last build and true if they have risen.
Another activity that can locate new warnings and/or present with their location in code would clearly be superior, yet I thought this might be an interesting startpoint:

using System;
using System.Activities;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Workflow.Activities;

namespace CheckWarnings
{
    [BuildActivity(HostEnvironmentOption.Agent)]
    public sealed class CheckWarnings : CodeActivity<bool>
    {
        [RequiredArgument]
        public InArgument<IBuildDetail> CurrentBuild { get; set; }  //buildDetail
        public InArgument<string> Configuration { get; set; }       //platformConfiguration.Configuration
        public InArgument<string> Platform { get; set; }            //platformConfiguration.Platform


        protected override bool Execute(CodeActivityContext context)
        {
            IBuildDetail currentBuildDetail = context.GetValue(CurrentBuild);
            string currentConfiguration = context.GetValue(Configuration);
            string currentPlatform = context.GetValue(Platform);

            Uri lastKnownGoodBuildUri = currentBuildDetail.BuildDefinition.LastGoodBuildUri;
            IBuildDetail lastKnownGoodBuild = currentBuildDetail.BuildServer.GetBuild(lastKnownGoodBuildUri);

            int numOfCurrentWarnings = GetNumberOfWarnings(currentBuildDetail, currentConfiguration, currentPlatform);
            context.TrackBuildMessage("Current compile presents " + numOfCurrentWarnings + " warnings.", BuildMessageImportance.Normal);

            int numOfLastGoodBuildWarnings = GetNumberOfWarnings(lastKnownGoodBuild, currentConfiguration,
                                                                 currentPlatform);
            context.TrackBuildMessage("Equivalent last good build compile presents " + numOfLastGoodBuildWarnings + " warnings.", BuildMessageImportance.Normal);

            if (numOfLastGoodBuildWarnings < numOfCurrentWarnings)
            {
                return true;
            }
            return false;
        }

        private static int GetNumberOfWarnings(IBuildDetail buildDetail, string configuration, string platform)
        {
            var buildInformationNodes =
                buildDetail.Information.GetNodesByType("ConfigurationSummary");

            foreach (var buildInformationNode in buildInformationNodes)
            {
                string localPlatform, numOfWarnings;
                string localConfiguration = localPlatform = numOfWarnings = "";
                foreach (var field in buildInformationNode.Fields)
                {

                    if (field.Key == "Flavor")
                    {
                        localConfiguration = field.Value;
                    }
                    if (field.Key == "Platform")
                    {
                        localPlatform = field.Value;
                    }
                    if (field.Key == "TotalCompilationWarnings")
                    {
                        numOfWarnings = field.Value;
                    }
                }
                if(localConfiguration == configuration && localPlatform == platform)
                {
                    return Convert.ToInt32((numOfWarnings));
                }
            }
            return 0;
        }
    }
}

Note that this activity doesn't provide with exception handling and should further be refined, in case your build definitions build more than one solutions.

It takes three input args (buildDetail, platformConfiguration.Configuration and platformConfiguration.Platform) and should be placed directly after the Run MSBuild activity.

like image 181
pantelif Avatar answered Nov 11 '22 22:11

pantelif