diff --git a/bake/compose.go b/bake/compose.go index f74730f18..261f5972f 100644 --- a/bake/compose.go +++ b/bake/compose.go @@ -76,13 +76,7 @@ func ParseCompose(cfgs []composetypes.ConfigFile, envs map[string]string) (*Conf var additionalContexts map[string]string if s.Build.AdditionalContexts != nil { - additionalContexts = map[string]string{} - for k, v := range s.Build.AdditionalContexts { - if strings.HasPrefix(v, "service:") { - v = strings.Replace(v, "service:", "target:", 1) - } - additionalContexts[k] = v - } + additionalContexts = composeToBuildkitNamedContexts(s.Build.AdditionalContexts) } var shmSize *string @@ -471,7 +465,7 @@ func (t *Target) composeExtTarget(exts map[string]any) error { t.NoCacheFilter = dedupSlice(append(t.NoCacheFilter, xb.NoCacheFilter...)) } if len(xb.Contexts) > 0 { - t.Contexts = dedupMap(t.Contexts, xb.Contexts) + t.Contexts = dedupMap(t.Contexts, composeToBuildkitNamedContexts(xb.Contexts)) } return nil @@ -506,3 +500,16 @@ func composeToBuildkitSSH(sshKey composetypes.SSHKey) *buildflags.SSH { } return bkssh } + +func composeToBuildkitNamedContexts(m map[string]string) map[string]string { + out := make(map[string]string, len(m)) + for k, v := range m { + if strings.HasPrefix(v, "service:") || strings.HasPrefix(v, "target:") { + if parts := strings.SplitN(v, ":", 2); len(parts) == 2 { + v = "target:" + sanitizeTargetName(parts[1]) + } + } + out[k] = v + } + return out +} diff --git a/bake/compose_test.go b/bake/compose_test.go index b06468049..23422796b 100644 --- a/bake/compose_test.go +++ b/bake/compose_test.go @@ -893,6 +893,44 @@ services: require.Equal(t, map[string]string{"base": "target:base"}, c.Targets[1].Contexts) } +func TestServiceContextDot(t *testing.T) { + dt := []byte(` +services: + base.1: + build: + dockerfile: baseapp.Dockerfile + command: ./entrypoint.sh + foo.1: + build: + dockerfile: fooapp.Dockerfile + command: ./entrypoint.sh + webapp: + build: + context: ./dir + additional_contexts: + base: service:base.1 + x-bake: + contexts: + foo: target:foo.1 +`) + + c, err := ParseCompose([]composetypes.ConfigFile{{Content: dt}}, nil) + require.NoError(t, err) + + require.Equal(t, 1, len(c.Groups)) + require.Equal(t, "default", c.Groups[0].Name) + sort.Strings(c.Groups[0].Targets) + require.Equal(t, []string{"base_1", "foo_1", "webapp"}, c.Groups[0].Targets) + + require.Equal(t, 3, len(c.Targets)) + sort.Slice(c.Targets, func(i, j int) bool { + return c.Targets[i].Name < c.Targets[j].Name + }) + + require.Equal(t, "webapp", c.Targets[2].Name) + require.Equal(t, map[string]string{"base": "target:base_1", "foo": "target:foo_1"}, c.Targets[2].Contexts) +} + func TestDotEnvDir(t *testing.T) { tmpdir := t.TempDir() require.NoError(t, os.Mkdir(filepath.Join(tmpdir, ".env"), 0755))