From e51a785cb9379e6ae281c095218a4db1195cd3c1 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Thu, 24 Aug 2023 14:15:25 +0100 Subject: [PATCH] bake: add annotations field Signed-off-by: Justin Chadwell --- bake/bake.go | 17 +++++++++++++++++ bake/bake_test.go | 28 ++++++++++++++++++++++++++++ docs/bake-reference.md | 21 +++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/bake/bake.go b/bake/bake.go index 72ca30ec2708..e3622e2c292a 100644 --- a/bake/bake.go +++ b/bake/bake.go @@ -589,6 +589,7 @@ type Target struct { // Inherits is the only field that cannot be overridden with --set Inherits []string `json:"inherits,omitempty" hcl:"inherits,optional" cty:"inherits"` + Annotations []string `json:"annotations,omitempty" hcl:"annotations,optional" cty:"annotations"` Attest []string `json:"attest,omitempty" hcl:"attest,optional" cty:"attest"` Context *string `json:"context,omitempty" hcl:"context,optional" cty:"context"` Contexts map[string]string `json:"contexts,omitempty" hcl:"contexts,optional" cty:"contexts"` @@ -620,6 +621,7 @@ var _ hclparser.WithEvalContexts = &Group{} var _ hclparser.WithGetName = &Group{} func (t *Target) normalize() { + t.Annotations = removeDupes(t.Annotations) t.Attest = removeAttestDupes(t.Attest) t.Tags = removeDupes(t.Tags) t.Secrets = removeDupes(t.Secrets) @@ -680,6 +682,9 @@ func (t *Target) Merge(t2 *Target) { if t2.Target != nil { t.Target = t2.Target } + if t2.Annotations != nil { // merge + t.Annotations = append(t.Annotations, t2.Annotations...) + } if t2.Attest != nil { // merge t.Attest = append(t.Attest, t2.Attest...) t.Attest = removeAttestDupes(t.Attest) @@ -766,6 +771,8 @@ func (t *Target) AddOverrides(overrides map[string]Override) error { t.Platforms = o.ArrValue case "output": t.Outputs = o.ArrValue + case "annotations": + t.Annotations = append(t.Annotations, o.ArrValue...) case "attest": t.Attest = append(t.Attest, o.ArrValue...) case "no-cache": @@ -1164,6 +1171,16 @@ func toBuildOpt(t *Target, inp *Input) (*build.Options, error) { return nil, err } + annotations, err := buildflags.ParseAnnotations(t.Annotations) + if err != nil { + return nil, err + } + for _, e := range bo.Exports { + for k, v := range annotations { + e.Attrs[k.String()] = v + } + } + attests, err := buildflags.ParseAttests(t.Attest) if err != nil { return nil, err diff --git a/bake/bake_test.go b/bake/bake_test.go index 32a21bc27322..a54e66c9230f 100644 --- a/bake/bake_test.go +++ b/bake/bake_test.go @@ -1460,3 +1460,31 @@ func TestAttestDuplicates(t *testing.T) { "provenance": ptrstr("type=provenance,mode=max"), }, opts["default"].Attests) } + +func TestAnnotations(t *testing.T) { + fp := File{ + Name: "docker-bake.hcl", + Data: []byte( + `target "app" { + output = ["type=image,name=foo"] + annotations = ["manifest[linux/amd64]:foo=bar"] + }`), + } + ctx := context.TODO() + m, g, err := ReadTargets(ctx, []File{fp}, []string{"app"}, nil, nil) + require.NoError(t, err) + + bo, err := TargetsToBuildOpt(m, &Input{}) + require.NoError(t, err) + + require.Equal(t, 1, len(g)) + require.Equal(t, []string{"app"}, g["default"].Targets) + + require.Equal(t, 1, len(m)) + require.Contains(t, m, "app") + require.Equal(t, "type=image,name=foo", m["app"].Outputs[0]) + require.Equal(t, "manifest[linux/amd64]:foo=bar", m["app"].Annotations[0]) + + require.Len(t, bo["app"].Exports, 1) + require.Equal(t, "bar", bo["app"].Exports[0].Attrs["annotation-manifest[linux/amd64].foo"]) +} diff --git a/docs/bake-reference.md b/docs/bake-reference.md index d767504efdd3..9a9104faf2a7 100644 --- a/docs/bake-reference.md +++ b/docs/bake-reference.md @@ -115,6 +115,7 @@ The following table shows the complete list of attributes that you can assign to | Name | Type | Description | | ----------------------------------------------- | ------- | -------------------------------------------------------------------- | | [`args`](#targetargs) | Map | Build arguments | +| [`annotations`](#targetannotations) | List | Exporter annotations | | [`attest`](#targetattest) | List | Build attestations | | [`cache-from`](#targetcache-from) | List | External cache sources | | [`cache-to`](#targetcache-to) | List | External cache destinations | @@ -171,6 +172,26 @@ target "db" { } ``` +### `target.annotations` + +The `annotations` attribute is a shortcut to allow you to easily set a list of +annotations on the target. + +```hcl +target "default" { + output = ["type=image,name=foo"] + annotations = ["key=value"] +} +``` + +is the same as + +```hcl +target "default" { + output = ["type=image,name=foo,annotation.key=value"] +} +``` + ### `target.attest` The `attest` attribute lets you apply [build attestations][attestations] to the target.