@@ -73,11 +73,11 @@ type executionOpts struct {
7373func runSteps (ctx context.Context , opts * executionOpts ) (result executionResult , stepResults []stepExecutionResult , err error ) {
7474 opts .ui .ArchiveDownloadStarted ()
7575 err = opts .task .Archive .Ensure (ctx )
76+ opts .ui .ArchiveDownloadFinished (err )
7677 if err != nil {
7778 return executionResult {}, nil , errors .Wrap (err , "fetching repo" )
7879 }
7980 defer opts .task .Archive .Close ()
80- opts .ui .ArchiveDownloadFinished ()
8181
8282 opts .ui .WorkspaceInitializationStarted ()
8383 workspace , err := opts .wc .Create (ctx , opts .task .Repository , opts .task .Steps , opts .task .Archive )
@@ -167,6 +167,16 @@ func runSteps(ctx context.Context, opts *executionOpts) (result executionResult,
167167 return execResult , nil , err
168168 }
169169 stdoutBuffer , stderrBuffer , err := executeSingleStep (ctx , opts , workspace , i , step , digest , & stepContext )
170+ defer func () {
171+ if err != nil {
172+ exitCode := - 1
173+ sfe := & stepFailedErr {}
174+ if errors .As (err , sfe ) {
175+ exitCode = sfe .ExitCode
176+ }
177+ opts .ui .StepFailed (i + 1 , err , exitCode )
178+ }
179+ }()
170180 if err != nil {
171181 return execResult , nil , err
172182 }
@@ -233,44 +243,55 @@ func executeSingleStep(
233243 // ----------
234244 // PREPARATION
235245 // ----------
236- opts .ui .StepPreparing (i + 1 )
246+ opts .ui .StepPreparingStart (i + 1 )
237247
238248 cidFile , cleanup , err := createCidFile (ctx , opts .tempDir , util .SlugForRepo (opts .task .Repository .Name , opts .task .Repository .Rev ()))
239249 if err != nil {
250+ opts .ui .StepPreparingFailed (i + 1 , err )
240251 return bytes.Buffer {}, bytes.Buffer {}, err
241252 }
242253 defer cleanup ()
243254
244255 // For now, we only support shell scripts provided via the Run field.
245256 shell , containerTemp , err := probeImageForShell (ctx , imageDigest )
246257 if err != nil {
247- return bytes.Buffer {}, bytes.Buffer {}, errors .Wrapf (err , "probing image %q for shell" , step .Container )
258+ err = errors .Wrapf (err , "probing image %q for shell" , step .Container )
259+ opts .ui .StepPreparingFailed (i + 1 , err )
260+ return bytes.Buffer {}, bytes.Buffer {}, err
248261 }
249262
250263 runScriptFile , runScript , cleanup , err := createRunScriptFile (ctx , opts .tempDir , step .Run , stepContext )
251264 if err != nil {
265+ opts .ui .StepPreparingFailed (i + 1 , err )
252266 return bytes.Buffer {}, bytes.Buffer {}, err
253267 }
254268 defer cleanup ()
255269
256270 // Parse and render the step.Files.
257271 filesToMount , cleanup , err := createFilesToMount (opts .tempDir , step , stepContext )
258272 if err != nil {
273+ opts .ui .StepPreparingFailed (i + 1 , err )
259274 return bytes.Buffer {}, bytes.Buffer {}, err
260275 }
261276 defer cleanup ()
262277
263278 // Resolve step.Env given the current environment.
264279 stepEnv , err := step .Env .Resolve (os .Environ ())
265280 if err != nil {
266- return bytes.Buffer {}, bytes.Buffer {}, errors .Wrap (err , "resolving step environment" )
281+ err = errors .Wrap (err , "resolving step environment" )
282+ opts .ui .StepPreparingFailed (i + 1 , err )
283+ return bytes.Buffer {}, bytes.Buffer {}, err
267284 }
268285 // Render the step.Env variables as templates.
269286 env , err := template .RenderStepMap (stepEnv , stepContext )
270287 if err != nil {
271- return bytes.Buffer {}, bytes.Buffer {}, errors .Wrap (err , "parsing step environment" )
288+ err = errors .Wrap (err , "parsing step environment" )
289+ opts .ui .StepPreparingFailed (i + 1 , err )
290+ return bytes.Buffer {}, bytes.Buffer {}, err
272291 }
273292
293+ opts .ui .StepPreparingSuccess (i + 1 )
294+
274295 // ----------
275296 // EXECUTION
276297 // ----------
@@ -330,8 +351,14 @@ func executeSingleStep(
330351 }
331352
332353 newStepFailedErr := func (wrappedErr error ) stepFailedErr {
354+ exitCode := - 1
355+ exitErr := & exec.ExitError {}
356+ if errors .As (wrappedErr , & exitErr ) {
357+ exitCode = exitErr .ExitCode ()
358+ }
333359 return stepFailedErr {
334360 Err : wrappedErr ,
361+ ExitCode : exitCode ,
335362 Args : cmd .Args ,
336363 Run : runScript ,
337364 Container : step .Container ,
@@ -570,7 +597,9 @@ type stepFailedErr struct {
570597 Stdout string
571598 Stderr string
572599
573- Err error
600+ // ExitCode of the command, or -1 if a non-command error occured.
601+ ExitCode int
602+ Err error
574603}
575604
576605func (e stepFailedErr ) Cause () error { return e .Err }
@@ -607,8 +636,8 @@ func (e stepFailedErr) Error() string {
607636 printOutput (e .Stderr )
608637 }
609638
610- if exitErr , ok := e . Err .( * exec. ExitError ); ok {
611- out .WriteString (fmt .Sprintf ("\n Command failed with exit code %d." , exitErr .ExitCode () ))
639+ if e . ExitCode != - 1 {
640+ out .WriteString (fmt .Sprintf ("\n Command failed with exit code %d." , e .ExitCode ))
612641 } else {
613642 out .WriteString (fmt .Sprintf ("\n Command failed: %s" , e .Err ))
614643 }
0 commit comments