diff --git a/imagebuildah/stage_executor.go b/imagebuildah/stage_executor.go index 942dcaa8a0b..3a4ae9971d6 100644 --- a/imagebuildah/stage_executor.go +++ b/imagebuildah/stage_executor.go @@ -1410,6 +1410,13 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, } } } else { + emptyLayer := !s.stepRequiresLayer(step) + // If lastIntruction of this stage and there was only single step and base image is `scratch` then commit this layer + // instead of ignoring this as an `emptyLayer`. i.e do not create `emptyLayer` if only single layer is present in the + // entire build. + if len(stage.Node.Children) == 1 && lastInstruction && s.builder.FromImage == "" && s.builder.FromImageID == "" && emptyLayer { + emptyLayer = false + } // We're not going to find any more cache hits, so we // can stop looking for them. checkForLayers = false @@ -1420,7 +1427,7 @@ func (s *StageExecutor) Execute(ctx context.Context, base string) (imgID string, // because at this point we want to save history for // layers even if its a squashed build so that they // can be part of build-cache. - imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), !s.stepRequiresLayer(step), commitName, false) + imgID, ref, err = s.commit(ctx, s.getCreatedBy(node, addedContentSummary), emptyLayer, commitName, false) if err != nil { return "", nil, fmt.Errorf("committing container for step %+v: %w", *step, err) } diff --git a/tests/bud.bats b/tests/bud.bats index 5c1b5cba372..5ace6597f1a 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -5782,6 +5782,12 @@ _EOF run_buildah rmi -f ${target} } +@test "layer must be created on scratch and label" { + run_buildah build --layers --label "label1=value1" -t test -f $BUDFILES/from-scratch/Containerfile + run_buildah inspect -f '{{len .Docker.RootFS.DiffIDs}}' test + expect_output "1" "layer must exist" +} + @test "bud-from-relabel" { _prefetch alpine busybox