vault/tools/pipeline/internal/pkg/github/workflow_run_summary.go
Vault Automation 0c6c13dd38
license: update headers to IBM Corp. (#10229) (#10233)
* license: update headers to IBM Corp.
* `make proto`
* update offset because source file changed

Signed-off-by: Ryan Cragun <me@ryan.ec>
Co-authored-by: Ryan Cragun <me@ryan.ec>
2025-10-21 15:20:20 -06:00

123 lines
2.8 KiB
Go

// Copyright IBM Corp. 2016, 2025
// SPDX-License-Identifier: BUSL-1.1
package github
import (
"bytes"
"errors"
"slices"
"strings"
"text/template"
)
// workflowRunTemplate is our template for rendering workflow runs in human
// readable text.
var workflowRunTemplate = template.Must(template.New("workflow-run-text.tmpl").Funcs(template.FuncMap{
"boldify": boldify,
"format_log_lines": formatLogLines,
"intensify_status": intensifyStatus,
"intensify_annotation": intensifyAnnotationLevel,
"redify": redify,
"splitlines": splitLines,
}).ParseFS(templates, "templates/workflow-run-text.tmpl"))
func summarizeWorkflowRun(r *WorkflowRun) (string, error) {
if r == nil {
return "", errors.New("uninitialized workflow run")
}
if r.summary != "" {
return r.summary, nil
}
b := &bytes.Buffer{}
err := workflowRunTemplate.Execute(b, r)
if err != nil {
return "", err
}
r.summary = b.String()
return r.summary, nil
}
func formatLogLines(log []byte) []string {
if len(log) == 0 {
return nil
}
lines := []string{}
lastLine := ""
for _, line := range strings.Split(string(log), "\n") {
// Strip out duplicate lines and blank lines so the summaries
// are more clear. Log lines include timestamps with microseconds
// so we compare for duplicates by comparing line values without
// the timestamp.
newLineNoTimestamp := ""
newLineParts := strings.SplitN(line, " ", 2)
if len(newLineParts) < 2 {
// blank lines may only have a timestamp
continue
}
newLineNoTimestamp = newLineParts[1]
if strings.TrimSpace(newLineNoTimestamp) == "" {
// Don't write otherwise blank lines
continue
}
if lastLine == newLineNoTimestamp {
continue
}
lines = append(lines, line)
lastLine = newLineNoTimestamp
}
return lines
}
func intensifyStatus(in string) string {
switch in {
case "completed", "success":
return "\x1b[1;32;49m" + in + "\x1b[0m"
case "cancelled":
return "\x1b[1;33;49m" + in + "\x1b[0m"
case "failure":
return "\x1b[1;31;49m" + in + "\x1b[0m"
case "skipped":
return "\x1b[1;37;49m" + in + "\x1b[0m"
case "in_progress":
return "\x1b[1;37;49m" + in + "\x1b[0m"
case "warning":
return "\x1b[1;33;49m" + in + "\x1b[0m"
default:
return in
}
}
func intensifyAnnotationLevel(in string) string {
switch in {
case "failure":
return "\x1b[1;31;49m" + in + "\x1b[0m"
case "warning":
return "\x1b[1;33;49m" + in + "\x1b[0m"
default:
return in
}
}
func boldify(in string) string {
return "\x1b[1;39m" + in + "\x1b[0m"
}
func redify(in string) string {
return "\x1b[1;31m" + in + "\x1b[0m"
}
func splitLines(in string) []string {
return slices.DeleteFunc(strings.Split(in, "\n"), func(s string) bool {
if s == "\n" || s == "" {
return true
}
return false
})
}