Skip to content

CI output: Spectre markup in log messages renders as literal text #2620

@thomhurst

Description

@thomhurst

Symptom

In GitHub Actions logs (e.g. run 25762828216, job 75668091053), many module completion lines look like:

[INFO ] [green]✓[/] Module [cyan]FindProjectsModule[/] completed successfully
[INFO ] [green]✓[/] Module [cyan]PrintEnvironmentVariablesModule[/] completed successfully
[INFO ] [green]✓[/] Module [cyan]NugetVersionGeneratorModule[/] completed successfully

The [green]✓[/] / [cyan]…[/] Spectre markup is being printed verbatim instead of rendered.

Cause

Producer code calls e.g.:

_logger.LogInformation("[green]✓[/] Module [cyan]{Name}[/] completed successfully", moduleName);

MEL.Spectre's message formatter (correctly, by default) treats the message template as literal text and escapes [ / ] so untrusted content can't break out into Spectre markup. The producer's embedded markup is therefore escaped rather than rendered.

Resolution

Once thomhurst/Spectre.MEL#2 lands and a new MEL.Spectre version is published, ModularPipelines can opt in:

services.AddLogging(b => b.AddSpectreConsole(o =>
{
    o.AllowMarkupInMessageTemplate = true;
}));

That makes [green]…[/] pass through to the renderer while still escaping placeholder values.

Alternative (preferred long-term)

Refactor to use semantic placeholders rather than literal markup tokens, e.g.:

_logger.LogInformation("{Status} Module {Name} completed", "✓", moduleName);

Then style via SpectreTheme.Placeholders.ForName("Status", new Style(Color.Green)) etc. Removes coupling between application code and a specific console renderer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions