Skip to content

Commit

Permalink
stripping ANSI codes from GitHub Action control messages (#4167)
Browse files Browse the repository at this point in the history
Fixes earthly/earthly#4131

GitHub Actions ::error and summary messages do not support ANSI control
characters such as colors.
  • Loading branch information
adamgordonbell authored May 28, 2024
1 parent 2131356 commit 31f93b5
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 7 deletions.
17 changes: 10 additions & 7 deletions logbus/formatter/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/earthly/earthly/util/deltautil"
"github.com/earthly/earthly/util/execstatssummary"
"github.com/earthly/earthly/util/progressbar"
"github.com/earthly/earthly/util/stringutil"
"github.com/hashicorp/go-multierror"
"github.com/mattn/go-isatty"
"github.com/pkg/errors"
Expand Down Expand Up @@ -483,21 +484,23 @@ func (f *Formatter) printGHAFailure() {

// Extract the error from first line of the error message
lines := strings.Split(failure.GetErrorMessage(), "\n")
var message string
var singleLineMessage string
if len(lines) > 1 {
message = strings.Join(strings.Fields(strings.Join(lines[1:], " ")), " ")
singleLineMessage = strings.Join(strings.Fields(strings.Join(lines[1:], " ")), " ")
} else {
message = strings.Join(strings.Fields(lines[0]), " ")
singleLineMessage = strings.Join(strings.Fields(lines[0]), " ")
}
singleLineMessage = stringutil.ScrubANSICodes(singleLineMessage)

// Print GHA Error with line info if available
if cm != nil && cm.SourceLocation != nil &&
cm.SourceLocation.File != "" && cm.SourceLocation.StartLine > 0 {
c.PrintGHAError(message, conslogging.WithGHASourceLocation(cm.SourceLocation.File, cm.SourceLocation.StartLine, cm.SourceLocation.StartColumn))
c.PrintGHAError(singleLineMessage, conslogging.WithGHASourceLocation(cm.SourceLocation.File, cm.SourceLocation.StartLine, cm.SourceLocation.StartColumn))
} else {
c.PrintGHAError(message)
c.PrintGHAError(singleLineMessage)
}

fullErrorMessage := stringutil.ScrubANSICodes(failure.GetErrorMessage())
output := stringutil.ScrubANSICodes(string(failure.GetOutput()))
//GHA Summary markdown
markdown := fmt.Sprintf(`
# ❌ Build Failure ❌
Expand All @@ -513,7 +516,7 @@ func (f *Formatter) printGHAFailure() {
~~~
%s
~~~
`, failure.GetErrorMessage(), string(failure.GetOutput()))
`, fullErrorMessage, output)
c.PrintGHASummary(markdown)
}

Expand Down
7 changes: 7 additions & 0 deletions util/stringutil/scrub.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,10 @@ func ScrubCredentialsAll(s string) string {
}
return strings.Join(ret, " ")
}

// ScrubANSICodes removes ANSI escape codes from a string.
func ScrubANSICodes(input string) string {
re := regexp.MustCompile(`\x1b\[[0-9;]*[a-zA-Z]`)
cleanedString := re.ReplaceAllString(input, "")
return cleanedString
}
5 changes: 5 additions & 0 deletions util/stringutil/scrub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ func TestScrubInline(t *testing.T) {
s := ScrubCredentialsAll("Here is a URL: https://user:[email protected]/org/repo.git")
Equal(t, "Here is a URL: https://user:[email protected]/org/repo.git", s)
}

func TestANSICodes(t *testing.T) {
s := ScrubANSICodes("\033[0;32mCommand succeeded.\033[0m")
Equal(t, "Command succeeded.", s)
}

0 comments on commit 31f93b5

Please sign in to comment.