From be7d7c0244613c345bdbdde48a206f42796a4dca Mon Sep 17 00:00:00 2001 From: Lauris BH Date: Wed, 28 Sep 2022 02:16:57 +0200 Subject: [PATCH] Implement option to add image labels and generate automatic labels (#19) Fixes #16 Results into labels: ![attels](/attachments/3aa6641e-fe50-4e28-be97-64c0afe2c35a) Co-authored-by: Lauris BH Reviewed-on: https://codeberg.org/woodpecker-plugins/plugin-docker-buildx/pulls/19 Reviewed-by: 6543 <6543@obermui.de> Co-authored-by: Lauris BH Co-committed-by: Lauris BH --- cmd/docker-buildx/config.go | 13 +++++++++++++ docs.md | 2 ++ plugin/docker.go | 4 ++++ plugin/impl.go | 5 +++++ plugin/labels.go | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+) create mode 100644 plugin/labels.go diff --git a/cmd/docker-buildx/config.go b/cmd/docker-buildx/config.go index ec49471..e11b0c3 100644 --- a/cmd/docker-buildx/config.go +++ b/cmd/docker-buildx/config.go @@ -133,6 +133,19 @@ func settingsFlags(settings *plugin.Settings) []cli.Flag { Usage: "generates tag names with the given suffix", Destination: &settings.Build.TagsSuffix, }, + &cli.StringSliceFlag{ + Name: "labels", + EnvVars: []string{"PLUGIN_LABEL", "PLUGIN_LABELS"}, + Usage: "sets labels to use for the image", + Destination: &settings.Build.Labels, + }, + &cli.BoolFlag{ + Name: "labels.auto", + EnvVars: []string{"PLUGIN_DEFAULT_LABELS", "PLUGIN_AUTO_LABEL"}, + Usage: "generates labels automatically based on git repository info", + Value: true, + Destination: &settings.Build.LabelsAuto, + }, &cli.StringSliceFlag{ Name: "args", EnvVars: []string{"PLUGIN_BUILD_ARGS"}, diff --git a/docs.md b/docs.md index 93fcd7d..37d6526 100644 --- a/docs.md +++ b/docs.md @@ -98,6 +98,8 @@ It will automatically generate buildkit configuration to use custom CA certifica | `context` | `.` | sets the path of the build context to use | `default_tags`/`auto_tag` | `false` | generates tag names automatically based on git branch and git tag | `default_suffix"`/`auto_tag_suffix`| *none* | generates tag names with the given suffix +| `label`/`labels` | *none* | sets labels to use for the image in format `=` +| `default_labels`/`auto_labels` | `true` | sets docker image labels based on git information | `build_args` | *none* | sets custom build arguments for the build | `build_args_from_env` | *none* | forwards environment variables as custom arguments to the build | `quiet` | `false` | enables suppression of the build output diff --git a/plugin/docker.go b/plugin/docker.go index 95caf1d..1f212e5 100644 --- a/plugin/docker.go +++ b/plugin/docker.go @@ -126,6 +126,10 @@ func commandBuild(build Build, dryrun bool) *exec.Cmd { args = append(args, "-t", fmt.Sprintf("%s:%s", build.Repo, arg)) } + for _, l := range build.Labels.Value() { + args = append(args, "--label", l) + } + return exec.Command(dockerExe, args...) } diff --git a/plugin/impl.go b/plugin/impl.go index db8887c..ea7a4df 100644 --- a/plugin/impl.go +++ b/plugin/impl.go @@ -49,6 +49,8 @@ type Build struct { TagsAuto bool // Docker build auto tag TagsSuffix string // Docker build tags with suffix Tags cli.StringSlice // Docker build tags + LabelsAuto bool // Docker build auto labels + Labels cli.StringSlice // Docker build labels Platforms cli.StringSlice // Docker build target platforms Args cli.StringSlice // Docker build args ArgsEnv cli.StringSlice // Docker build args from env @@ -98,6 +100,9 @@ func (p *Plugin) Validate() error { return nil } } + if p.settings.Build.LabelsAuto { + p.settings.Build.Labels = *cli.NewStringSlice(p.Labels()...) + } return nil } diff --git a/plugin/labels.go b/plugin/labels.go new file mode 100644 index 0000000..57d9926 --- /dev/null +++ b/plugin/labels.go @@ -0,0 +1,32 @@ +package plugin + +import ( + "fmt" + "strings" + "time" + + "github.com/coreos/go-semver/semver" +) + +// Labels returns list of labels to use for image +func (p *Plugin) Labels() []string { + l := p.settings.Build.Labels.Value() + // As described in https://github.com/opencontainers/image-spec/blob/main/annotations.md + l = append(l, fmt.Sprintf("org.opencontainers.image.created=%s", time.Now().UTC().Format(time.RFC3339))) + if p.settings.Build.Remote != "" { + l = append(l, fmt.Sprintf("org.opencontainers.image.source=%s", p.settings.Build.Remote)) + } + if p.pipeline.Repo.Link != "" { + l = append(l, fmt.Sprintf("org.opencontainers.image.url=%s", p.pipeline.Repo.Link)) + } + if p.pipeline.Commit.SHA != "" { + l = append(l, fmt.Sprintf("org.opencontainers.image.revision=%s", p.pipeline.Commit.SHA)) + } + if p.settings.Build.Ref != "" && strings.HasPrefix(p.settings.Build.Ref, "refs/tags/") { + v, err := semver.NewVersion(strings.TrimPrefix(p.settings.Build.Ref[10:], "v")) + if err == nil && v != nil { + l = append(l, fmt.Sprintf("org.opencontainers.image.version=%s", v.String())) + } + } + return l +}