Skip to content
Open
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
39 changes: 27 additions & 12 deletions bake/bake.go
Original file line number Diff line number Diff line change
Expand Up @@ -1394,7 +1394,7 @@ func (t *Target) updateSecret(id, value string) error {
return errors.Errorf("invalid format for secret, expecting secret.<id>=<value>")
}

for _, s := range t.Secrets {
for i, s := range t.Secrets {
if s.ID != id {
continue
}
Expand All @@ -1407,8 +1407,11 @@ func (t *Target) updateSecret(id, value string) error {
return errors.Errorf("secret override id %q does not match declared secret %q", next.ID, id)
}

s.Env = next.Env
s.FilePath = next.FilePath
// t.Secrets can share entries with other targets through inherits,
// so the entry is replaced instead of changed in place.
secrets := slices.Clone(t.Secrets)
secrets[i] = &buildflags.Secret{ID: s.ID, FilePath: next.FilePath, Env: next.Env}
t.Secrets = secrets
return nil
}

Expand Down Expand Up @@ -1887,36 +1890,37 @@ func removeDupesStr(s []string) []string {
}

func setPushOverride(outputs []*buildflags.ExportEntry, push bool) []*buildflags.ExportEntry {
// outputs can be shared with other targets through inherits, so they
// are copied before being changed.
if !push {
// Disable push for any relevant export types
for i := 0; i < len(outputs); {
output := outputs[i]
res := make([]*buildflags.ExportEntry, 0, len(outputs))
for _, output := range outputs {
switch output.Type {
case "registry":
// Filter out registry output type
outputs[i], outputs[len(outputs)-1] = outputs[len(outputs)-1], outputs[i]
outputs = outputs[:len(outputs)-1]
continue
case "image":
// Override push attribute
output.Attrs["push"] = "false"
output = withExportAttr(output, "push", "false")
}
i++
res = append(res, output)
}
return outputs
return res
}

// Force push to be enabled
setPush := true
for _, output := range outputs {
outputs = slices.Clone(outputs)
for i, output := range outputs {
if output.Type != "docker" {
// If there is an output type that is not docker, don't set "push"
setPush = false
}

// Set push attribute for image
if output.Type == "image" {
output.Attrs["push"] = "true"
outputs[i] = withExportAttr(output, "push", "true")
}
}

Expand All @@ -1932,6 +1936,17 @@ func setPushOverride(outputs []*buildflags.ExportEntry, push bool) []*buildflags
return outputs
}

// withExportAttr returns a copy of e with the attribute key set to value.
func withExportAttr(e *buildflags.ExportEntry, key, value string) *buildflags.ExportEntry {
out := *e
out.Attrs = maps.Clone(e.Attrs)
if out.Attrs == nil {
out.Attrs = map[string]string{}
}
out.Attrs[key] = value
return &out
}

func setLoadOverride(outputs []*buildflags.ExportEntry, load bool) []*buildflags.ExportEntry {
if !load {
return outputs
Expand Down
45 changes: 45 additions & 0 deletions bake/bake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,51 @@ func TestPushOverride(t *testing.T) {
require.Equal(t, 1, len(m["bar"].Outputs))
require.Equal(t, []string{"type=image,push=true"}, stringify(m["bar"].Outputs))
})

t.Run("inherited outputs", func(t *testing.T) {
fp := File{
Name: "docker-bake.hcl",
Data: []byte(
`target "_common" {
output = ["type=registry", "type=image,name=foo"]
}
target "api" {
inherits = ["_common"]
}
target "app" {
inherits = ["_common"]
}`),
}
m, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"api", "app"}, []string{"app.push=true"}, nil, nil, &EntitlementConf{})
require.NoError(t, err)
require.Equal(t, []string{"type=image,name=foo", "type=registry"}, stringify(m["api"].Outputs))
require.Equal(t, []string{"type=image,name=foo,push=true", "type=registry"}, stringify(m["app"].Outputs))

m, _, err = ReadTargets(context.TODO(), []File{fp}, []string{"api", "app"}, []string{"app.push=false"}, nil, nil, &EntitlementConf{})
require.NoError(t, err)
require.Equal(t, []string{"type=image,name=foo", "type=registry"}, stringify(m["api"].Outputs))
require.Equal(t, []string{"type=image,name=foo,push=false"}, stringify(m["app"].Outputs))
})
}

func TestSecretSourceOverrideInherited(t *testing.T) {
fp := File{
Name: "docker-bake.hcl",
Data: []byte(
`target "_common" {
secret = ["id=token,env=COMMON_TOKEN"]
}
target "api" {
inherits = ["_common"]
}
target "app" {
inherits = ["_common"]
}`),
}
m, _, err := ReadTargets(context.TODO(), []File{fp}, []string{"api", "app"}, []string{"app.secret.token=env=APP_TOKEN"}, nil, nil, &EntitlementConf{})
require.NoError(t, err)
require.Equal(t, []string{"id=token,env=COMMON_TOKEN"}, stringify(m["api"].Secrets))
require.Equal(t, []string{"id=token,env=APP_TOKEN"}, stringify(m["app"].Secrets))
}

func TestLoadOverride(t *testing.T) {
Expand Down
Loading