From a0afdac193ad93a516785570b67f033020f3011c Mon Sep 17 00:00:00 2001 From: Sinkerine Date: Thu, 20 Jan 2022 00:05:51 -0800 Subject: [PATCH 1/3] Port the auto tag feature from https://plugins.drone.io/drone-plugins/drone-docker The logic is forked from https://github.com/drone-plugins/drone-docker code base with necessary modification. I've tested it e2e for DockerHub on my Drone server via this plugin image https://hub.docker.com/repository/docker/15cm/drone-kaniko, for both tag pushes and commit pushes. With this change the .drone.yml in this repo should work as intended. Other changes: - Rename the existing "auto tag" flags/code to "expand tag" for a less misleading naming. - ATTENTION: make a breaking change to set default value of "--tags" to empty. Rationale is to expect most users to use the auto tagging feature. When power users want to specify tags, they should always explicitly set tags instead of being surprised by the default "latest" tag. --- README.md | 51 +++++++++- cmd/kaniko-docker/main.go | 40 ++++++-- cmd/kaniko-ecr/main.go | 38 +++++++- cmd/kaniko-gcr/main.go | 38 +++++++- go.mod | 1 + go.sum | 2 + kaniko.go | 6 +- kaniko_test.go | 70 +++++++------- pkg/tagger/tagger.go | 116 ++++++++++++++++++++++ pkg/tagger/tagger_test.go | 199 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 502 insertions(+), 59 deletions(-) create mode 100644 pkg/tagger/tagger.go create mode 100644 pkg/tagger/tagger_test.go diff --git a/README.md b/README.md index ccbd17e..dfe86a0 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ docker build \ ``` ## Usage +### Manual Tagging ```console docker run --rm \ @@ -52,14 +53,12 @@ docker run --rm \ plugins/kaniko:linux-amd64 ``` -### Automatic Tagging - -With auto tagging enabled, semantic versions can be passed to PLUGIN_TAGS directly for expansion: +With expanded tagging enabled, semantic versions can be passed to PLUGIN_TAGS directly for expansion: ```console docker run --rm \ -e PLUGIN_TAGS=v1.2.3,latest \ - -e PLUGIN_AUTO_TAG=true \ + -e PLUGIN_EXPAND_TAGS=true \ -v $(pwd):/drone \ -w /drone \ plugins/kaniko:linux-amd64 @@ -72,14 +71,56 @@ PLUGIN_TAGS=1,1.2,1.2.3,latest This allows for passing `$DRONE_TAG` directly as a tag for repos that use [semver](https://semver.org) tags. -To avoid confusion between repo tags and image tags, `PLUGIN_AUTO_TAG` also recognizes a semantic version +To avoid confusion between repo tags and image tags, `PLUGIN_EXPAND_TAGS` also recognizes a semantic version without the `v` prefix. As such, the following is also equivalent to the above: ```console docker run --rm \ -e PLUGIN_TAGS=1.2.3,latest \ + -e PLUGIN_EXPAND_TAGS=true \ + -v $(pwd):/drone \ + -w /drone \ + plugins/kaniko:linux-amd64 +``` + +### Auto Tagging +The [auto tag feature](https://plugins.drone.io/drone-plugins/drone-docker/) of docker plugin is also supported. + +When auto tagging is enabled, if any of the case is matched below, a docker build will be pushed with auto generated tags. Otherwise the docker build will be skipped. + +#### Git Tag Push: + +```console +docker run --rm \ + -e DRONE_COMMIT_REF=refs/tags/v1.2.3 \ + -e PLUGIN_REPO=foo/bar \ + -e PLUGIN_USERNAME=foo \ + -e PLUGIN_PASSWORD=bar \ -e PLUGIN_AUTO_TAG=true \ -v $(pwd):/drone \ -w /drone \ plugins/kaniko:linux-amd64 ``` + +Tags to push: +- 1.2.3 +- 1.2 +- 1 + +#### Git Commit Push in default branch: + +```console +docker run --rm \ + -e DRONE_COMMIT_REF=refs/heads/master \ + -e DRONE_REPO_BRANCH=main \ + -e PLUGIN_REPO=foo/bar \ + -e PLUGIN_USERNAME=foo \ + -e PLUGIN_PASSWORD=bar \ + -e PLUGIN_AUTO_TAG=true \ + -v $(pwd):/drone \ + -w /drone \ + plugins/kaniko:linux-amd64 +``` + +Tags to push: +- latest diff --git a/cmd/kaniko-docker/main.go b/cmd/kaniko-docker/main.go index 1067d39..535fccf 100644 --- a/cmd/kaniko-docker/main.go +++ b/cmd/kaniko-docker/main.go @@ -14,6 +14,7 @@ import ( kaniko "github.com/drone/drone-kaniko" "github.com/drone/drone-kaniko/pkg/artifact" + "github.com/drone/drone-kaniko/pkg/tagger" ) const ( @@ -58,18 +59,38 @@ func main() { Value: ".", EnvVar: "PLUGIN_CONTEXT", }, + cli.StringFlag{ + Name: "commit.ref", + Usage: "git commit ref", + EnvVar: "DRONE_COMMIT_REF", + }, + cli.StringFlag{ + Name: "repo.branch", + Usage: "repository default branch", + EnvVar: "DRONE_REPO_BRANCH", + }, cli.StringSliceFlag{ Name: "tags", Usage: "build tags", - Value: &cli.StringSlice{"latest"}, + Value: &cli.StringSlice{}, EnvVar: "PLUGIN_TAGS", FilePath: ".tags", }, cli.BoolFlag{ - Name: "auto_tag", + Name: "tag.expand", Usage: "enable for semver tagging", + EnvVar: "PLUGIN_EXPAND_TAGS", + }, + cli.BoolFlag{ + Name: "tags.auto", + Usage: "enable auto generate build tags", EnvVar: "PLUGIN_AUTO_TAG", }, + cli.StringFlag{ + Name: "tags.auto_suffix", + Usage: "the suffix of auto build tags", + EnvVar: "PLUGIN_AUTO_TAG_SUFFIX", + }, cli.StringSliceFlag{ Name: "args", Usage: "build args", @@ -169,12 +190,19 @@ func run(c *cli.Context) error { } } + enableAutoTag := c.Bool("tags.auto") + enableExpandTag := c.Bool("tags.expand") + tags, shouldSkipBuild, err := tagger.MaybeAutoTag(c.StringSlice("tags"), c.String("commit.ref"), c.String("tags.auto_suffix"), c.String("repo.branch"), enableAutoTag, enableExpandTag) + if shouldSkipBuild { + return err + } + plugin := kaniko.Plugin{ Build: kaniko.Build{ Dockerfile: c.String("dockerfile"), Context: c.String("context"), - Tags: c.StringSlice("tags"), - AutoTag: c.Bool("auto_tag"), + Tags: tags, + ExpandTag: !enableAutoTag && enableExpandTag, Args: c.StringSlice("args"), Target: c.String("target"), Repo: c.String("repo"), @@ -190,7 +218,7 @@ func run(c *cli.Context) error { Platform: c.String("platform"), }, Artifact: kaniko.Artifact{ - Tags: c.StringSlice("tags"), + Tags: tags, Repo: buildRepo(c.String("registry"), c.String("repo")), Registry: c.String("registry"), ArtifactFile: c.String("artifact-file"), @@ -238,7 +266,7 @@ func buildRepo(registry, repo string) string { // No custom registry, just return the repo name return repo } - if strings.HasPrefix(repo, registry + "/") { + if strings.HasPrefix(repo, registry+"/") { // Repo already includes the registry prefix // For backward compatibility, we won't add the prefix again. return repo diff --git a/cmd/kaniko-ecr/main.go b/cmd/kaniko-ecr/main.go index 48fea83..f9c48c9 100644 --- a/cmd/kaniko-ecr/main.go +++ b/cmd/kaniko-ecr/main.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/drone/drone-kaniko/pkg/tagger" "io/ioutil" "os" "strings" @@ -71,18 +72,38 @@ func main() { Value: ".", EnvVar: "PLUGIN_CONTEXT", }, + cli.StringFlag{ + Name: "commit.ref", + Usage: "git commit ref", + EnvVar: "DRONE_COMMIT_REF", + }, + cli.StringFlag{ + Name: "repo.branch", + Usage: "repository default branch", + EnvVar: "DRONE_REPO_BRANCH", + }, cli.StringSliceFlag{ Name: "tags", Usage: "build tags", - Value: &cli.StringSlice{"latest"}, + Value: &cli.StringSlice{}, EnvVar: "PLUGIN_TAGS", FilePath: ".tags", }, cli.BoolFlag{ - Name: "auto_tag", + Name: "expand_tags", Usage: "enable for semver tagging", + EnvVar: "PLUGIN_EXPAND_TAGS", + }, + cli.BoolFlag{ + Name: "tags.auto", + Usage: "enable auto generate build tags", EnvVar: "PLUGIN_AUTO_TAG", }, + cli.StringFlag{ + Name: "tags.auto_suffix", + Usage: "the suffix of auto build tags", + EnvVar: "PLUGIN_AUTO_TAG_SUFFIX", + }, cli.StringSliceFlag{ Name: "args", Usage: "build args", @@ -240,12 +261,19 @@ func run(c *cli.Context) error { } } + enableAutoTag := c.Bool("tags.auto") + enableExpandTag := c.Bool("tags.expand") + tags, shouldSkipBuild, err := tagger.MaybeAutoTag(c.StringSlice("tags"), c.String("commit.ref"), c.String("tags.auto_suffix"), c.String("repo.branch"), enableAutoTag, enableExpandTag) + if shouldSkipBuild { + return err + } + plugin := kaniko.Plugin{ Build: kaniko.Build{ Dockerfile: c.String("dockerfile"), Context: c.String("context"), - Tags: c.StringSlice("tags"), - AutoTag: c.Bool("auto_tag"), + Tags: tags, + ExpandTag: !enableAutoTag && enableExpandTag, Args: c.StringSlice("args"), Target: c.String("target"), Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")), @@ -260,7 +288,7 @@ func run(c *cli.Context) error { Platform: c.String("platform"), }, Artifact: kaniko.Artifact{ - Tags: c.StringSlice("tags"), + Tags: tags, Repo: c.String("repo"), Registry: c.String("registry"), ArtifactFile: c.String("artifact-file"), diff --git a/cmd/kaniko-gcr/main.go b/cmd/kaniko-gcr/main.go index 1492a7b..caee07e 100644 --- a/cmd/kaniko-gcr/main.go +++ b/cmd/kaniko-gcr/main.go @@ -12,6 +12,7 @@ import ( kaniko "github.com/drone/drone-kaniko" "github.com/drone/drone-kaniko/pkg/artifact" + "github.com/drone/drone-kaniko/pkg/tagger" ) const ( @@ -52,18 +53,38 @@ func main() { Value: ".", EnvVar: "PLUGIN_CONTEXT", }, + cli.StringFlag{ + Name: "commit.ref", + Usage: "git commit ref", + EnvVar: "DRONE_COMMIT_REF", + }, + cli.StringFlag{ + Name: "repo.branch", + Usage: "repository default branch", + EnvVar: "DRONE_REPO_BRANCH", + }, cli.StringSliceFlag{ Name: "tags", Usage: "build tags", - Value: &cli.StringSlice{"latest"}, + Value: &cli.StringSlice{}, EnvVar: "PLUGIN_TAGS", FilePath: ".tags", }, cli.BoolFlag{ - Name: "auto_tag", + Name: "expand_tags", Usage: "enable for semver tagging", + EnvVar: "PLUGIN_EXPAND_TAGS", + }, + cli.BoolFlag{ + Name: "tags.auto", + Usage: "enable auto generate build tags", EnvVar: "PLUGIN_AUTO_TAG", }, + cli.StringFlag{ + Name: "tags.auto_suffix", + Usage: "the suffix of auto build tags", + EnvVar: "PLUGIN_AUTO_TAG_SUFFIX", + }, cli.StringSliceFlag{ Name: "args", Usage: "build args", @@ -155,12 +176,19 @@ func run(c *cli.Context) error { } } + enableAutoTag := c.Bool("tags.auto") + enableExpandTag := c.Bool("tags.expand") + tags, shouldSkipBuild, err := tagger.MaybeAutoTag(c.StringSlice("tags"), c.String("commit.ref"), c.String("tags.auto_suffix"), c.String("repo.branch"), enableAutoTag, enableExpandTag) + if shouldSkipBuild { + return err + } + plugin := kaniko.Plugin{ Build: kaniko.Build{ Dockerfile: c.String("dockerfile"), Context: c.String("context"), - Tags: c.StringSlice("tags"), - AutoTag: c.Bool("auto_tag"), + Tags: tags, + ExpandTag: !enableAutoTag && enableExpandTag, Args: c.StringSlice("args"), Target: c.String("target"), Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")), @@ -175,7 +203,7 @@ func run(c *cli.Context) error { Platform: c.String("platform"), }, Artifact: kaniko.Artifact{ - Tags: c.StringSlice("tags"), + Tags: tags, Repo: c.String("repo"), Registry: c.String("registry"), ArtifactFile: c.String("artifact-file"), diff --git a/go.mod b/go.mod index 7802806..23d75db 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ecr v1.4.3 github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.4.3 github.com/aws/smithy-go v1.7.0 + github.com/coreos/go-semver v0.3.0 github.com/google/go-cmp v0.5.6 github.com/joho/godotenv v1.3.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index c20fb37..81e7944 100644 --- a/go.sum +++ b/go.sum @@ -21,6 +21,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.6.2 h1:l504GWCoQi1Pk68vSUFGLmDIEMzRf github.com/aws/aws-sdk-go-v2/service/sts v1.6.2/go.mod h1:RBhoMJB8yFToaCnbe0jNq5Dcdy0jp6LhHqg55rjClkM= github.com/aws/smithy-go v1.7.0 h1:+cLHMRrDZvQ4wk+KuQ9yH6eEg6KZEJ9RI2IkDqnygCg= github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/kaniko.go b/kaniko.go index 78d1f97..98079ba 100644 --- a/kaniko.go +++ b/kaniko.go @@ -17,7 +17,7 @@ type ( Dockerfile string // Docker build Dockerfile Context string // Docker build context Tags []string // Docker build tags - AutoTag bool // Set this to create semver-tagged labels + ExpandTag bool // Set this to create semver-tagged labels Args []string // Docker build args Target string // Docker build target Repo string // Docker build repository @@ -49,7 +49,7 @@ type ( } ) -// labelsForTag returns the labels to use for the given tag, subject to the value of AutoTag. +// labelsForTag returns the labels to use for the given tag, subject to the value of ExpandTag. // // Build information (e.g. +linux_amd64) is carried through to all labels. // Pre-release information (e.g. -rc1) suppresses major and major+minor auto-labels. @@ -67,7 +67,7 @@ func (b Build) labelsForTag(tag string) (labels []string) { } // Pass through tags if auto-tag is not set, or if the tag is not a semantic version - if !b.AutoTag || !semver.IsValid(semverTag) { + if !b.ExpandTag || !semver.IsValid(semverTag) { return []string{tag} } tag = semverTag diff --git a/kaniko_test.go b/kaniko_test.go index 4bd1f47..dec4f13 100644 --- a/kaniko_test.go +++ b/kaniko_test.go @@ -8,65 +8,65 @@ import ( func TestBuild_labelsForTag(t *testing.T) { tests := []struct { - name string - tag string - autoTags []string + name string + tag string + expandTags []string }{ { - name: "semver", - tag: "v1.2.3", - autoTags: []string{"1", "1.2", "1.2.3"}, + name: "semver", + tag: "v1.2.3", + expandTags: []string{"1", "1.2", "1.2.3"}, }, { - name: "no_patch", - tag: "v1.2", - autoTags: []string{"1", "1.2", "1.2.0"}, + name: "no_patch", + tag: "v1.2", + expandTags: []string{"1", "1.2", "1.2.0"}, }, { - name: "only_major", - tag: "v1", - autoTags: []string{"1", "1.0", "1.0.0"}, + name: "only_major", + tag: "v1", + expandTags: []string{"1", "1.0", "1.0.0"}, }, { - name: "full_with_build", - tag: "v1.2.3+build-info", - autoTags: []string{"1+build-info", "1.2+build-info", "1.2.3+build-info"}, + name: "full_with_build", + tag: "v1.2.3+build-info", + expandTags: []string{"1+build-info", "1.2+build-info", "1.2.3+build-info"}, }, { - name: "build_with_underscores", - tag: "v1.2.3+linux_amd64", - autoTags: []string{"1+linux-amd64", "1.2+linux-amd64", "1.2.3+linux-amd64"}, + name: "build_with_underscores", + tag: "v1.2.3+linux_amd64", + expandTags: []string{"1+linux-amd64", "1.2+linux-amd64", "1.2.3+linux-amd64"}, }, { - name: "prerelease", - tag: "v1.2.3-rc1", - autoTags: []string{"1.2.3-rc1"}, + name: "prerelease", + tag: "v1.2.3-rc1", + expandTags: []string{"1.2.3-rc1"}, }, { - name: "prerelease_with_build", - tag: "v1.2.3-rc1+bld", - autoTags: []string{"1.2.3-rc1+bld"}, + name: "prerelease_with_build", + tag: "v1.2.3-rc1+bld", + expandTags: []string{"1.2.3-rc1+bld"}, }, { - name: "invalid_build", - tag: "v1+bld", // can only include build detail with all three elements - autoTags: []string{"v1+bld"}, + name: "invalid_build", + tag: "v1+bld", // can only include build detail with all three elements + expandTags: []string{"v1+bld"}, }, { - name: "accidental_non_semver", - tag: "1.2.3", - autoTags: []string{"1", "1.2", "1.2.3"}, + name: "accidental_non_semver", + tag: "1.2.3", + expandTags: []string{"1", "1.2", "1.2.3"}, }, { - name: "non_semver", - tag: "latest", - autoTags: []string{"latest"}, + name: "non_semver", + tag: "latest", + expandTags: []string{"latest"}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - tags := Build{AutoTag: true}.labelsForTag(tt.tag) - if got, want := tags, tt.autoTags; !cmp.Equal(got, want) { + tags := Build{ExpandTag: true}.labelsForTag(tt.tag) + if got, want := tags, tt.expandTags; !cmp.Equal(got, want) { t.Errorf("tagsFor(%q) = %q, want %q", tt.tag, got, want) } }) diff --git a/pkg/tagger/tagger.go b/pkg/tagger/tagger.go new file mode 100644 index 0000000..ad1e514 --- /dev/null +++ b/pkg/tagger/tagger.go @@ -0,0 +1,116 @@ +// A fork of https://github.com/drone-plugins/drone-docker/blob/master/tags.go + +package tagger + +import ( + "fmt" + "strings" + + "github.com/coreos/go-semver/semver" + "github.com/sirupsen/logrus" +) + +// AutoTagsSuffix returns a set of default suggested tags +// based on the commit ref with an attached suffix. +func AutoTagsSuffix(ref, suffix string) ([]string, error) { + tags, err := AutoTags(ref) + if err != nil { + return nil, err + } + if len(suffix) == 0 { + return tags, nil + } + for i, tag := range tags { + if tag == "latest" { + tags[i] = suffix + } else { + tags[i] = fmt.Sprintf("%s-%s", tag, suffix) + } + } + return tags, nil +} + +func splitOff(input string, delim string) string { + parts := strings.SplitN(input, delim, 2) + + if len(parts) == 2 { + return parts[0] + } + + return input +} + +// AutoTags returns a set of default suggested tags based on +// the commit ref. +func AutoTags(ref string) ([]string, error) { + if !strings.HasPrefix(ref, "refs/tags/") { + return []string{"latest"}, nil + } + v := stripTagPrefix(ref) + version, err := semver.NewVersion(v) + if err != nil { + return []string{"latest"}, err + } + if version.PreRelease != "" || version.Metadata != "" { + return []string{ + version.String(), + }, nil + } + + v = stripTagPrefix(ref) + v = splitOff(splitOff(v, "+"), "-") + dotParts := strings.SplitN(v, ".", 3) + + if version.Major == 0 { + return []string{ + fmt.Sprintf("%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor), + fmt.Sprintf("%0*d.%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor, len(dotParts[2]), version.Patch), + }, nil + } + return []string{ + fmt.Sprintf("%0*d", len(dotParts[0]), version.Major), + fmt.Sprintf("%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor), + fmt.Sprintf("%0*d.%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor, len(dotParts[2]), version.Patch), + }, nil +} + +// UseAutoTag for keep only default branch for latest tag +func UseAutoTag(ref, defaultBranch string) bool { + if strings.HasPrefix(ref, "refs/tags/") { + return true + } + if stripHeadPrefix(ref) == defaultBranch { + return true + } + return false +} + +func stripHeadPrefix(ref string) string { + return strings.TrimPrefix(ref, "refs/heads/") +} + +func stripTagPrefix(ref string) string { + ref = strings.TrimPrefix(ref, "refs/tags/") + ref = strings.TrimPrefix(ref, "v") + return ref +} + +func MaybeAutoTag(tags []string, ref string, autoTagSuffix string, defaultBranch string, enableAutoTag bool, enableExpandTag bool) (resultTags []string, shouldSkipBuild bool, err error) { + if enableAutoTag && (len(tags) > 0 || enableExpandTag) { + err = fmt.Errorf("auto_tag cannot be enabled along with tags or expand_tags") + } else if enableAutoTag { + if !UseAutoTag(ref, defaultBranch) { + logrus.Infof("skipping automated docker build for %s", ref) + err = nil + } else { + tmp_tags, err := AutoTagsSuffix(ref, autoTagSuffix) + if err == nil { + resultTags = tmp_tags + } else { + logrus.Errorf("cannot build docker image for %s, invalid semantic version", ref) + } + } + } + shouldSkipBuild = len(resultTags) == 0 + return +} diff --git a/pkg/tagger/tagger_test.go b/pkg/tagger/tagger_test.go new file mode 100644 index 0000000..fddc8aa --- /dev/null +++ b/pkg/tagger/tagger_test.go @@ -0,0 +1,199 @@ +// A fork of https://github.com/drone-plugins/drone-docker/blob/master/tags_test.go + +package tagger + +import ( + "reflect" + "testing" +) + +func Test_stripTagPrefix(t *testing.T) { + var tests = []struct { + Before string + After string + }{ + {"refs/tags/1.0.0", "1.0.0"}, + {"refs/tags/v1.0.0", "1.0.0"}, + {"v1.0.0", "1.0.0"}, + } + + for _, test := range tests { + got, want := stripTagPrefix(test.Before), test.After + if got != want { + t.Errorf("Got tag %s, want %s", got, want) + } + } +} + +func TestAutoTags(t *testing.T) { + var tests = []struct { + Before string + After []string + }{ + {"", []string{"latest"}}, + {"refs/heads/master", []string{"latest"}}, + {"refs/tags/0.9.0", []string{"0.9", "0.9.0"}}, + {"refs/tags/1.0.0", []string{"1", "1.0", "1.0.0"}}, + {"refs/tags/v1.0.0", []string{"1", "1.0", "1.0.0"}}, + {"refs/tags/v1.0.0-alpha.1", []string{"1.0.0-alpha.1"}}, + } + + for _, test := range tests { + tags, err := AutoTags(test.Before) + if err != nil { + t.Error(err) + continue + } + got, want := tags, test.After + if !reflect.DeepEqual(got, want) { + t.Errorf("Got tag %v, want %v", got, want) + } + } +} + +func TestAutoTagsError(t *testing.T) { + var tests = []string{ + "refs/tags/x1.0.0", + "refs/tags/20190203", + } + + for _, test := range tests { + _, err := AutoTags(test) + if err == nil { + t.Errorf("Expect tag error for %s", test) + } + } +} + +func TestAutoTagsSuffix(t *testing.T) { + var tests = []struct { + Before string + Suffix string + After []string + }{ + // without suffix + { + After: []string{"latest"}, + }, + { + Before: "refs/tags/v1.0.0", + After: []string{ + "1", + "1.0", + "1.0.0", + }, + }, + // with suffix + { + Suffix: "linux-amd64", + After: []string{"linux-amd64"}, + }, + { + Before: "refs/tags/v1.0.0", + Suffix: "linux-amd64", + After: []string{ + "1-linux-amd64", + "1.0-linux-amd64", + "1.0.0-linux-amd64", + }, + }, + { + Suffix: "nanoserver", + After: []string{"nanoserver"}, + }, + { + Before: "refs/tags/v1.9.2", + Suffix: "nanoserver", + After: []string{ + "1-nanoserver", + "1.9-nanoserver", + "1.9.2-nanoserver", + }, + }, + { + Before: "refs/tags/v18.06.0", + Suffix: "nanoserver", + After: []string{ + "18-nanoserver", + "18.06-nanoserver", + "18.06.0-nanoserver", + }, + }, + } + + for _, test := range tests { + tag, err := AutoTagsSuffix(test.Before, test.Suffix) + if err != nil { + t.Error(err) + continue + } + got, want := tag, test.After + if !reflect.DeepEqual(got, want) { + t.Errorf("Got tag %v, want %v", got, want) + } + } +} + +func Test_stripHeadPrefix(t *testing.T) { + type args struct { + ref string + } + tests := []struct { + args args + want string + }{ + { + args: args{ + ref: "refs/heads/master", + }, + want: "master", + }, + } + for _, tt := range tests { + if got := stripHeadPrefix(tt.args.ref); got != tt.want { + t.Errorf("stripHeadPrefix() = %v, want %v", got, tt.want) + } + } +} + +func TestUseAutoTag(t *testing.T) { + type args struct { + ref string + defaultBranch string + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "latest tag for default branch", + args: args{ + ref: "refs/heads/master", + defaultBranch: "master", + }, + want: true, + }, + { + name: "build from tags", + args: args{ + ref: "refs/tags/v1.0.0", + defaultBranch: "master", + }, + want: true, + }, + { + name: "skip build for not default branch", + args: args{ + ref: "refs/heads/develop", + defaultBranch: "master", + }, + want: false, + }, + } + for _, tt := range tests { + if got := UseAutoTag(tt.args.ref, tt.args.defaultBranch); got != tt.want { + t.Errorf("%q. UseAutoTag() = %v, want %v", tt.name, got, tt.want) + } + } +} From 79916ff0b64eed87d8f7ce8a5f12a7dfc0646bdc Mon Sep 17 00:00:00 2001 From: Sinkerine Date: Tue, 8 Feb 2022 21:09:20 -0800 Subject: [PATCH 2/3] Change how --auto-tag flag works with other flags The --auto-tag has to be a breaking change. This commit limit the breaking impact to the users who enable the flag. Behaviors of flag combination after this commit: * --auto-tag=false: No changes. * --auto-tag=false,--expand-tag=true,tags=1.0.0: * Old behavior: Should not happen. --expand-tag didn't exist. * New Behavior: Build with [1,1.0,1.0.0] tags. * --auto-tag=true * Old behavior: Build with the "latest" tag. * New behavior: Build with auto detected tags. Abort if auto detection failed. * --auto-tag=true,tags=latest: same as "--auto-tag=true". * --auto-tag=true,tags=1.0.0: * Old behavior: Build with [1,1.0,1.0.0] tags. * New behavior: Abort the build with an error message. * --auto-tag=true,--expand-tag=true,tags=1.0.0: Abort the build with an error message. Also added a test for the integration of the BUILD struct and the tagger package, which is used by kaniko.go. --- cmd/kaniko-docker/main.go | 68 ++++++++++++++++----------------- cmd/kaniko-ecr/main.go | 66 +++++++++++++++----------------- cmd/kaniko-gcr/main.go | 66 +++++++++++++++----------------- kaniko.go | 79 +++++++++++++++++++++++++++++---------- kaniko_test.go | 67 +++++++++++++++++++++++++++++++++ pkg/tagger/tagger.go | 23 +----------- 6 files changed, 222 insertions(+), 147 deletions(-) diff --git a/cmd/kaniko-docker/main.go b/cmd/kaniko-docker/main.go index 535fccf..7f10884 100644 --- a/cmd/kaniko-docker/main.go +++ b/cmd/kaniko-docker/main.go @@ -14,7 +14,6 @@ import ( kaniko "github.com/drone/drone-kaniko" "github.com/drone/drone-kaniko/pkg/artifact" - "github.com/drone/drone-kaniko/pkg/tagger" ) const ( @@ -60,34 +59,34 @@ func main() { EnvVar: "PLUGIN_CONTEXT", }, cli.StringFlag{ - Name: "commit.ref", - Usage: "git commit ref", + Name: "drone-commit-ref", + Usage: "git commit ref passed by Drone", EnvVar: "DRONE_COMMIT_REF", }, cli.StringFlag{ - Name: "repo.branch", - Usage: "repository default branch", + Name: "drone-repo-branch", + Usage: "git repository default branch passed by Drone", EnvVar: "DRONE_REPO_BRANCH", }, cli.StringSliceFlag{ Name: "tags", Usage: "build tags", - Value: &cli.StringSlice{}, + Value: &cli.StringSlice{"latest"}, EnvVar: "PLUGIN_TAGS", FilePath: ".tags", }, cli.BoolFlag{ - Name: "tag.expand", + Name: "expand-tag", Usage: "enable for semver tagging", - EnvVar: "PLUGIN_EXPAND_TAGS", + EnvVar: "PLUGIN_EXPAND_TAG", }, cli.BoolFlag{ - Name: "tags.auto", - Usage: "enable auto generate build tags", + Name: "auto-tag", + Usage: "enable auto generation of build tags", EnvVar: "PLUGIN_AUTO_TAG", }, cli.StringFlag{ - Name: "tags.auto_suffix", + Name: "auto-tag-suffix", Usage: "the suffix of auto build tags", EnvVar: "PLUGIN_AUTO_TAG_SUFFIX", }, @@ -190,35 +189,32 @@ func run(c *cli.Context) error { } } - enableAutoTag := c.Bool("tags.auto") - enableExpandTag := c.Bool("tags.expand") - tags, shouldSkipBuild, err := tagger.MaybeAutoTag(c.StringSlice("tags"), c.String("commit.ref"), c.String("tags.auto_suffix"), c.String("repo.branch"), enableAutoTag, enableExpandTag) - if shouldSkipBuild { - return err - } - plugin := kaniko.Plugin{ Build: kaniko.Build{ - Dockerfile: c.String("dockerfile"), - Context: c.String("context"), - Tags: tags, - ExpandTag: !enableAutoTag && enableExpandTag, - Args: c.StringSlice("args"), - Target: c.String("target"), - Repo: c.String("repo"), - Labels: c.StringSlice("custom-labels"), - SkipTlsVerify: c.Bool("skip-tls-verify"), - SnapshotMode: c.String("snapshot-mode"), - EnableCache: c.Bool("enable-cache"), - CacheRepo: c.String("cache-repo"), - CacheTTL: c.Int("cache-ttl"), - DigestFile: defaultDigestFile, - NoPush: noPush, - Verbosity: c.String("verbosity"), - Platform: c.String("platform"), + DroneCommitRef: c.String("drone-commit-ref"), + DroneRepoBranch: c.String("drone-repo-branch"), + Dockerfile: c.String("dockerfile"), + Context: c.String("context"), + Tags: c.StringSlice("tags"), + AutoTag: c.Bool("auto-tag"), + AutoTagSuffix: c.String("auto-tag-suffix"), + ExpandTag: c.Bool("expand-tag"), + Args: c.StringSlice("args"), + Target: c.String("target"), + Repo: c.String("repo"), + Labels: c.StringSlice("custom-labels"), + SkipTlsVerify: c.Bool("skip-tls-verify"), + SnapshotMode: c.String("snapshot-mode"), + EnableCache: c.Bool("enable-cache"), + CacheRepo: c.String("cache-repo"), + CacheTTL: c.Int("cache-ttl"), + DigestFile: defaultDigestFile, + NoPush: noPush, + Verbosity: c.String("verbosity"), + Platform: c.String("platform"), }, Artifact: kaniko.Artifact{ - Tags: tags, + Tags: c.StringSlice("tags"), Repo: buildRepo(c.String("registry"), c.String("repo")), Registry: c.String("registry"), ArtifactFile: c.String("artifact-file"), diff --git a/cmd/kaniko-ecr/main.go b/cmd/kaniko-ecr/main.go index f9c48c9..7f35e93 100644 --- a/cmd/kaniko-ecr/main.go +++ b/cmd/kaniko-ecr/main.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/drone/drone-kaniko/pkg/tagger" "io/ioutil" "os" "strings" @@ -73,34 +72,34 @@ func main() { EnvVar: "PLUGIN_CONTEXT", }, cli.StringFlag{ - Name: "commit.ref", - Usage: "git commit ref", + Name: "drone-commit-ref", + Usage: "git commit ref passed by Drone", EnvVar: "DRONE_COMMIT_REF", }, cli.StringFlag{ - Name: "repo.branch", - Usage: "repository default branch", + Name: "drone-repo-branch", + Usage: "git repository default branch passed by Drone", EnvVar: "DRONE_REPO_BRANCH", }, cli.StringSliceFlag{ Name: "tags", Usage: "build tags", - Value: &cli.StringSlice{}, + Value: &cli.StringSlice{"latest"}, EnvVar: "PLUGIN_TAGS", FilePath: ".tags", }, cli.BoolFlag{ - Name: "expand_tags", + Name: "expand-tag", Usage: "enable for semver tagging", - EnvVar: "PLUGIN_EXPAND_TAGS", + EnvVar: "PLUGIN_EXPAND_TAG", }, cli.BoolFlag{ - Name: "tags.auto", - Usage: "enable auto generate build tags", + Name: "auto-tag", + Usage: "enable auto generation of build tags", EnvVar: "PLUGIN_AUTO_TAG", }, cli.StringFlag{ - Name: "tags.auto_suffix", + Name: "auto-tag-suffix", Usage: "the suffix of auto build tags", EnvVar: "PLUGIN_AUTO_TAG_SUFFIX", }, @@ -261,34 +260,31 @@ func run(c *cli.Context) error { } } - enableAutoTag := c.Bool("tags.auto") - enableExpandTag := c.Bool("tags.expand") - tags, shouldSkipBuild, err := tagger.MaybeAutoTag(c.StringSlice("tags"), c.String("commit.ref"), c.String("tags.auto_suffix"), c.String("repo.branch"), enableAutoTag, enableExpandTag) - if shouldSkipBuild { - return err - } - plugin := kaniko.Plugin{ Build: kaniko.Build{ - Dockerfile: c.String("dockerfile"), - Context: c.String("context"), - Tags: tags, - ExpandTag: !enableAutoTag && enableExpandTag, - Args: c.StringSlice("args"), - Target: c.String("target"), - Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")), - Labels: c.StringSlice("custom-labels"), - SnapshotMode: c.String("snapshot-mode"), - EnableCache: c.Bool("enable-cache"), - CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")), - CacheTTL: c.Int("cache-ttl"), - DigestFile: defaultDigestFile, - NoPush: noPush, - Verbosity: c.String("verbosity"), - Platform: c.String("platform"), + DroneCommitRef: c.String("drone-commit-ref"), + DroneRepoBranch: c.String("drone-repo-branch"), + Dockerfile: c.String("dockerfile"), + Context: c.String("context"), + Tags: c.StringSlice("tags"), + AutoTag: c.Bool("auto-tag"), + AutoTagSuffix: c.String("auto-tag-suffix"), + ExpandTag: c.Bool("expand-tag"), + Args: c.StringSlice("args"), + Target: c.String("target"), + Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")), + Labels: c.StringSlice("custom-labels"), + SnapshotMode: c.String("snapshot-mode"), + EnableCache: c.Bool("enable-cache"), + CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")), + CacheTTL: c.Int("cache-ttl"), + DigestFile: defaultDigestFile, + NoPush: noPush, + Verbosity: c.String("verbosity"), + Platform: c.String("platform"), }, Artifact: kaniko.Artifact{ - Tags: tags, + Tags: c.StringSlice("tags"), Repo: c.String("repo"), Registry: c.String("registry"), ArtifactFile: c.String("artifact-file"), diff --git a/cmd/kaniko-gcr/main.go b/cmd/kaniko-gcr/main.go index caee07e..ed6eaa2 100644 --- a/cmd/kaniko-gcr/main.go +++ b/cmd/kaniko-gcr/main.go @@ -12,7 +12,6 @@ import ( kaniko "github.com/drone/drone-kaniko" "github.com/drone/drone-kaniko/pkg/artifact" - "github.com/drone/drone-kaniko/pkg/tagger" ) const ( @@ -54,34 +53,34 @@ func main() { EnvVar: "PLUGIN_CONTEXT", }, cli.StringFlag{ - Name: "commit.ref", - Usage: "git commit ref", + Name: "drone-commit-ref", + Usage: "git commit ref passed by Drone", EnvVar: "DRONE_COMMIT_REF", }, cli.StringFlag{ - Name: "repo.branch", - Usage: "repository default branch", + Name: "drone-repo-branch", + Usage: "git repository default branch passed by Drone", EnvVar: "DRONE_REPO_BRANCH", }, cli.StringSliceFlag{ Name: "tags", Usage: "build tags", - Value: &cli.StringSlice{}, + Value: &cli.StringSlice{"latest"}, EnvVar: "PLUGIN_TAGS", FilePath: ".tags", }, cli.BoolFlag{ - Name: "expand_tags", + Name: "expand-tag", Usage: "enable for semver tagging", - EnvVar: "PLUGIN_EXPAND_TAGS", + EnvVar: "PLUGIN_EXPAND_TAG", }, cli.BoolFlag{ - Name: "tags.auto", - Usage: "enable auto generate build tags", + Name: "auto-tag", + Usage: "enable auto generation of build tags", EnvVar: "PLUGIN_AUTO_TAG", }, cli.StringFlag{ - Name: "tags.auto_suffix", + Name: "auto-tag-suffix", Usage: "the suffix of auto build tags", EnvVar: "PLUGIN_AUTO_TAG_SUFFIX", }, @@ -176,34 +175,31 @@ func run(c *cli.Context) error { } } - enableAutoTag := c.Bool("tags.auto") - enableExpandTag := c.Bool("tags.expand") - tags, shouldSkipBuild, err := tagger.MaybeAutoTag(c.StringSlice("tags"), c.String("commit.ref"), c.String("tags.auto_suffix"), c.String("repo.branch"), enableAutoTag, enableExpandTag) - if shouldSkipBuild { - return err - } - plugin := kaniko.Plugin{ Build: kaniko.Build{ - Dockerfile: c.String("dockerfile"), - Context: c.String("context"), - Tags: tags, - ExpandTag: !enableAutoTag && enableExpandTag, - Args: c.StringSlice("args"), - Target: c.String("target"), - Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")), - Labels: c.StringSlice("custom-labels"), - SnapshotMode: c.String("snapshot-mode"), - EnableCache: c.Bool("enable-cache"), - CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")), - CacheTTL: c.Int("cache-ttl"), - DigestFile: defaultDigestFile, - NoPush: noPush, - Verbosity: c.String("verbosity"), - Platform: c.String("platform"), + DroneCommitRef: c.String("drone-commit-ref"), + DroneRepoBranch: c.String("drone-repo-branch"), + Dockerfile: c.String("dockerfile"), + Context: c.String("context"), + Tags: c.StringSlice("tags"), + AutoTag: c.Bool("auto-tag"), + AutoTagSuffix: c.String("auto-tag-suffix"), + ExpandTag: c.Bool("expand-tag"), + Args: c.StringSlice("args"), + Target: c.String("target"), + Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")), + Labels: c.StringSlice("custom-labels"), + SnapshotMode: c.String("snapshot-mode"), + EnableCache: c.Bool("enable-cache"), + CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")), + CacheTTL: c.Int("cache-ttl"), + DigestFile: defaultDigestFile, + NoPush: noPush, + Verbosity: c.String("verbosity"), + Platform: c.String("platform"), }, Artifact: kaniko.Artifact{ - Tags: tags, + Tags: c.StringSlice("tags"), Repo: c.String("repo"), Registry: c.String("registry"), ArtifactFile: c.String("artifact-file"), diff --git a/kaniko.go b/kaniko.go index 98079ba..b28b588 100644 --- a/kaniko.go +++ b/kaniko.go @@ -8,29 +8,34 @@ import ( "strings" "github.com/drone/drone-kaniko/pkg/artifact" + "github.com/drone/drone-kaniko/pkg/tagger" "golang.org/x/mod/semver" ) type ( // Build defines Docker build parameters. Build struct { - Dockerfile string // Docker build Dockerfile - Context string // Docker build context - Tags []string // Docker build tags - ExpandTag bool // Set this to create semver-tagged labels - Args []string // Docker build args - Target string // Docker build target - Repo string // Docker build repository - Labels []string // Label map - SkipTlsVerify bool // Docker skip tls certificate verify for registry - SnapshotMode string // Kaniko snapshot mode - EnableCache bool // Whether to enable kaniko cache - CacheRepo string // Remote repository that will be used to store cached layers - CacheTTL int // Cache timeout in hours - DigestFile string // Digest file location - NoPush bool // Set this flag if you only want to build the image, without pushing to a registry - Verbosity string // Log level - Platform string // Allows to build with another default platform than the host, similarly to docker build --platform + DroneCommitRef string // Drone git commit reference + DroneRepoBranch string // Drone repo branch + Dockerfile string // Docker build Dockerfile + Context string // Docker build context + Tags []string // Docker build tags + AutoTag bool // Set this to auto detect tags from git commits and semver-tagged labels + AutoTagSuffix string // Suffix to append to the auto detect tags + ExpandTag bool // Set this to expand the `Tags` into semver-tagged labels + Args []string // Docker build args + Target string // Docker build target + Repo string // Docker build repository + Labels []string // Label map + SkipTlsVerify bool // Docker skip tls certificate verify for registry + SnapshotMode string // Kaniko snapshot mode + EnableCache bool // Whether to enable kaniko cache + CacheRepo string // Remote repository that will be used to store cached layers + CacheTTL int // Cache timeout in hours + DigestFile string // Digest file location + NoPush bool // Set this flag if you only want to build the image, without pushing to a registry + Verbosity string // Log level + Platform string // Allows to build with another default platform than the host, similarly to docker build --platform } // Artifact defines content of artifact file @@ -66,7 +71,7 @@ func (b Build) labelsForTag(tag string) (labels []string) { semverTag = withV } - // Pass through tags if auto-tag is not set, or if the tag is not a semantic version + // Pass through tags if expand-tag is not set, or if the tag is not a semantic version if !b.ExpandTag || !semver.IsValid(semverTag) { return []string{tag} } @@ -90,6 +95,30 @@ func (b Build) labelsForTag(tag string) (labels []string) { } } +// Returns the auto detected tags. See the AutoTag section of +// https://plugins.drone.io/drone-plugins/drone-docker/ for more info. +func (b Build) AutoTags() (tags []string, err error) { + if len(b.Tags) > 1 || len(b.Tags) == 1 && b.Tags[0] != "latest" { + err = fmt.Errorf("The auto-tag flag does not work with user provided tags %s", b.Tags) + return + } + // We have tried the best to prevent enabling auto-tag and passing in + // user specified at the same time. Starts to auto detect tags. + // Note: passing in a "latest" tag with auto-tag enabled won't trigger the + // early returns above, because we cannot tell if the tag is provided by + // the default value of by the users. + commitRef := b.DroneCommitRef + if !tagger.UseAutoTag(commitRef, b.DroneRepoBranch) { + err = fmt.Errorf("Could not auto detect the tag. Skipping automated docker build for commit %s", commitRef) + return + } + tags, err = tagger.AutoTagsSuffix(commitRef, b.AutoTagSuffix) + if err != nil { + err = fmt.Errorf("Invalid semantic version when auto detecting the tag. Skipping automated docker build for %s.", commitRef) + } + return +} + // Exec executes the plugin step func (p Plugin) Exec() error { if !p.Build.NoPush && p.Build.Repo == "" { @@ -100,6 +129,18 @@ func (p Plugin) Exec() error { return fmt.Errorf("dockerfile does not exist at path: %s", p.Build.Dockerfile) } + var tags = p.Build.Tags + if p.Build.AutoTag && p.Build.ExpandTag { + return fmt.Errorf("The auto-tag flag conflicts with the expand-tag flag") + } + if p.Build.AutoTag { + var err error + tags, err = p.Build.AutoTags() + if err != nil { + return err + } + } + cmdArgs := []string{ fmt.Sprintf("--dockerfile=%s", p.Build.Dockerfile), fmt.Sprintf("--context=dir://%s", p.Build.Context), @@ -107,7 +148,7 @@ func (p Plugin) Exec() error { // Set the destination repository if !p.Build.NoPush { - for _, tag := range p.Build.Tags { + for _, tag := range tags { for _, label := range p.Build.labelsForTag(tag) { cmdArgs = append(cmdArgs, fmt.Sprintf("--destination=%s:%s", p.Build.Repo, label)) } diff --git a/kaniko_test.go b/kaniko_test.go index dec4f13..8b87252 100644 --- a/kaniko_test.go +++ b/kaniko_test.go @@ -72,3 +72,70 @@ func TestBuild_labelsForTag(t *testing.T) { }) } } + +func TestBuild_AutoTags(t *testing.T) { + tests := []struct { + name string + repoBranch string + commitRef string + autoTagSuffix string + expectedTags []string + }{ + { + name: "commit push", + repoBranch: "master", + commitRef: "refs/heads/master", + autoTagSuffix: "", + expectedTags: []string{"latest"}, + }, + { + name: "tag push", + repoBranch: "master", + commitRef: "refs/tags/v1.0.0", + autoTagSuffix: "", + expectedTags: []string{ + "1", + "1.0", + "1.0.0", + }, + }, + { + name: "tag push", + repoBranch: "master", + commitRef: "refs/tags/v1.0.0", + autoTagSuffix: "linux-amd64", + expectedTags: []string{ + "1-linux-amd64", + "1.0-linux-amd64", + "1.0.0-linux-amd64", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + b := Build{DroneCommitRef: tt.commitRef, DroneRepoBranch: tt.repoBranch, AutoTag: true} + if tt.autoTagSuffix != "" { + b.AutoTagSuffix = tt.autoTagSuffix + } + tags, err := b.AutoTags() + if err != nil { + t.Errorf("Unexpected err %q", err) + } + if got, want := tags, tt.expectedTags; !cmp.Equal(got, want) { + t.Errorf("auto detected tags = %q, wanted = %q", got, want) + } + }) + } + t.Run("flag conflict", func(t *testing.T) { + b := Build{ + DroneCommitRef: "refs/tags/v1.0.0", + DroneRepoBranch: "master", + AutoTag: true, + Tags: []string{"v1"}, + } + _, err := b.AutoTags() + if err == nil { + t.Errorf("Expect flag conflict error") + } + }) +} diff --git a/pkg/tagger/tagger.go b/pkg/tagger/tagger.go index ad1e514..bb0720c 100644 --- a/pkg/tagger/tagger.go +++ b/pkg/tagger/tagger.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/coreos/go-semver/semver" - "github.com/sirupsen/logrus" ) // AutoTagsSuffix returns a set of default suggested tags @@ -74,7 +73,7 @@ func AutoTags(ref string) ([]string, error) { }, nil } -// UseAutoTag for keep only default branch for latest tag +// UseAutoTag for keep only default branch for latest tag. func UseAutoTag(ref, defaultBranch string) bool { if strings.HasPrefix(ref, "refs/tags/") { return true @@ -94,23 +93,3 @@ func stripTagPrefix(ref string) string { ref = strings.TrimPrefix(ref, "v") return ref } - -func MaybeAutoTag(tags []string, ref string, autoTagSuffix string, defaultBranch string, enableAutoTag bool, enableExpandTag bool) (resultTags []string, shouldSkipBuild bool, err error) { - if enableAutoTag && (len(tags) > 0 || enableExpandTag) { - err = fmt.Errorf("auto_tag cannot be enabled along with tags or expand_tags") - } else if enableAutoTag { - if !UseAutoTag(ref, defaultBranch) { - logrus.Infof("skipping automated docker build for %s", ref) - err = nil - } else { - tmp_tags, err := AutoTagsSuffix(ref, autoTagSuffix) - if err == nil { - resultTags = tmp_tags - } else { - logrus.Errorf("cannot build docker image for %s, invalid semantic version", ref) - } - } - } - shouldSkipBuild = len(resultTags) == 0 - return -} From 011a6d47a245b48f4826a72f40a69d471e50fa1a Mon Sep 17 00:00:00 2001 From: Sinkerine Date: Tue, 8 Feb 2022 21:53:12 -0800 Subject: [PATCH 3/3] Update readme to note that expand-tag and auto-tag don't support artifacts --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dfe86a0..1ba2cbd 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,9 @@ docker run --rm \ plugins/kaniko:linux-amd64 ``` -With expanded tagging enabled, semantic versions can be passed to PLUGIN_TAGS directly for expansion: +With expanded tagging enabled, semantic versions can be passed to PLUGIN_TAGS directly for expansion. + +**Note**: this feature only works for build labels. Artifact labels are not supported. ```console docker run --rm \ @@ -84,10 +86,12 @@ docker run --rm \ ``` ### Auto Tagging -The [auto tag feature](https://plugins.drone.io/drone-plugins/drone-docker/) of docker plugin is also supported. +The [auto tag feature](https://plugins.drone.io/drone-plugins/drone-docker/** of docker plugin is also supported. When auto tagging is enabled, if any of the case is matched below, a docker build will be pushed with auto generated tags. Otherwise the docker build will be skipped. +**Note**: this feature only works for build labels. Artifact labels are not supported. + #### Git Tag Push: ```console