From e250adfa9284d6b083e5e0b21229bafb969e5351 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:28:42 +0000 Subject: [PATCH 1/7] Initial plan From 55a172457d426295b5786f8f0baeb3e64054f866 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:40:35 +0000 Subject: [PATCH 2/7] Add help message when pipeline fails - Modified ConsoleActivityLogger to accept optional commandName in SetFinalResult - Display help message when pipeline fails with command name - Updated PipelineCommandBase to pass command name to logger Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- src/Aspire.Cli/Commands/PipelineCommandBase.cs | 2 +- src/Aspire.Cli/Utils/ConsoleActivityLogger.cs | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Aspire.Cli/Commands/PipelineCommandBase.cs b/src/Aspire.Cli/Commands/PipelineCommandBase.cs index b8f7a14e211..475807b13c6 100644 --- a/src/Aspire.Cli/Commands/PipelineCommandBase.cs +++ b/src/Aspire.Cli/Commands/PipelineCommandBase.cs @@ -621,7 +621,7 @@ var cs when IsCompletionStateWarning(cs) => ConsoleActivityLogger.ActivityState. logger.SetStepDurations(durationRecords); // Provide final result to logger and print its structured summary. - logger.SetFinalResult(!hasErrors); + logger.SetFinalResult(!hasErrors, this.Name); logger.WriteSummary(); // Visual bell diff --git a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs index db66fd54475..18cdb47e3d4 100644 --- a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs +++ b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs @@ -252,6 +252,15 @@ public void WriteSummary() if (!string.IsNullOrEmpty(_finalStatusHeader)) { AnsiConsole.MarkupLine(_finalStatusHeader!); + + // If pipeline failed, show help message about using --log-level debug + if (_finalStatusHeader.Contains("PIPELINE FAILED") && !string.IsNullOrEmpty(_commandName)) + { + var helpMessage = _enableColor + ? $"[dim]For more details, re-run with: aspire {_commandName} --log-level debug[/]" + : $"For more details, re-run with: aspire {_commandName} --log-level debug"; + AnsiConsole.MarkupLine(helpMessage); + } } AnsiConsole.MarkupLine(line); AnsiConsole.WriteLine(); // Ensure final newline after deployment summary @@ -259,13 +268,15 @@ public void WriteSummary() } private string? _finalStatusHeader; + private string? _commandName; /// /// Sets the final deployment result lines to be displayed in the summary (e.g., DEPLOYMENT FAILED ...). /// Optional usage so existing callers remain compatible. /// - public void SetFinalResult(bool succeeded) + public void SetFinalResult(bool succeeded, string? commandName = null) { + _commandName = commandName; // Always show only a single final header line with symbol; no per-step duplication. if (succeeded) { From e8bed6c0cd5924575a2e1ba847bd2d88a9c780a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:49:46 +0000 Subject: [PATCH 3/7] Use boolean field instead of string Contains check Store the succeeded value from SetFinalResult in _pipelineSucceeded field and use !_pipelineSucceeded instead of checking if string contains "PIPELINE FAILED" Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- src/Aspire.Cli/Utils/ConsoleActivityLogger.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs index 18cdb47e3d4..bea9555d0ba 100644 --- a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs +++ b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs @@ -254,7 +254,7 @@ public void WriteSummary() AnsiConsole.MarkupLine(_finalStatusHeader!); // If pipeline failed, show help message about using --log-level debug - if (_finalStatusHeader.Contains("PIPELINE FAILED") && !string.IsNullOrEmpty(_commandName)) + if (!_pipelineSucceeded && !string.IsNullOrEmpty(_commandName)) { var helpMessage = _enableColor ? $"[dim]For more details, re-run with: aspire {_commandName} --log-level debug[/]" @@ -269,6 +269,7 @@ public void WriteSummary() private string? _finalStatusHeader; private string? _commandName; + private bool _pipelineSucceeded; /// /// Sets the final deployment result lines to be displayed in the summary (e.g., DEPLOYMENT FAILED ...). @@ -276,6 +277,7 @@ public void WriteSummary() /// public void SetFinalResult(bool succeeded, string? commandName = null) { + _pipelineSucceeded = succeeded; _commandName = commandName; // Always show only a single final header line with symbol; no per-step duplication. if (succeeded) From a2313fd8432bcce2642a5bb7903043edbbad7dc6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 22:56:02 +0000 Subject: [PATCH 4/7] Pass command name in ConsoleActivityLogger constructor Move command name from SetFinalResult parameter to constructor parameter. This is cleaner since the command name doesn't change throughout the lifecycle of the logger. Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- src/Aspire.Cli/Commands/PipelineCommandBase.cs | 4 ++-- src/Aspire.Cli/Utils/ConsoleActivityLogger.cs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Aspire.Cli/Commands/PipelineCommandBase.cs b/src/Aspire.Cli/Commands/PipelineCommandBase.cs index 475807b13c6..cfcfcc49340 100644 --- a/src/Aspire.Cli/Commands/PipelineCommandBase.cs +++ b/src/Aspire.Cli/Commands/PipelineCommandBase.cs @@ -410,7 +410,7 @@ public async Task ProcessAndDisplayPublishingActivitiesAsync(IAsyncEnumera { var stepCounter = 1; var steps = new Dictionary(); - var logger = new ConsoleActivityLogger(_hostEnvironment); + var logger = new ConsoleActivityLogger(_hostEnvironment, commandName: this.Name); logger.StartSpinner(); PublishingActivity? publishingActivity = null; @@ -621,7 +621,7 @@ var cs when IsCompletionStateWarning(cs) => ConsoleActivityLogger.ActivityState. logger.SetStepDurations(durationRecords); // Provide final result to logger and print its structured summary. - logger.SetFinalResult(!hasErrors, this.Name); + logger.SetFinalResult(!hasErrors); logger.WriteSummary(); // Visual bell diff --git a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs index bea9555d0ba..801485ada2b 100644 --- a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs +++ b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs @@ -18,6 +18,7 @@ internal sealed class ConsoleActivityLogger { private readonly bool _enableColor; private readonly ICliHostEnvironment _hostEnvironment; + private readonly string? _commandName; private readonly object _lock = new(); private readonly Stopwatch _stopwatch = Stopwatch.StartNew(); private readonly Dictionary _stepColors = new(); @@ -43,10 +44,11 @@ internal sealed class ConsoleActivityLogger private const string InProgressSymbol = "→"; private const string InfoSymbol = "i"; - public ConsoleActivityLogger(ICliHostEnvironment hostEnvironment, bool? forceColor = null) + public ConsoleActivityLogger(ICliHostEnvironment hostEnvironment, bool? forceColor = null, string? commandName = null) { _hostEnvironment = hostEnvironment; _enableColor = forceColor ?? _hostEnvironment.SupportsAnsi; + _commandName = commandName; // Disable spinner in non-interactive environments if (!_hostEnvironment.SupportsInteractiveOutput) @@ -268,17 +270,15 @@ public void WriteSummary() } private string? _finalStatusHeader; - private string? _commandName; private bool _pipelineSucceeded; /// /// Sets the final deployment result lines to be displayed in the summary (e.g., DEPLOYMENT FAILED ...). /// Optional usage so existing callers remain compatible. /// - public void SetFinalResult(bool succeeded, string? commandName = null) + public void SetFinalResult(bool succeeded) { _pipelineSucceeded = succeeded; - _commandName = commandName; // Always show only a single final header line with symbol; no per-step duplication. if (succeeded) { From d8a8b60af3cfef85640a153b1ba6d514b4594cfc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Nov 2025 23:06:21 +0000 Subject: [PATCH 5/7] Make commandName non-nullable in ConsoleActivityLogger The commandName parameter is always provided from PipelineCommandBase.Name and should never be null. Changed constructor signature to make it a required parameter and removed null checks. Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- src/Aspire.Cli/Commands/PipelineCommandBase.cs | 2 +- src/Aspire.Cli/Utils/ConsoleActivityLogger.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Aspire.Cli/Commands/PipelineCommandBase.cs b/src/Aspire.Cli/Commands/PipelineCommandBase.cs index cfcfcc49340..a695738e217 100644 --- a/src/Aspire.Cli/Commands/PipelineCommandBase.cs +++ b/src/Aspire.Cli/Commands/PipelineCommandBase.cs @@ -410,7 +410,7 @@ public async Task ProcessAndDisplayPublishingActivitiesAsync(IAsyncEnumera { var stepCounter = 1; var steps = new Dictionary(); - var logger = new ConsoleActivityLogger(_hostEnvironment, commandName: this.Name); + var logger = new ConsoleActivityLogger(_hostEnvironment, this.Name); logger.StartSpinner(); PublishingActivity? publishingActivity = null; diff --git a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs index 801485ada2b..382fb08106b 100644 --- a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs +++ b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs @@ -18,7 +18,7 @@ internal sealed class ConsoleActivityLogger { private readonly bool _enableColor; private readonly ICliHostEnvironment _hostEnvironment; - private readonly string? _commandName; + private readonly string _commandName; private readonly object _lock = new(); private readonly Stopwatch _stopwatch = Stopwatch.StartNew(); private readonly Dictionary _stepColors = new(); @@ -44,7 +44,7 @@ internal sealed class ConsoleActivityLogger private const string InProgressSymbol = "→"; private const string InfoSymbol = "i"; - public ConsoleActivityLogger(ICliHostEnvironment hostEnvironment, bool? forceColor = null, string? commandName = null) + public ConsoleActivityLogger(ICliHostEnvironment hostEnvironment, string commandName, bool? forceColor = null) { _hostEnvironment = hostEnvironment; _enableColor = forceColor ?? _hostEnvironment.SupportsAnsi; @@ -256,7 +256,7 @@ public void WriteSummary() AnsiConsole.MarkupLine(_finalStatusHeader!); // If pipeline failed, show help message about using --log-level debug - if (!_pipelineSucceeded && !string.IsNullOrEmpty(_commandName)) + if (!_pipelineSucceeded) { var helpMessage = _enableColor ? $"[dim]For more details, re-run with: aspire {_commandName} --log-level debug[/]" From 47810f2716459ab5b40eadb87509070a77a6daf1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 03:43:18 +0000 Subject: [PATCH 6/7] Reorganize fields for better maintainability Move _finalStatusHeader and _pipelineSucceeded fields to the top with other private fields for better organization and consistency. Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- src/Aspire.Cli/Utils/ConsoleActivityLogger.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs index 382fb08106b..136d4378674 100644 --- a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs +++ b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs @@ -36,6 +36,9 @@ internal sealed class ConsoleActivityLogger private readonly char[] _spinnerChars = ['|', '/', '-', '\\']; private int _spinnerIndex; + private string? _finalStatusHeader; + private bool _pipelineSucceeded; + // No raw ANSI escape codes; rely on Spectre.Console markup tokens. private const string SuccessSymbol = "✓"; @@ -269,9 +272,6 @@ public void WriteSummary() } } - private string? _finalStatusHeader; - private bool _pipelineSucceeded; - /// /// Sets the final deployment result lines to be displayed in the summary (e.g., DEPLOYMENT FAILED ...). /// Optional usage so existing callers remain compatible. From 44ca5e25b602516d664d15f98e65e5c3a71a50bb Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 2 Nov 2025 06:16:10 +0000 Subject: [PATCH 7/7] Update help message and suppress when debug/trace logging enabled - Changed message to generic "For more details, add --log-level debug/trace to the command." - Suppress help message when user already passed --log-level debug or trace - Replaced commandName parameter with isDebugOrTraceLoggingEnabled flag Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com> --- src/Aspire.Cli/Commands/PipelineCommandBase.cs | 11 ++++++++--- src/Aspire.Cli/Utils/ConsoleActivityLogger.cs | 14 +++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/Aspire.Cli/Commands/PipelineCommandBase.cs b/src/Aspire.Cli/Commands/PipelineCommandBase.cs index a695738e217..ba3b9f3f314 100644 --- a/src/Aspire.Cli/Commands/PipelineCommandBase.cs +++ b/src/Aspire.Cli/Commands/PipelineCommandBase.cs @@ -224,11 +224,16 @@ protected override async Task ExecuteAsync(ParseResult parseResult, Cancell var publishingActivities = backchannel.GetPublishingActivitiesAsync(cancellationToken); var debugMode = parseResult.GetValue("--debug") ?? false; + + // Check if debug or trace logging is enabled + var logLevel = parseResult.GetValue(_logLevelOption); + var isDebugOrTraceLoggingEnabled = logLevel?.Equals("debug", StringComparison.OrdinalIgnoreCase) == true || + logLevel?.Equals("trace", StringComparison.OrdinalIgnoreCase) == true; var noFailuresReported = debugMode switch { true => await ProcessPublishingActivitiesDebugAsync(publishingActivities, backchannel, cancellationToken), - false => await ProcessAndDisplayPublishingActivitiesAsync(publishingActivities, backchannel, cancellationToken), + false => await ProcessAndDisplayPublishingActivitiesAsync(publishingActivities, backchannel, isDebugOrTraceLoggingEnabled, cancellationToken), }; // Send terminal progress bar stop sequence @@ -406,11 +411,11 @@ public async Task ProcessPublishingActivitiesDebugAsync(IAsyncEnumerable

