private void PostAnalyzeBuild(Build build) { if (!build.Succeeded) { build.AddChild(new Error { Text = "Build failed." }); } else { build.AddChild(new Item { Text = "Build succeeded." }); } build.AddChild(new Property { Name = "Duration", Value = build.DurationText }); doubleWritesAnalyzer.AppendDoubleWritesFolder(build); resolveAssemblyReferenceAnalyzer.AppendFinalReport(build); if (build.LogFilePath != null) { build.AddChildAtBeginning(new Item { Text = build.LogFilePath }); } var durations = taskDurations .OrderByDescending(kvp => kvp.Value) .Where(kvp => // no need to include MSBuild and CallTarget tasks as they are not "terminal leaf" tasks !string.Equals(kvp.Key, "MSBuild", StringComparison.OrdinalIgnoreCase) && !string.Equals(kvp.Key, "CallTarget", StringComparison.OrdinalIgnoreCase)) .Take(10) .ToArray(); if (durations.Length > 0) { var top10Tasks = build.GetOrCreateNodeWithName <Folder>($"Top {durations.Count()} most expensive tasks"); foreach (var kvp in durations) { top10Tasks.AddChild(new Item { Name = kvp.Key, Text = TextUtilities.DisplayDuration(kvp.Value) }); } } if (analyzerReports.Count > 0) { var analyzerReportSummary = build.GetOrCreateNodeWithName <Folder>($"Analyzer Summary"); CscTaskAnalyzer.CreateMergedReport(analyzerReportSummary, analyzerReports.ToArray()); } }