From bc119c6c604d31396a1e58194c02f4a6380aad0c Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 12 Dec 2025 19:10:15 +0100 Subject: [PATCH 1/4] feat(ci): emit error annotations in GitHub Actions When a task fails and GITHUB_ACTIONS=true, emit a ::error:: annotation that shows up in the workflow summary, making it easier to spot failures without scrolling through logs. --- cmd/task/task.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/cmd/task/task.go b/cmd/task/task.go index 0a31dd7a6d..71171b6a7b 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -28,19 +28,34 @@ func main() { Color: flags.Color, } if err, ok := err.(*errors.TaskRunError); ok && flags.ExitCode { + emitCIErrorAnnotation(err) l.Errf(logger.Red, "%v\n", err) os.Exit(err.TaskExitCode()) } if err, ok := err.(errors.TaskError); ok { + emitCIErrorAnnotation(err) l.Errf(logger.Red, "%v\n", err) os.Exit(err.Code()) } + emitCIErrorAnnotation(err) l.Errf(logger.Red, "%v\n", err) os.Exit(errors.CodeUnknown) } os.Exit(errors.CodeOk) } +// emitCIErrorAnnotation emits an error annotation for supported CI providers. +func emitCIErrorAnnotation(err error) { + if os.Getenv("GITHUB_ACTIONS") != "true" { + return + } + if e, ok := err.(*errors.TaskRunError); ok { + fmt.Fprintf(os.Stdout, "::error title=Task '%s' failed::%v\n", e.TaskName, e.Err) + return + } + fmt.Fprintf(os.Stdout, "::error title=Task failed::%v\n", err) +} + func run() error { log := &logger.Logger{ Stdout: os.Stdout, From e8f2b9a212fc342bf2512e9f247917f8bd4c114a Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 12 Dec 2025 19:22:47 +0100 Subject: [PATCH 2/4] docs(guide): add CI integration section Document automatic color detection and GitHub Actions error annotations. --- website/src/docs/guide.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/website/src/docs/guide.md b/website/src/docs/guide.md index 80ccf98dbf..ef59375cb0 100644 --- a/website/src/docs/guide.md +++ b/website/src/docs/guide.md @@ -2290,6 +2290,28 @@ The `output` option can also be specified by the `--output` or `-o` flags. ::: +## CI Integration + +### Colored output + +Task automatically enables colored output when running in CI environments +(`CI=true`). Most CI providers set this variable automatically. + +You can also force colored output with `FORCE_COLOR=1` or disable it with +`NO_COLOR=1`. + +### Error annotations + +When running in GitHub Actions (`GITHUB_ACTIONS=true`), Task automatically emits +error annotations when a task fails. These annotations appear in the workflow +summary, making it easier to spot failures without scrolling through logs. + +```shell +::error title=Task 'build' failed::exit status 1 +``` + +This feature requires no configuration and works automatically. + ## Interactive CLI application When running interactive CLI applications inside Task they can sometimes behave From 74ecd27336d728efe2ffa1e84177bba8c2958b39 Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 12 Dec 2025 19:57:27 +0100 Subject: [PATCH 3/4] Apply suggestion from @andreynering --- cmd/task/task.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/task/task.go b/cmd/task/task.go index 71171b6a7b..0f01eb97b9 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -46,7 +46,7 @@ func main() { // emitCIErrorAnnotation emits an error annotation for supported CI providers. func emitCIErrorAnnotation(err error) { - if os.Getenv("GITHUB_ACTIONS") != "true" { + if isGA, _ := strconv.ParsePool(os.Getenv("GITHUB_ACTIONS")); !isGA { return } if e, ok := err.(*errors.TaskRunError); ok { From f8d3a1e75328770d91e46988d55bfeac93e6d45c Mon Sep 17 00:00:00 2001 From: Valentin Maerten Date: Fri, 12 Dec 2025 20:02:04 +0100 Subject: [PATCH 4/4] import strconv --- cmd/task/task.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/task/task.go b/cmd/task/task.go index 0f01eb97b9..f999f7c966 100644 --- a/cmd/task/task.go +++ b/cmd/task/task.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "strconv" "github.com/spf13/pflag" @@ -46,7 +47,7 @@ func main() { // emitCIErrorAnnotation emits an error annotation for supported CI providers. func emitCIErrorAnnotation(err error) { - if isGA, _ := strconv.ParsePool(os.Getenv("GITHUB_ACTIONS")); !isGA { + if isGA, _ := strconv.ParseBool(os.Getenv("GITHUB_ACTIONS")); !isGA { return } if e, ok := err.(*errors.TaskRunError); ok {