diff --git a/e2e/cucumber-features/build-contexts.feature b/e2e/cucumber-features/build-contexts.feature new file mode 100644 index 000000000..b57fbe7d0 --- /dev/null +++ b/e2e/cucumber-features/build-contexts.feature @@ -0,0 +1,23 @@ +Feature: Build Contexts + +Background: + Given a compose file + """ + services: + a: + build: + context: . + additional_contexts: + - dep=docker-image://ubuntu:latest + """ + And a dockerfile + """ + # syntax=docker/dockerfile:1 + FROM alpine:latest + COPY --from=dep /etc/hostname / + """ + +Scenario: Build w/ build context + When I run "compose build" + Then the exit code is 0 + diff --git a/pkg/compose/build.go b/pkg/compose/build.go index 08dc06ed4..cbeb5893e 100644 --- a/pkg/compose/build.go +++ b/pkg/compose/build.go @@ -80,6 +80,9 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti if err != nil { return err } + if len(service.Build.AdditionalContexts) > 0 { + buildOptions.Inputs.NamedContexts = toBuildContexts(service.Build.AdditionalContexts) + } for _, image := range service.Build.CacheFrom { buildOptions.CacheFrom = append(buildOptions.CacheFrom, bclient.CacheOptionsEntry{ Type: "registry", @@ -200,7 +203,6 @@ func (s *composeService) getBuildOptions(project *types.Project, images map[stri } } return opts, nil - } func (s *composeService) getLocalImagesDigests(ctx context.Context, project *types.Project) (map[string]string, error) { @@ -422,6 +424,14 @@ func getImageBuildLabels(project *types.Project, service types.ServiceConfig) ty return ret } +func toBuildContexts(additionalContexts map[string]*string) map[string]build.NamedContext { + namedContexts := map[string]build.NamedContext{} + for name, buildContext := range additionalContexts { + namedContexts[name] = build.NamedContext{Path: *buildContext} + } + return namedContexts +} + func useDockerDefaultPlatform(project *types.Project, platformList types.StringList) ([]specs.Platform, error) { var plats []specs.Platform if platform, ok := project.Environment["DOCKER_DEFAULT_PLATFORM"]; ok { diff --git a/pkg/compose/build_classic.go b/pkg/compose/build_classic.go index c2548400d..b532b46bf 100644 --- a/pkg/compose/build_classic.go +++ b/pkg/compose/build_classic.go @@ -46,7 +46,7 @@ import ( ) func (s *composeService) doBuildClassic(ctx context.Context, project *types.Project, opts map[string]buildx.Options) (map[string]string, error) { - var nameDigests = make(map[string]string) + nameDigests := make(map[string]string) var errs error err := project.WithServices(nil, func(service types.ServiceConfig) error { imageName := api.GetImageNameOrDefault(service, project.Name) @@ -103,6 +103,9 @@ func (s *composeService) doBuildClassicSimpleImage(ctx context.Context, options if utils.Contains(options.Allow, entitlements.EntitlementSecurityInsecure) { return "", errors.Errorf("this builder doesn't support privileged mode, set DOCKER_BUILDKIT=1 to use builder supporting privileged mode") } + if len(options.Inputs.NamedContexts) > 0 { + return "", errors.Errorf("this builder doesn't support additional contexts, set DOCKER_BUILDKIT=1 to use BuildKit which does") + } if options.Labels == nil { options.Labels = make(map[string]string)