select services implicitly declared by a service:xx build dependency
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
9c998a934f
commit
fc8c56b407
@ -27,7 +27,6 @@ import (
|
|||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
cliopts "github.com/docker/cli/opts"
|
cliopts "github.com/docker/cli/opts"
|
||||||
ui "github.com/docker/compose/v2/pkg/progress"
|
ui "github.com/docker/compose/v2/pkg/progress"
|
||||||
"github.com/docker/compose/v2/pkg/utils"
|
|
||||||
buildkit "github.com/moby/buildkit/util/progress/progressui"
|
buildkit "github.com/moby/buildkit/util/progress/progressui"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -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 {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
services = addBuildDependencies(services, project)
|
|
||||||
|
|
||||||
if err := applyPlatforms(project, false); err != nil {
|
if err := applyPlatforms(project, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -159,21 +156,3 @@ func runBuild(ctx context.Context, dockerCli command.Cli, backend api.Service, o
|
|||||||
|
|
||||||
return backend.Build(ctx, project, apiBuildOptions)
|
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()
|
|
||||||
}
|
|
||||||
|
@ -85,7 +85,16 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
|
|||||||
policy = types.IncludeDependencies
|
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 {
|
if service.Build == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -613,3 +622,21 @@ func parsePlatforms(service types.ServiceConfig) ([]specs.Platform, error) {
|
|||||||
|
|
||||||
return ret, nil
|
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()
|
||||||
|
}
|
||||||
|
@ -117,14 +117,14 @@ func TestLocalComposeBuild(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run(env+" rebuild when up --build", func(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 static /usr/share/nginx/html"})
|
||||||
res.Assert(t, icmd.Expected{Out: "COPY static2 /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) {
|
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())
|
assert.Assert(t, !strings.Contains(res.Stdout(), "failed to push"), res.Stdout())
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ func TestBuildTags(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestBuildImageDependencies(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() {
|
resetState := func() {
|
||||||
cli.RunDockerComposeCmd(t, "down", "--rmi=all", "-t=0")
|
cli.RunDockerComposeCmd(t, "down", "--rmi=all", "-t=0")
|
||||||
res := cli.RunDockerOrExitError(t, "image", "rm", "build-dependencies-service")
|
res := cli.RunDockerOrExitError(t, "image", "rm", "build-dependencies-service")
|
||||||
@ -250,7 +250,7 @@ func TestBuildImageDependencies(t *testing.T) {
|
|||||||
Err: "No such image: build-dependencies-service",
|
Err: "No such image: build-dependencies-service",
|
||||||
})
|
})
|
||||||
|
|
||||||
res = cli.RunDockerComposeCmd(t, "build")
|
res = cli.RunDockerComposeCmd(t, args...)
|
||||||
t.Log(res.Combined())
|
t.Log(res.Combined())
|
||||||
|
|
||||||
res = cli.RunDockerCmd(t,
|
res = cli.RunDockerCmd(t,
|
||||||
@ -273,7 +273,8 @@ func TestBuildImageDependencies(t *testing.T) {
|
|||||||
"DOCKER_BUILDKIT=0",
|
"DOCKER_BUILDKIT=0",
|
||||||
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
|
"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) {
|
t.Run("BuildKit by dependency order", func(t *testing.T) {
|
||||||
@ -281,7 +282,8 @@ func TestBuildImageDependencies(t *testing.T) {
|
|||||||
"DOCKER_BUILDKIT=1",
|
"DOCKER_BUILDKIT=1",
|
||||||
"COMPOSE_FILE=./fixtures/build-dependencies/classic.yaml",
|
"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) {
|
t.Run("BuildKit by additional contexts", func(t *testing.T) {
|
||||||
@ -289,7 +291,8 @@ func TestBuildImageDependencies(t *testing.T) {
|
|||||||
"DOCKER_BUILDKIT=1",
|
"DOCKER_BUILDKIT=1",
|
||||||
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
|
"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) {
|
t.Run("Bake by additional contexts", func(t *testing.T) {
|
||||||
@ -297,7 +300,8 @@ func TestBuildImageDependencies(t *testing.T) {
|
|||||||
"DOCKER_BUILDKIT=1", "COMPOSE_BAKE=1",
|
"DOCKER_BUILDKIT=1", "COMPOSE_BAKE=1",
|
||||||
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
|
"COMPOSE_FILE=./fixtures/build-dependencies/compose.yaml",
|
||||||
))
|
))
|
||||||
doTest(t, cli)
|
doTest(t, cli, "build")
|
||||||
|
doTest(t, cli, "build", "service")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user