Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(turborepo): Add task ids to failure reports #5535

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions cli/internal/run/real_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,13 @@ func RealRun(

if isGrouped {
outWriter = logBuffer.StdoutWriter()
errWriter = logBuffer.StderrWriter()
if rs.Opts.runOpts.IsGithubActions {
// If we're running on Github Actions, force everything to stdout
// so as not to have out-of-order log lines
errWriter = outWriter
} else {
errWriter = logBuffer.StderrWriter()
}
}

var spacesLogBuffer *threadsafeOutputBuffer
Expand Down Expand Up @@ -280,6 +286,14 @@ func RealRun(
// Assign tasks after execution
runSummary.RunSummary.Tasks = taskSummaries

terminal := base.UI
if rs.Opts.runOpts.IsGithubActions {
terminal = &cli.PrefixedUi{
Ui: terminal,
ErrorPrefix: "::error::",
WarnPrefix: "::warn::",
}
}
for _, err := range errs {
if errors.As(err, &exitCodeErr) {
// If a process gets killed via a signal, Go reports it's exit code as -1.
Expand All @@ -296,7 +310,7 @@ func RealRun(
// We hit some error, it shouldn't be exit code 0
exitCode = 1
}
base.UI.Error(err.Error())
terminal.Error(err.Error())
}

// When continue on error is enabled don't register failed tasks as errors
Expand Down Expand Up @@ -399,14 +413,14 @@ func (ec *execContext) exec(ctx gocontext.Context, packageTask *nodes.PackageTas
Ui: ui,
OutputPrefix: prettyPrefix,
InfoPrefix: prettyPrefix,
ErrorPrefix: prettyPrefix,
ErrorPrefix: prettyPrefix + "ERROR: ",
WarnPrefix: prettyPrefix,
}

if ec.rs.Opts.runOpts.IsGithubActions {
ui.Output(fmt.Sprintf("::group::%s", packageTask.OutputPrefix(ec.isSinglePackage)))
prefixedUI.WarnPrefix = "::warn::"
prefixedUI.ErrorPrefix = "::error::"
prefixedUI.WarnPrefix = "[WARN] "
prefixedUI.ErrorPrefix = "[ERROR] "
defer func() {
// We don't use the prefixedUI here because the prefix in this case would include
// the ::group::<taskID>, and we explicitly want to close the github group
Expand Down Expand Up @@ -544,17 +558,25 @@ func (ec *execContext) exec(ctx gocontext.Context, packageTask *nodes.PackageTas
// If it wasn't a ChildExit, and something else went wrong, we don't have an exitCode
tracer(runsummary.TargetBuildFailed, err, nil)
}

taskIDDisplay := packageTask.TaskID
if ec.isSinglePackage {
taskIDDisplay = packageTask.Task
}
taskErr := &TaskError{
cause: err,
taskIDDisplay: taskIDDisplay,
}
// If there was an error, flush the buffered output
taskCache.OnError(prefixedUI, progressLogger)
progressLogger.Error(fmt.Sprintf("Error: command finished with error: %v", err))
if !ec.rs.Opts.runOpts.ContinueOnError {
prefixedUI.Error(fmt.Sprintf("ERROR: command finished with error: %s", err))
prefixedUI.Error(fmt.Sprintf("command finished with error: %s", err))
ec.processes.Close()
// We're not continuing, stop graph traversal
err = core.StopExecution(err)
err = core.StopExecution(taskErr)
} else {
prefixedUI.Warn("command finished with error, but continuing...")
err = taskErr
}

return taskExecutionSummary, err
Expand All @@ -580,3 +602,16 @@ func (ec *execContext) exec(ctx gocontext.Context, packageTask *nodes.PackageTas
progressLogger.Debug("done", "status", "complete", "duration", taskExecutionSummary.Duration)
return taskExecutionSummary, nil
}

// TaskError wraps an error encountered running the given task
type TaskError struct {
cause error
taskIDDisplay string
}

// Unwrap allows for interoperation with standard library error wrapping
func (te *TaskError) Unwrap() error { return te.cause }

func (te *TaskError) Error() string {
return fmt.Sprintf("%v: %v", te.taskIDDisplay, te.cause)
}
4 changes: 2 additions & 2 deletions turborepo-tests/integration/tests/ordered/github.t
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ Verify that errors are grouped properly
npm ERR! Error: command failed
npm ERR! in workspace: util
npm ERR\! at location: (.*)/packages/util (re)
::error::ERROR: command finished with error: command \((.*)/packages/util\) npm run fail exited \(1\) (re)
\[ERROR\] command finished with error: command \((.*)/packages/util\) npm run fail exited \(1\) (re)
::endgroup::
command \(.*/packages/util\) npm run fail exited \(1\) (re)
::error::util#fail: command \(.*/packages/util\) npm run fail exited \(1\) (re)

Tasks: 0 successful, 1 total
Cached: 0 cached, 1 total
Expand Down
4 changes: 2 additions & 2 deletions turborepo-tests/integration/tests/run-logging/errors-only.t
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Setup
app-a:builderror: npm ERR! in workspace: app-a
app-a:builderror: npm ERR! at location: .* (re)
app-a:builderror: ERROR: command finished with error: command .* npm run builderror exited \(1\) (re)
command .* npm run builderror exited \(1\) (re)
app-a#builderror: command .* npm run builderror exited \(1\) (re)

Tasks: 0 successful, 1 total
Cached: 0 cached, 1 total
Expand Down Expand Up @@ -79,7 +79,7 @@ Setup
app-a:builderror2: npm ERR! in workspace: app-a
app-a:builderror2: npm ERR! at location: .* (re)
app-a:builderror2: ERROR: command finished with error: command .* npm run builderror2 exited \(1\) (re)
command .* npm run builderror2 exited \(1\) (re)
app-a#builderror2: command .* npm run builderror2 exited \(1\) (re)

Tasks: 0 successful, 1 total
Cached: 0 cached, 1 total
Expand Down
8 changes: 4 additions & 4 deletions turborepo-tests/integration/tests/run/continue.t
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Run without --continue
some-lib:build: npm ERR! in workspace: some-lib
some-lib:build: npm ERR! at location: (.*)/apps/some-lib (re)
some-lib:build: ERROR: command finished with error: command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)
command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)
some-lib#build: command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)

Tasks: 0 successful, 1 total
Cached: 0 cached, 1 total
Expand All @@ -41,7 +41,7 @@ Run without --continue, and with only errors.
some-lib:build: npm ERR! in workspace: some-lib
some-lib:build: npm ERR! at location: (.*)/apps/some-lib (re)
some-lib:build: ERROR: command finished with error: command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)
command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)
some-lib#build: command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)

Tasks: 0 successful, 1 total
Cached: 0 cached, 1 total
Expand Down Expand Up @@ -76,8 +76,8 @@ Run with --continue
other-app:build: npm ERR! in workspace: other-app
other-app:build: npm ERR! at location: (.*)/apps/other-app (re)
other-app:build: command finished with error, but continuing...
command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)
command \((.*)/apps/other-app\) npm run build exited \(1\) (re)
some-lib#build: command \((.*)/apps/some-lib\) npm run build exited \(1\) (re)
other-app#build: command \((.*)/apps/other-app\) npm run build exited \(1\) (re)

