From e23f5cab0cce3b78a9fbbf97426501d0e634cc16 Mon Sep 17 00:00:00 2001 From: Mariano Reingart Date: Tue, 9 Sep 2025 18:07:13 -0500 Subject: [PATCH 1/2] fix: honor target in input digest tagger Add the target to the input list so it affects the final hash. Closes #9826 --- pkg/skaffold/tag/input_digest.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pkg/skaffold/tag/input_digest.go b/pkg/skaffold/tag/input_digest.go index d144326aa5f..ff79abe3358 100644 --- a/pkg/skaffold/tag/input_digest.go +++ b/pkg/skaffold/tag/input_digest.go @@ -59,10 +59,16 @@ func (t *inputDigestTagger) GenerateTag(ctx context.Context, image latest.Artifa if image.DockerArtifact != nil { srcFiles = append(srcFiles, image.DockerArtifact.DockerfilePath) + if image.DockerArtifact.Target != "" { + inputs = append(inputs, image.DockerArtifact.Target) + } } if image.KanikoArtifact != nil { srcFiles = append(srcFiles, image.KanikoArtifact.DockerfilePath) + if image.KanikoArtifact.Target != "" { + inputs = append(inputs, image.KanikoArtifact.Target) + } } if image.CustomArtifact != nil && image.CustomArtifact.Dependencies != nil && image.CustomArtifact.Dependencies.Dockerfile != nil { From ee9f4454a27729aaa4815d02f8a3abd9284a69d3 Mon Sep 17 00:00:00 2001 From: Mariano Reingart Date: Tue, 9 Sep 2025 18:27:58 -0500 Subject: [PATCH 2/2] test: UT for target in input digest --- pkg/skaffold/tag/input_digest_test.go | 65 +++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/pkg/skaffold/tag/input_digest_test.go b/pkg/skaffold/tag/input_digest_test.go index dc76985ce38..9fa78760c27 100644 --- a/pkg/skaffold/tag/input_digest_test.go +++ b/pkg/skaffold/tag/input_digest_test.go @@ -153,3 +153,68 @@ CMD [ "true" ] } }) } + +func TestGenerateTag_DifferentTarget(t *testing.T) { + runCtx := &runcontext.RunContext{} + dockerfilePath := filepath.Join(t.TempDir(), "Dockerfile") + if err := os.WriteFile(dockerfilePath, []byte("FROM busybox\nCMD [\"ps\", \"faux\"]\n"), 0644); err != nil { + t.Fatalf("failed to write dockerfile: %v", err) + } + + digestExample, _ := NewInputDigestTagger(runCtx, graph.ToArtifactGraph(runCtx.Artifacts())) + tag1, err := digestExample.GenerateTag(context.Background(), latest.Artifact{ + Workspace: t.TempDir(), + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + DockerfilePath: dockerfilePath, + Target: "target1", + }, + }, + }) + if err != nil { + t.Fatalf("GenerateTag failed for target1: %v", err) + } + + digestExample, _ = NewInputDigestTagger(runCtx, graph.ToArtifactGraph(runCtx.Artifacts())) + tag2, err := digestExample.GenerateTag(context.Background(), latest.Artifact{ + Workspace: t.TempDir(), + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + DockerfilePath: dockerfilePath, + Target: "target2", + }, + }, + }) + if err != nil { + t.Fatalf("GenerateTag failed for target2: %v", err) + } + + if tag1 == tag2 { + t.Errorf("expected different tags for different targets, got same: %s", tag1) + } +} + +func TestGenerateTag_NoTarget(t *testing.T) { + runCtx := &runcontext.RunContext{} + dockerfilePath := filepath.Join(t.TempDir(), "Dockerfile") + if err := os.WriteFile(dockerfilePath, []byte("FROM busybox\nCMD [\"ps\", \"faux\"]\n"), 0644); err != nil { + t.Fatalf("failed to write dockerfile: %v", err) + } + + digestExample, _ := NewInputDigestTagger(runCtx, graph.ToArtifactGraph(runCtx.Artifacts())) + tag, err := digestExample.GenerateTag(context.Background(), latest.Artifact{ + Workspace: t.TempDir(), + ArtifactType: latest.ArtifactType{ + DockerArtifact: &latest.DockerArtifact{ + DockerfilePath: dockerfilePath, + // No Target field set + }, + }, + }) + if err != nil { + t.Fatalf("GenerateTag failed when no target: %v", err) + } + if tag == "" { + t.Errorf("expected a non-empty tag when no target is set") + } +}