bake: fix remote named context subdir handling

Fix using CopyDirContentsOnly when projecting remote named contexts so
subdir contexts keep the same root semantics as local bake runs.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi
2026-02-27 17:06:32 -08:00
parent 22074cd400
commit d39a81e456
2 changed files with 80 additions and 1 deletions
+4 -1
View File
@@ -1299,6 +1299,7 @@ func updateContext(t *build.Inputs, inp *Input) {
for k, v := range t.NamedContexts {
if v.Path == "." {
t.NamedContexts[k] = build.NamedContext{Path: inp.URL}
continue
}
if strings.HasPrefix(v.Path, "cwd://") || strings.HasPrefix(v.Path, "target:") || strings.HasPrefix(v.Path, "docker-image:") {
continue
@@ -1306,7 +1307,9 @@ func updateContext(t *build.Inputs, inp *Input) {
if urlutil.IsRemoteURL(v.Path) {
continue
}
st := llb.Scratch().File(llb.Copy(*inp.State, v.Path, "/"), llb.WithCustomNamef("set context %s to %s", k, v.Path))
st := llb.Scratch().File(llb.Copy(*inp.State, v.Path, "/", &llb.CopyInfo{
CopyDirContentsOnly: true,
}), llb.WithCustomNamef("set context %s to %s", k, v.Path))
t.NamedContexts[k] = build.NamedContext{State: &st, Path: inp.URL}
}
+76
View File
@@ -51,6 +51,8 @@ var bakeTests = []func(t *testing.T, sb integration.Sandbox){
testBakeLocalCwdOverride,
testBakeRemoteCmdContextOverride,
testBakeRemoteContextSubdir,
testBakeRemoteNamedContextSubdir,
testBakeRemoteNamedContextDot,
testBakeRemoteCmdContextEscapeRoot,
testBakeRemoteCmdContextEscapeRelative,
testBakeRemoteDockerfileCwd,
@@ -920,6 +922,80 @@ COPY super-cool.txt /
require.FileExists(t, filepath.Join(dirDest, "super-cool.txt"))
}
// https://github.com/docker/buildx/issues/3670
func testBakeRemoteNamedContextSubdir(t *testing.T, sb integration.Sandbox) {
bakefile := []byte(`
target default {
context = "./build"
dockerfile = "Dockerfile"
contexts = {
files = "./files-src/"
}
}
`)
dockerfile := []byte(`
FROM scratch
COPY --from=files file.txt /file.txt
`)
dir := tmpdir(
t,
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
fstest.CreateDir("build", 0700),
fstest.CreateFile("build/Dockerfile", dockerfile, 0600),
fstest.CreateDir("files-src", 0700),
fstest.CreateFile("files-src/file.txt", []byte("hello"), 0600),
)
dirDest := t.TempDir()
git, err := gitutil.New(gitutil.WithWorkingDir(dir))
require.NoError(t, err)
gittestutil.GitInit(git, t)
gittestutil.GitAdd(git, t, "docker-bake.hcl", "build", "files-src")
gittestutil.GitCommit(git, t, "initial commit")
addr := gittestutil.GitServeHTTP(git, t)
out, err := bakeCmd(sb, withDir("/tmp"), withArgs(addr, "--set", "*.output=type=local,dest="+dirDest))
require.NoError(t, err, out)
require.FileExists(t, filepath.Join(dirDest, "file.txt"))
}
func testBakeRemoteNamedContextDot(t *testing.T, sb integration.Sandbox) {
bakefile := []byte(`
target default {
context = "./build"
dockerfile = "Dockerfile"
contexts = {
files = "."
}
}
`)
dockerfile := []byte(`
FROM scratch
COPY --from=files marker.txt /marker.txt
`)
dir := tmpdir(
t,
fstest.CreateFile("docker-bake.hcl", bakefile, 0600),
fstest.CreateDir("build", 0700),
fstest.CreateFile("build/Dockerfile", dockerfile, 0600),
fstest.CreateFile("marker.txt", []byte("hello"), 0600),
)
dirDest := t.TempDir()
git, err := gitutil.New(gitutil.WithWorkingDir(dir))
require.NoError(t, err)
gittestutil.GitInit(git, t)
gittestutil.GitAdd(git, t, "docker-bake.hcl", "build", "marker.txt")
gittestutil.GitCommit(git, t, "initial commit")
addr := gittestutil.GitServeHTTP(git, t)
out, err := bakeCmd(sb, withDir("/tmp"), withArgs(addr, "--set", "*.output=type=local,dest="+dirDest))
require.NoError(t, err, out)
require.FileExists(t, filepath.Join(dirDest, "marker.txt"))
}
func testBakeRemoteCmdContextEscapeRoot(t *testing.T, sb integration.Sandbox) {
dirSrc := tmpdir(
t,