From 26343cae513fff64795f3bbba3667ed68e767d99 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 2e39ad0f6d5aa9a0a2e44edf1a1019aba530efd7 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 0465e6a668d253fd1d9ea84470b53fcc6acd3389 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 ea2f6731cb8978445090c59c28a41486429387b0 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 7791c62845bc96ee47f92b445dca2000341de549 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 a2f61ea4046087fb2dc13a780340ee5999ff819d 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 0d67d3ad6e5c159b9a0c5e8cc9706c2aa749282a 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); } }