Skip to content
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
23 changes: 1 addition & 22 deletions cmd/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/docker/cli/cli/command"
cliopts "github.com/docker/cli/opts"
ui "github.com/docker/compose/v2/pkg/progress"
"github.com/docker/compose/v2/pkg/utils"
buildkit "github.com/moby/buildkit/util/progress/progressui"
"github.com/spf13/cobra"

Expand Down Expand Up @@ -141,13 +140,11 @@ func buildCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
}

func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, opts buildOptions, services []string) error {
project, _, err := opts.ToProject(ctx, dockerCli, services, cli.WithResolvedPaths(true), cli.WithoutEnvironmentResolution)
project, _, err := opts.ToProject(ctx, dockerCli, nil, cli.WithResolvedPaths(true), cli.WithoutEnvironmentResolution)
if err != nil {
return err
}

services = addBuildDependencies(services, project)

if err := applyPlatforms(project, false); err != nil {
return err
}
Expand All @@ -159,21 +156,3 @@ func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, o

return backend.Build(ctx, project, apiBuildOptions)
}

func addBuildDependencies(services []string, project *types.Project) []string {
servicesWithDependencies := utils.NewSet(services...)
for _, service := range services {
build := project.Services[service].Build
if build != nil {
for _, target := range build.AdditionalContexts {
if s, found := strings.CutPrefix(target, types.ServicePrefix); found {
servicesWithDependencies.Add(s)
}
}
}
}
if len(servicesWithDependencies) > len(services) {
return addBuildDependencies(servicesWithDependencies.Elements(), project)
}
return servicesWithDependencies.Elements()
}
29 changes: 28 additions & 1 deletion pkg/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,16 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
policy = types.IncludeDependencies
}

err := project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
if len(options.Services) > 0 {
// As user requested some services to be built, also include those used as additional_contexts
options.Services = addBuildDependencies(options.Services, project)
}
project, err := project.WithSelectedServices(options.Services)
if err != nil {
return nil, err
}

err = project.ForEachService(options.Services, func(serviceName string, service *types.ServiceConfig) error {
if service.Build == nil {
return nil
}
Expand Down Expand Up @@ -613,3 +622,21 @@ func parsePlatforms(service types.ServiceConfig) ([]specs.Platform, error) {

return ret, nil
}

func addBuildDependencies(services []string, project *types.Project) []string {
servicesWithDependencies := utils.NewSet(services...)
for _, service := range services {
b := project.Services[service].Build
if b != nil {
for _, target := range b.AdditionalContexts {
if s, found := strings.CutPrefix(target, types.ServicePrefix); found {
servicesWithDependencies.Add(s)
}
}
}
}
if len(servicesWithDependencies) > len(services) {
return addBuildDependencies(servicesWithDependencies.Elements(), project)
}
return servicesWithDependencies.Elements()
}
File renamed without changes.
20 changes: 12 additions & 8 deletions pkg/e2e/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ func TestLocalComposeBuild(t *testing.T) {
})

t.Run(env+" rebuild when up --build", func(t *testing.T) {
res := c.RunDockerComposeCmd(t, "--workdir", "fixtures/build-test", "up", "-d", "--build")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "up", "-d", "--build")

res.Assert(t, icmd.Expected{Out: "COPY static /usr/share/nginx/html"})
res.Assert(t, icmd.Expected{Out: "COPY static2 /usr/share/nginx/html"})
})

t.Run(env+" build --push ignored for unnamed images", func(t *testing.T) {
res := c.RunDockerComposeCmd(t, "--workdir", "fixtures/build-test", "build", "--push", "nginx")
res := c.RunDockerComposeCmd(t, "--project-directory", "fixtures/build-test", "build", "--push", "nginx")
assert.Assert(t, !strings.Contains(res.Stdout(), "failed to push"), res.Stdout())
})

Expand Down Expand Up @@ -232,7 +232,7 @@ func TestBuildTags(t *testing.T) {
}

func TestBuildImageDependencies(t *testing.T) {
doTest := func(t *testing.T, cli *CLI) {
doTest := func(t *testing.T, cli *CLI, args ...string) {
resetState := func() {
cli.RunDockerComposeCmd(t, "down", "--rmi=all", "-t=0")
res := cli.RunDockerOrExitError(t, "image", "rm", "build-dependencies-service")
Expand All @@ -250,7 +250,7 @@ func TestBuildImageDependencies(t *testing.T) {
Err: "No such image: build-dependencies-service",
})

res = cli.RunDockerComposeCmd(t, "build")
res = cli.RunDockerComposeCmd(t, args...)
t.Log(res.Combined())

res = cli.RunDockerCmd(t,
Expand All @@ -273,31 +273,35 @@ func TestBuildImageDependencies(t *testing.T) {
"DOCKER_BUILDKIT=0",
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
))
doTest(t, cli)
doTest(t, cli, "build")
doTest(t, cli, "build", "--with-dependencies", "service")
})

t.Run("BuildKit by dependency order", func(t *testing.T) {
cli := NewCLI(t, WithEnv(
"DOCKER_BUILDKIT=1",
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
))
doTest(t, cli)
doTest(t, cli, "build")
doTest(t, cli, "build", "--with-dependencies", "service")
})

t.Run("BuildKit by additional contexts", func(t *testing.T) {
cli := NewCLI(t, WithEnv(
"DOCKER_BUILDKIT=1",
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
))
doTest(t, cli)
doTest(t, cli, "build")
doTest(t, cli, "build", "service")
})

t.Run("Bake by additional contexts", func(t *testing.T) {
cli := NewCLI(t, WithEnv(
"DOCKER_BUILDKIT=1", "COMPOSE_BAKE=1",
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
))
doTest(t, cli)
doTest(t, cli, "build")
doTest(t, cli, "build", "service")
})
}

Expand Down