@@ -126,7 +126,15 @@ func runBuilder(builder bobfile.BuilderSpec, buildCtx *BuildContext, opDesc stri
126126 return nil
127127}
128128
129- func buildAndPushOneDockerImage (dockerImage bobfile.DockerImageSpec , buildCtx * BuildContext ) error {
129+ type imageBuildOutput struct {
130+ tag string
131+ }
132+
133+ func buildAndPushOneDockerImage (dockerImage bobfile.DockerImageSpec , buildCtx * BuildContext ) (* imageBuildOutput , error ) {
134+ withErr := func (err error ) (* imageBuildOutput , error ) {
135+ return nil , fmt .Errorf ("buildAndPushOneDockerImage: %w" , err )
136+ }
137+
130138 tagWithoutVersion := dockerImage .Image
131139 tag := tagWithoutVersion + ":" + buildCtx .RevisionId .FriendlyRevisionId
132140 tagLatest := tagWithoutVersion + ":latest"
@@ -213,58 +221,60 @@ func buildAndPushOneDockerImage(dockerImage bobfile.DockerImageSpec, buildCtx *B
213221 args = append (args , "--push" )
214222 }
215223
216- return passthroughStdoutAndStderr (exec .Command ("docker" , args ... )).Run ()
217- }
224+ if err := passthroughStdoutAndStderr (exec .Command ("docker" , args ... )).Run (); err != nil {
225+ return withErr (err )
226+ }
227+ } else {
228+ dockerBuildArgs := []string {"docker" ,
229+ "build" ,
230+ "--file" , dockerfilePath ,
231+ "--tag" , tag }
232+ // `$ docker build ...` doesn't have annotation support. we have to use labels.
233+ dockerBuildArgs = append (dockerBuildArgs , annotationsAs ("--label=" )... )
234+ dockerBuildArgs = append (dockerBuildArgs , buildContextDir )
218235
219- dockerBuildArgs := []string {"docker" ,
220- "build" ,
221- "--file" , dockerfilePath ,
222- "--tag" , tag }
223- // `$ docker build ...` doesn't have annotation support. we have to use labels.
224- dockerBuildArgs = append (dockerBuildArgs , annotationsAs ("--label=" )... )
225- dockerBuildArgs = append (dockerBuildArgs , buildContextDir )
236+ //nolint:gosec // ok
237+ buildCmd := passthroughStdoutAndStderr (exec .Command (dockerBuildArgs [0 ], dockerBuildArgs [1 :]... ))
226238
227- //nolint:gosec // ok
228- buildCmd := passthroughStdoutAndStderr (exec .Command (dockerBuildArgs [0 ], dockerBuildArgs [1 :]... ))
239+ if err := buildCmd .Run (); err != nil {
240+ return withErr (err )
241+ }
229242
230- if err := buildCmd . Run (); err != nil {
231- return err
232- }
243+ if buildCtx . PublishArtefacts {
244+ pushTag := func ( tag string ) error {
245+ printHeading ( fmt . Sprintf ( "Pushing %s" , tag ))
233246
234- if buildCtx .PublishArtefacts {
235- pushTag := func (tag string ) error {
236- printHeading (fmt .Sprintf ("Pushing %s" , tag ))
247+ pushCmd := passthroughStdoutAndStderr (exec .Command (
248+ "docker" ,
249+ "push" ,
250+ tag ))
237251
238- pushCmd := passthroughStdoutAndStderr (exec .Command (
239- "docker" ,
240- "push" ,
241- tag ))
252+ if err := pushCmd .Run (); err != nil {
253+ return err
254+ }
242255
243- if err := pushCmd .Run (); err != nil {
244- return err
256+ return nil
245257 }
246258
247- return nil
248- }
249-
250- if err := pushTag (tag ); err != nil {
251- return err
252- }
253-
254- if shouldTagLatest {
255- if err := exec .Command ("docker" , "tag" , tag , tagLatest ).Run (); err != nil {
256- return fmt .Errorf ("tagging failed %s -> %s failed: %v" , tag , tagLatest , err )
259+ if err := pushTag (tag ); err != nil {
260+ return withErr (err )
257261 }
258262
259- if err := pushTag (tagLatest ); err != nil {
260- return err
263+ if shouldTagLatest {
264+ if err := exec .Command ("docker" , "tag" , tag , tagLatest ).Run (); err != nil {
265+ return withErr (fmt .Errorf ("tagging failed %s -> %s failed: %v" , tag , tagLatest , err ))
266+ }
267+
268+ if err := pushTag (tagLatest ); err != nil {
269+ return withErr (err )
270+ }
261271 }
262272 }
263-
264- return nil
265273 }
266274
267- return nil
275+ return & imageBuildOutput {
276+ tag : tag ,
277+ }, nil
268278}
269279
270280func cloneToWorkdir (buildCtx * BuildContext ) error {
@@ -322,16 +332,22 @@ func cloneToWorkdir(buildCtx *BuildContext) error {
322332 return nil
323333}
324334
325- func build (buildCtx * BuildContext ) error {
335+ type buildOutput struct {
336+ images []imageBuildOutput
337+ }
338+
339+ func build (buildCtx * BuildContext ) (* buildOutput , error ) {
340+ withErr := func (err error ) (* buildOutput , error ) { return nil , fmt .Errorf ("build: %w" , err ) }
341+
326342 if buildCtx .CloningStepNeeded {
327343 if err := cloneToWorkdir (buildCtx ); err != nil {
328- return err
344+ return withErr ( err )
329345 }
330346 }
331347
332348 for _ , subrepo := range buildCtx .Bobfile .Subrepos {
333349 if err := ensureSubrepoCloned (buildCtx .WorkspaceDir + "/" + subrepo .Destination , subrepo ); err != nil {
334- return err
350+ return withErr ( err )
335351 }
336352 }
337353
@@ -349,7 +365,7 @@ func build(buildCtx *BuildContext) error {
349365
350366 builderType , _ , err := parseBuilderUsesType (builder .Uses )
351367 if err != nil {
352- return err
368+ return withErr ( err )
353369 }
354370
355371 // only need to build if a builder is dockerfile. images are ready for consumption.
@@ -358,7 +374,7 @@ func build(buildCtx *BuildContext) error {
358374 }
359375
360376 if err := buildBuilder (buildCtx .Bobfile , & builder ); err != nil {
361- return err
377+ return withErr ( err )
362378 }
363379 }
364380
@@ -387,36 +403,43 @@ func build(buildCtx *BuildContext) error {
387403 publishPass := func (cmds bobfile.BuilderCommands ) []string { return cmds .Publish }
388404
389405 if err := pass ("prepare" , preparePass ); err != nil {
390- return err // err context ok
406+ return withErr ( err ) // err context ok
391407 }
392408
393409 if err := pass ("build" , buildPass ); err != nil {
394- return err // err context ok
410+ return withErr ( err ) // err context ok
395411 }
396412
397413 if err := pass ("publish" , publishPass ); err != nil {
398- return err // err context ok
414+ return withErr ( err ) // err context ok
399415 }
400416
401417 dockerLoginCache := newDockerRegistryLoginCache ()
402418
419+ output := buildOutput {
420+ images : []imageBuildOutput {},
421+ }
422+
403423 for _ , dockerImage := range buildCtx .Bobfile .DockerImages {
404424 if buildCtx .BuilderNameFilter != "" {
405425 continue // when building a specifified builder => skip everything else
406426 }
407427
408428 if buildCtx .PublishArtefacts {
409429 if err := loginToDockerRegistry (dockerImage , dockerLoginCache ); err != nil {
410- return err
430+ return withErr ( err )
411431 }
412432 }
413433
414- if err := buildAndPushOneDockerImage (dockerImage , buildCtx ); err != nil {
415- return err
434+ imageOutput , err := buildAndPushOneDockerImage (dockerImage , buildCtx )
435+ if err != nil {
436+ return withErr (err )
416437 }
438+
439+ output .images = append (output .images , * imageOutput )
417440 }
418441
419- return nil
442+ return & output , nil
420443}
421444
422445func constructBuildContext (
@@ -498,7 +521,8 @@ func buildEntry() *cobra.Command {
498521 areWeInCi )
499522 osutil .ExitIfError (err )
500523
501- osutil .ExitIfError (build (buildCtx ))
524+ _ , err = build (buildCtx )
525+ osutil .ExitIfError (err )
502526 },
503527 }
504528
@@ -547,7 +571,12 @@ func buildEntry() *cobra.Command {
547571 buildCtx .Debug = true
548572 }
549573
550- return build (buildCtx )
574+ _ , err := build (buildCtx )
575+ if err != nil {
576+ return err
577+ }
578+
579+ return nil
551580 }())
552581 },
553582 })
0 commit comments