Skip to content

Commit

Permalink
AddPipelineGlobalHooks<GitHubMarkdownSummaryGenerator>
Browse files Browse the repository at this point in the history
  • Loading branch information
thomhurst committed Jul 14, 2024
1 parent d6beb4c commit 00a99b9
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/ModularPipelines.Build/ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
null
- GitHub Actions Markdown Summary - Thanks to @MattParkerDev !
2 changes: 2 additions & 0 deletions src/ModularPipelines.GitHub/Extensions/GitHubExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.Extensions.DependencyInjection.Extensions;
using ModularPipelines.Context;
using ModularPipelines.Engine;
using ModularPipelines.Extensions;

namespace ModularPipelines.GitHub.Extensions;

Expand All @@ -23,6 +24,7 @@ public static IServiceCollection RegisterGitHubContext(this IServiceCollection s
services.TryAddScoped<IGitHub, GitHub>();
services.TryAddScoped<IGitHubEnvironmentVariables, GitHubEnvironmentVariables>();
services.TryAddSingleton<IGitHubRepositoryInfo, GitHubRepositoryInfo>();
services.AddPipelineGlobalHooks<GitHubMarkdownSummaryGenerator>();
return services;
}

Expand Down
121 changes: 121 additions & 0 deletions src/ModularPipelines.GitHub/GitHubMarkdownSummaryGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using ModularPipelines.Context;
using ModularPipelines.Enums;
using ModularPipelines.Interfaces;
using ModularPipelines.Models;

namespace ModularPipelines.GitHub;

internal class GitHubMarkdownSummaryGenerator : IPipelineGlobalHooks
{
public Task OnStartAsync(IPipelineHookContext pipelineContext)
{
return Task.CompletedTask;
}

public async Task OnEndAsync(IPipelineHookContext pipelineContext, PipelineSummary pipelineSummary)
{
var mermaid = await GenerateMermaidSummary(pipelineSummary);
var table = await GenerateTableSummary(pipelineSummary);

var stepSummaryVariable = pipelineContext.Environment.EnvironmentVariables.GetEnvironmentVariable("GITHUB_STEP_SUMMARY");

if (string.IsNullOrEmpty(stepSummaryVariable))
{
return;
}

await pipelineContext.FileSystem.GetFile(stepSummaryVariable).WriteAsync($"{mermaid}\n\n{table}");
}

private async Task<string> GenerateMermaidSummary(PipelineSummary pipelineSummary)
{
var results = await pipelineSummary.GetModuleResultsAsync();

var stepStringList = results
.OrderBy(x => x.ModuleEnd)
.ThenBy(s => s.ModuleStart)
.Select(x =>
{
var (startTime, endTime) = (x.ModuleStart, x.ModuleEnd);
return $"{x.ModuleName} :{AddCritIfFailed(x)} {startTime:mm:ss:fff}, {endTime:mm:ss:fff}";
}).ToList();

var text = $"""
```mermaid
---
config:
theme: base
themeVariables:
primaryColor: "#007d15"
primaryTextColor: "#fff"
primaryBorderColor: "#02ad1e"
lineColor: "#F8B229"
secondaryColor: "#006100"
tertiaryColor: "#fff"
darkmode: "true"
titleColor: "#fff"
gantt:
leftPadding: 40
rightPadding: 120
---
gantt
dateFormat mm:ss:SSS
title Run Summary
axisFormat %M:%S
{string.Join("\n", stepStringList)}
```
""";

return text;
}

private async Task<string> GenerateTableSummary(PipelineSummary pipelineSummary)
{
var results = await pipelineSummary.GetModuleResultsAsync();

var stepStringList = results.OrderBy(x => x.ModuleEnd)
.ThenBy(s => s.ModuleStart)
.Select(stepContainer =>
{
var (startTime, endTime, duration) = (stepContainer.ModuleStart, stepContainer.ModuleEnd, stepContainer.ModuleDuration);
var text = $"| {stepContainer.ModuleName} | {GetStatusString(stepContainer.ModuleStatus)} | {startTime:HH:mm:ss} | {endTime:HH:mm:ss} | {duration} |";
return text;
}
).ToList();

var (globalStartTime, globalEndTime, globalDuration) = (pipelineSummary.Start, pipelineSummary.End, pipelineSummary.TotalDuration);
var pipelineStatusString = GetStatusString(pipelineSummary.Status);
var overallSummaryString = $"| **Total** | **{pipelineStatusString}** | **{globalStartTime:HH:mm:ss}** | **{globalEndTime:HH:mm:ss}** | **{globalDuration}** |";
var text = $"""
### Run Summary
| Step | Status | Start | End | Duration |
| --- | --- | --- | --- | --- |
{string.Join("\n", stepStringList)}
{overallSummaryString}
""";

return text;
}

private static string AddCritIfFailed(IModuleResult moduleResult)
{
return moduleResult.ModuleResultType is ModuleResultType.Failure
? "crit,"
: string.Empty;
}

private static string GetStatusString(Status status)
{
return status switch
{
Status.Successful or Status.UsedHistory => $$$"""${\textsf{\color{lightgreen}{{{status}}}}}$""",
Status.NotYetStarted or Status.IgnoredFailure or Status.Processing or Status.Skipped =>
$$$"""${\textsf{\color{orange}{{{status}}}}}$""",
Status.PipelineTerminated or Status.TimedOut or Status.Failed or Status.Unknown =>
$$$"""${\textsf{\color{red}{{{status}}}}}$""",
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
};
}
}

0 comments on commit 00a99b9

Please sign in to comment.