Tasks: 1 successful, 3 total
Cached: 0 cached, 3 total
Expand Down
6 changes: 3 additions & 3 deletions turborepo-tests/integration/tests/run/one-script-error.t
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Note that npm reports any failed script as exit code 1, even though we "exit 2"
my-app:error: npm ERR! in workspace: my-app
my-app:error: npm ERR! at location: .*apps/my-app (re)
my-app:error: ERROR: command finished with error: command \(.*apps/my-app\) npm run error exited \(1\) (re)
command \(.*apps/my-app\) npm run error exited \(1\) (re)
my-app#error: command \(.*apps/my-app\) npm run error exited \(1\) (re)

Tasks: 1 successful, 2 total
Cached: 0 cached, 2 total
Expand Down Expand Up @@ -55,7 +55,7 @@ Make sure error isn't cached
my-app:error: npm ERR! in workspace: my-app
my-app:error: npm ERR! at location: .*apps/my-app (re)
my-app:error: ERROR: command finished with error: command \(.*apps/my-app\) npm run error exited \(1\) (re)
command \(.*apps/my-app\) npm run error exited \(1\) (re)
my-app#error: command \(.*apps/my-app\) npm run error exited \(1\) (re)

Tasks: 1 successful, 2 total
Cached: 1 cached, 2 total
Expand Down Expand Up @@ -92,7 +92,7 @@ Make sure error code isn't swallowed with continue
my-app:okay2: > echo 'working'
my-app:okay2:
my-app:okay2: working
command \((.*)/apps/my-app\) npm run error exited \(1\) (re)
my-app#error: command \((.*)/apps/my-app\) npm run error exited \(1\) (re)

Tasks: 2 successful, 3 total
Cached: 1 cached, 3 total
Expand Down
Loading