ProcessAndDisplayPublishingActivitiesAsync(IAsyncEnumerable publishingActivities, IAppHostBackchannel backchannel, CancellationToken cancellationToken) + public async Task ProcessAndDisplayPublishingActivitiesAsync(IAsyncEnumerable publishingActivities, IAppHostBackchannel backchannel, bool isDebugOrTraceLoggingEnabled, CancellationToken cancellationToken) { var stepCounter = 1; var steps = new Dictionary(); - var logger = new ConsoleActivityLogger(_hostEnvironment, this.Name); + var logger = new ConsoleActivityLogger(_hostEnvironment, isDebugOrTraceLoggingEnabled); logger.StartSpinner(); PublishingActivity? publishingActivity = null; diff --git a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs index 136d4378674..5143b0bd3f3 100644 --- a/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs +++ b/src/Aspire.Cli/Utils/ConsoleActivityLogger.cs @@ -18,7 +18,7 @@ internal sealed class ConsoleActivityLogger { private readonly bool _enableColor; private readonly ICliHostEnvironment _hostEnvironment; - private readonly string _commandName; + private readonly bool _isDebugOrTraceLoggingEnabled; private readonly object _lock = new(); private readonly Stopwatch _stopwatch = Stopwatch.StartNew(); private readonly Dictionary _stepColors = new(); @@ -47,11 +47,11 @@ internal sealed class ConsoleActivityLogger private const string InProgressSymbol = "→"; private const string InfoSymbol = "i"; - public ConsoleActivityLogger(ICliHostEnvironment hostEnvironment, string commandName, bool? forceColor = null) + public ConsoleActivityLogger(ICliHostEnvironment hostEnvironment, bool isDebugOrTraceLoggingEnabled = false, bool? forceColor = null) { _hostEnvironment = hostEnvironment; _enableColor = forceColor ?? _hostEnvironment.SupportsAnsi; - _commandName = commandName; + _isDebugOrTraceLoggingEnabled = isDebugOrTraceLoggingEnabled; // Disable spinner in non-interactive environments if (!_hostEnvironment.SupportsInteractiveOutput) @@ -258,12 +258,12 @@ public void WriteSummary() { AnsiConsole.MarkupLine(_finalStatusHeader!); - // If pipeline failed, show help message about using --log-level debug - if (!_pipelineSucceeded) + // If pipeline failed and not already in debug/trace mode, show help message about using --log-level debug + if (!_pipelineSucceeded && !_isDebugOrTraceLoggingEnabled) { var helpMessage = _enableColor - ? $"[dim]For more details, re-run with: aspire {_commandName} --log-level debug[/]" - : $"For more details, re-run with: aspire {_commandName} --log-level debug"; + ? "[dim]For more details, add --log-level debug/trace to the command.[/]" + : "For more details, add --log-level debug/trace to the command."; AnsiConsole.MarkupLine(helpMessage); } }