diff --git a/test/SharedFx.UnitTests/ConsoleReporter.cs b/test/SharedFx.UnitTests/ConsoleReporter.cs
new file mode 100644
index 0000000000..190e805dc2
--- /dev/null
+++ b/test/SharedFx.UnitTests/ConsoleReporter.cs
@@ -0,0 +1,71 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using McMaster.Extensions.CommandLineUtils;
+
+namespace Microsoft.Extensions.Tools.Internal
+{
+ public class ConsoleReporter : IReporter
+ {
+ private object _writeLock = new object();
+
+ public ConsoleReporter(IConsole console)
+ : this(console, verbose: false, quiet: false)
+ { }
+
+ public ConsoleReporter(IConsole console, bool verbose, bool quiet)
+ {
+ Console = console;
+ IsVerbose = verbose;
+ IsQuiet = quiet;
+ }
+
+ protected IConsole Console { get; }
+ public bool IsVerbose { get; }
+ public bool IsQuiet { get; }
+
+ protected virtual void WriteLine(TextWriter writer, string message, ConsoleColor? color)
+ {
+ lock (_writeLock)
+ {
+ if (color.HasValue)
+ {
+ Console.ForegroundColor = color.Value;
+ }
+
+ writer.WriteLine(message);
+
+ if (color.HasValue)
+ {
+ Console.ResetColor();
+ }
+ }
+ }
+
+ public virtual void Error(string message)
+ => WriteLine(Console.Error, message, ConsoleColor.Red);
+ public virtual void Warn(string message)
+ => WriteLine(Console.Out, message, ConsoleColor.Yellow);
+
+ public virtual void Output(string message)
+ {
+ if (IsQuiet)
+ {
+ return;
+ }
+ WriteLine(Console.Out, message, color: null);
+ }
+
+ public virtual void Verbose(string message)
+ {
+ if (!IsVerbose)
+ {
+ return;
+ }
+
+ WriteLine(Console.Out, message, ConsoleColor.DarkGray);
+ }
+ }
+}
diff --git a/test/SharedFx.UnitTests/RetryHelper.cs b/test/SharedFx.UnitTests/RetryHelper.cs
new file mode 100644
index 0000000000..2d92113e36
--- /dev/null
+++ b/test/SharedFx.UnitTests/RetryHelper.cs
@@ -0,0 +1,65 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Threading.Tasks;
+using McMaster.Extensions.CommandLineUtils;
+
+namespace TriageBuildFailures
+{
+ internal static class RetryHelpers
+ {
+ ///
+ /// Constrain the exponential back-off to this many minutes.
+ ///
+ private const int MaxRetryMinutes = 15;
+
+ private static int TotalRetriesUsed;
+
+ public static int GetTotalRetriesUsed()
+ {
+ return TotalRetriesUsed;
+ }
+
+ public static async Task RetryAsync(Func action, IReporter reporter)
+ {
+ await RetryAsync