0
0
mirror of https://github.com/thegeeklab/wp-docker-buildx.git synced 2024-11-28 08:10:36 +00:00

refactor: add more linters and fix findings (#195)

This commit is contained in:
Robert Kaussow 2023-02-08 10:13:28 +01:00 committed by GitHub
parent 3f12a30324
commit 0688b1cf1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 229 additions and 76 deletions

View File

@ -8,7 +8,7 @@ platform:
steps: steps:
- name: deps - name: deps
image: golang:1.19 image: golang:1.20
commands: commands:
- make deps - make deps
volumes: volumes:
@ -16,7 +16,7 @@ steps:
path: /go path: /go
- name: lint - name: lint
image: golang:1.19 image: golang:1.20
commands: commands:
- make lint - make lint
volumes: volumes:
@ -24,7 +24,7 @@ steps:
path: /go path: /go
- name: test - name: test
image: golang:1.19 image: golang:1.20
commands: commands:
- make test - make test
volumes: volumes:
@ -51,7 +51,7 @@ platform:
steps: steps:
- name: build - name: build
image: techknowlogick/xgo:go-1.19.x image: techknowlogick/xgo:go-1.20.x
commands: commands:
- ln -s /drone/src /source - ln -s /drone/src /source
- make release - make release
@ -286,6 +286,6 @@ depends_on:
--- ---
kind: signature kind: signature
hmac: 5e54d2041c971a61b9545f50d3eb303541de10ef02f6ecf9f5043c49e2827657 hmac: 99430572409aea6256230c2812e815fc98a8f5bba518455a4472f981817eba77
... ...

View File

@ -1,25 +1,92 @@
linters: linters:
enable:
- gosimple
- deadcode
- typecheck
- govet
- errcheck
- staticcheck
- unused
- structcheck
- varcheck
- dupl
- gofmt
- misspell
- gocritic
- bidichk
- ineffassign
- revive
- gofumpt
- depguard
enable-all: false enable-all: false
disable-all: true disable-all: true
enable:
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- typecheck
- unused
- asasalint
- asciicheck
- bidichk
- bodyclose
- containedctx
- contextcheck
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- errchkjson
- errname
- errorlint
- execinquery
- exhaustive
- exportloopref
- forcetypeassert
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- goerr113
- gofmt
- gofumpt
- goheader
- goimports
- gomnd
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- grouper
- importas
- interfacebloat
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- misspell
- musttag
- nakedret
- nestif
- nilerr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- prealloc
- predeclared
- promlinter
- reassign
- revive
# - rowserrcheck
# - sqlclosecheck
# - structcheck
- stylecheck
- tagliatelle
- tenv
- testableexamples
- thelper
- tparallel
- unconvert
- unparam
- usestdlibvars
# - wastedassign
- whitespace
- wsl
fast: false fast: false
run: run:
@ -28,4 +95,4 @@ run:
linters-settings: linters-settings:
gofumpt: gofumpt:
extra-rules: true extra-rules: true
lang-version: "1.18" lang-version: "1.20"

View File

@ -19,7 +19,7 @@ GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(G
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
GENERATE ?= GENERATE ?=
XGO_VERSION := go-1.19.x XGO_VERSION := go-1.20.x
XGO_TARGETS ?= linux/amd64,linux/arm64 XGO_TARGETS ?= linux/amd64,linux/arm64
TARGETOS ?= linux TARGETOS ?= linux

View File

@ -7,6 +7,8 @@ import (
) )
// settingsFlags has the cli.Flags for the plugin.Settings. // settingsFlags has the cli.Flags for the plugin.Settings.
//
//nolint:maintidx
func settingsFlags(settings *plugin.Settings, category string) []cli.Flag { func settingsFlags(settings *plugin.Settings, category string) []cli.Flag {
return []cli.Flag{ return []cli.Flag{
&cli.BoolFlag{ &cli.BoolFlag{

View File

@ -1,6 +1,7 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
@ -13,11 +14,14 @@ import (
"github.com/thegeeklab/drone-plugin-lib/v2/urfave" "github.com/thegeeklab/drone-plugin-lib/v2/urfave"
) )
//nolint:gochecknoglobals
var ( var (
BuildVersion = "devel" BuildVersion = "devel"
BuildDate = "00000000" BuildDate = "00000000"
) )
var ErrTypeAssertionFailed = errors.New("type assertion failed")
func main() { func main() {
settings := &plugin.Settings{} settings := &plugin.Settings{}
@ -46,7 +50,12 @@ func run(settings *plugin.Settings) cli.ActionFunc {
return func(ctx *cli.Context) error { return func(ctx *cli.Context) error {
urfave.LoggingFromContext(ctx) urfave.LoggingFromContext(ctx)
settings.Build.CacheFrom = ctx.Generic("cache-from").(*drone.StringSliceFlag).Get() cacheFrom, ok := ctx.Generic("cache-from").(*drone.StringSliceFlag)
if !ok {
return fmt.Errorf("%w: failed to read cache-from input", ErrTypeAssertionFailed)
}
settings.Build.CacheFrom = cacheFrom.Get()
plugin := plugin.New( plugin := plugin.New(
*settings, *settings,

4
go.mod
View File

@ -1,6 +1,6 @@
module github.com/thegeeklab/drone-docker-buildx module github.com/thegeeklab/drone-docker-buildx
go 1.19 go 1.20
require ( require (
github.com/coreos/go-semver v0.3.1 github.com/coreos/go-semver v0.3.1
@ -8,11 +8,11 @@ require (
github.com/sirupsen/logrus v1.9.0 github.com/sirupsen/logrus v1.9.0
github.com/thegeeklab/drone-plugin-lib/v2 v2.2.1 github.com/thegeeklab/drone-plugin-lib/v2 v2.2.1
github.com/urfave/cli/v2 v2.24.3 github.com/urfave/cli/v2 v2.24.3
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8
) )
require ( require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
) )

View File

@ -6,8 +6,8 @@ import (
) )
const ( const (
dockerExe = "/usr/local/bin/docker" dockerBin = "/usr/local/bin/docker"
dockerdExe = "/usr/local/bin/dockerd" dockerdBin = "/usr/local/bin/dockerd"
dockerHome = "/root/.docker/" dockerHome = "/root/.docker/"
buildkitConfig = "/tmp/buildkit.toml" buildkitConfig = "/tmp/buildkit.toml"
) )
@ -21,6 +21,7 @@ func (p Plugin) startDaemon() {
cmd.Stdout = io.Discard cmd.Stdout = io.Discard
cmd.Stderr = io.Discard cmd.Stderr = io.Discard
} }
go func() { go func() {
trace(cmd) trace(cmd)
_ = cmd.Run() _ = cmd.Run()

View File

@ -3,47 +3,56 @@ package plugin
import ( import (
"fmt" "fmt"
"os" "os"
"os/exec"
"strings" "strings"
"time" "time"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/sys/execabs"
) )
// helper function to create the docker login command. // helper function to create the docker login command.
func commandLogin(login Login) *exec.Cmd { func commandLogin(login Login) *execabs.Cmd {
if login.Email != "" { if login.Email != "" {
return commandLoginEmail(login) return commandLoginEmail(login)
} }
return exec.Command(
dockerExe, "login", args := []string{
"login",
"-u", login.Username, "-u", login.Username,
"-p", login.Password, "-p", login.Password,
login.Registry, login.Registry,
}
return execabs.Command(
dockerBin, args...,
) )
} }
func commandLoginEmail(login Login) *exec.Cmd { func commandLoginEmail(login Login) *execabs.Cmd {
return exec.Command( args := []string{
dockerExe, "login", "login",
"-u", login.Username, "-u", login.Username,
"-p", login.Password, "-p", login.Password,
"-e", login.Email, "-e", login.Email,
login.Registry, login.Registry,
}
return execabs.Command(
dockerBin, args...,
) )
} }
// helper function to create the docker info command. // helper function to create the docker info command.
func commandVersion() *exec.Cmd { func commandVersion() *execabs.Cmd {
return exec.Command(dockerExe, "version") return execabs.Command(dockerBin, "version")
} }
// helper function to create the docker info command. // helper function to create the docker info command.
func commandInfo() *exec.Cmd { func commandInfo() *execabs.Cmd {
return exec.Command(dockerExe, "info") return execabs.Command(dockerBin, "info")
} }
func commandBuilder(daemon Daemon) *exec.Cmd { func commandBuilder(daemon Daemon) *execabs.Cmd {
args := []string{ args := []string{
"buildx", "buildx",
"create", "create",
@ -54,15 +63,15 @@ func commandBuilder(daemon Daemon) *exec.Cmd {
args = append(args, "--config", buildkitConfig) args = append(args, "--config", buildkitConfig)
} }
return exec.Command(dockerExe, args...) return execabs.Command(dockerBin, args...)
} }
func commandBuildx() *exec.Cmd { func commandBuildx() *execabs.Cmd {
return exec.Command(dockerExe, "buildx", "ls") return execabs.Command(dockerBin, "buildx", "ls")
} }
// helper function to create the docker build command. // helper function to create the docker build command.
func commandBuild(build Build, dryrun bool) *exec.Cmd { func commandBuild(build Build, dryrun bool) *execabs.Cmd {
args := []string{ args := []string{
"buildx", "buildx",
"build", "build",
@ -78,39 +87,51 @@ func commandBuild(build Build, dryrun bool) *exec.Cmd {
if !dryrun && build.Output == "" && len(build.Tags.Value()) > 0 { if !dryrun && build.Output == "" && len(build.Tags.Value()) > 0 {
args = append(args, "--push") args = append(args, "--push")
} }
if build.Compress { if build.Compress {
args = append(args, "--compress") args = append(args, "--compress")
} }
if build.Pull { if build.Pull {
args = append(args, "--pull=true") args = append(args, "--pull=true")
} }
if build.NoCache { if build.NoCache {
args = append(args, "--no-cache") args = append(args, "--no-cache")
} }
for _, arg := range build.CacheFrom { for _, arg := range build.CacheFrom {
args = append(args, "--cache-from", arg) args = append(args, "--cache-from", arg)
} }
if build.CacheTo != "" { if build.CacheTo != "" {
args = append(args, "--cache-to", build.CacheTo) args = append(args, "--cache-to", build.CacheTo)
} }
for _, arg := range build.ArgsEnv.Value() { for _, arg := range build.ArgsEnv.Value() {
addProxyValue(&build, arg) addProxyValue(&build, arg)
} }
for _, arg := range append(defaultBuildArgs, build.Args.Value()...) { for _, arg := range append(defaultBuildArgs, build.Args.Value()...) {
args = append(args, "--build-arg", arg) args = append(args, "--build-arg", arg)
} }
for _, host := range build.AddHost.Value() { for _, host := range build.AddHost.Value() {
args = append(args, "--add-host", host) args = append(args, "--add-host", host)
} }
if build.Target != "" { if build.Target != "" {
args = append(args, "--target", build.Target) args = append(args, "--target", build.Target)
} }
if build.Quiet { if build.Quiet {
args = append(args, "--quiet") args = append(args, "--quiet")
} }
if build.Output != "" { if build.Output != "" {
args = append(args, "--output", build.Output) args = append(args, "--output", build.Output)
} }
for _, arg := range build.NamedContext.Value() { for _, arg := range build.NamedContext.Value() {
args = append(args, "--build-context", arg) args = append(args, "--build-context", arg)
} }
@ -135,10 +156,10 @@ func commandBuild(build Build, dryrun bool) *exec.Cmd {
args = append(args, "--provenance", build.Provenance) args = append(args, "--provenance", build.Provenance)
} }
return exec.Command(dockerExe, args...) return execabs.Command(dockerBin, args...)
} }
// helper function to add proxy values from the environment // helper function to add proxy values from the environment.
func addProxyBuildArgs(build *Build) { func addProxyBuildArgs(build *Build) {
addProxyValue(build, "http_proxy") addProxyValue(build, "http_proxy")
addProxyValue(build, "https_proxy") addProxyValue(build, "https_proxy")
@ -182,7 +203,7 @@ func hasProxyBuildArg(build *Build, key string) bool {
} }
// helper function to create the docker daemon command. // helper function to create the docker daemon command.
func commandDaemon(daemon Daemon) *exec.Cmd { func commandDaemon(daemon Daemon) *execabs.Cmd {
args := []string{ args := []string{
"--data-root", daemon.StoragePath, "--data-root", daemon.StoragePath,
"--host=unix:///var/run/docker.sock", "--host=unix:///var/run/docker.sock",
@ -191,35 +212,44 @@ func commandDaemon(daemon Daemon) *exec.Cmd {
if daemon.StorageDriver != "" { if daemon.StorageDriver != "" {
args = append(args, "-s", daemon.StorageDriver) args = append(args, "-s", daemon.StorageDriver)
} }
if daemon.Insecure && daemon.Registry != "" { if daemon.Insecure && daemon.Registry != "" {
args = append(args, "--insecure-registry", daemon.Registry) args = append(args, "--insecure-registry", daemon.Registry)
} }
if daemon.IPv6 { if daemon.IPv6 {
args = append(args, "--ipv6") args = append(args, "--ipv6")
} }
if len(daemon.Mirror) != 0 { if len(daemon.Mirror) != 0 {
args = append(args, "--registry-mirror", daemon.Mirror) args = append(args, "--registry-mirror", daemon.Mirror)
} }
if len(daemon.Bip) != 0 { if len(daemon.Bip) != 0 {
args = append(args, "--bip", daemon.Bip) args = append(args, "--bip", daemon.Bip)
} }
for _, dns := range daemon.DNS.Value() { for _, dns := range daemon.DNS.Value() {
args = append(args, "--dns", dns) args = append(args, "--dns", dns)
} }
for _, dnsSearch := range daemon.DNSSearch.Value() { for _, dnsSearch := range daemon.DNSSearch.Value() {
args = append(args, "--dns-search", dnsSearch) args = append(args, "--dns-search", dnsSearch)
} }
if len(daemon.MTU) != 0 { if len(daemon.MTU) != 0 {
args = append(args, "--mtu", daemon.MTU) args = append(args, "--mtu", daemon.MTU)
} }
if daemon.Experimental { if daemon.Experimental {
args = append(args, "--experimental") args = append(args, "--experimental")
} }
return exec.Command(dockerdExe, args...)
return execabs.Command(dockerdBin, args...)
} }
// trace writes each command to stdout with the command wrapped in an xml // trace writes each command to stdout with the command wrapped in an xml
// tag so that it can be extracted and displayed in the logs. // tag so that it can be extracted and displayed in the logs.
func trace(cmd *exec.Cmd) { func trace(cmd *execabs.Cmd) {
fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " ")) fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " "))
} }

View File

@ -1 +0,0 @@
package plugin

View File

@ -3,12 +3,12 @@ package plugin
import ( import (
"fmt" "fmt"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"time" "time"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/sys/execabs"
) )
// Daemon defines Docker daemon parameters. // Daemon defines Docker daemon parameters.
@ -74,6 +74,8 @@ type Settings struct {
Dryrun bool Dryrun bool
} }
const strictFilePerm = 0o600
// Validate handles the settings validation of the plugin. // Validate handles the settings validation of the plugin.
func (p *Plugin) Validate() error { func (p *Plugin) Validate() error {
p.settings.Build.Branch = p.pipeline.Repo.Branch p.settings.Build.Branch = p.pipeline.Repo.Branch
@ -92,11 +94,14 @@ func (p *Plugin) Validate() error {
) )
if err != nil { if err != nil {
logrus.Infof("cannot generate tags from %s, invalid semantic version", p.settings.Build.Ref) logrus.Infof("cannot generate tags from %s, invalid semantic version", p.settings.Build.Ref)
return err return err
} }
p.settings.Build.Tags = *cli.NewStringSlice(tag...) p.settings.Build.Tags = *cli.NewStringSlice(tag...)
} else { } else {
logrus.Infof("skip auto-tagging for %s, not on default branch or tag", p.settings.Build.Ref) logrus.Infof("skip auto-tagging for %s, not on default branch or tag", p.settings.Build.Ref)
return nil return nil
} }
} }
@ -115,55 +120,59 @@ func (p *Plugin) Execute() error {
// ready to accept connections before we proceed. // ready to accept connections before we proceed.
for i := 0; i < 15; i++ { for i := 0; i < 15; i++ {
cmd := commandInfo() cmd := commandInfo()
err := cmd.Run() err := cmd.Run()
if err == nil { if err == nil {
break break
} }
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
} }
// Create Auth Config File // Create Auth Config File
if p.settings.Login.Config != "" { if p.settings.Login.Config != "" {
if err := os.MkdirAll(dockerHome, 0o600); err != nil { if err := os.MkdirAll(dockerHome, strictFilePerm); err != nil {
return fmt.Errorf("failed to create docker home: %s", err) return fmt.Errorf("failed to create docker home: %w", err)
} }
path := filepath.Join(dockerHome, "config.json") path := filepath.Join(dockerHome, "config.json")
err := os.WriteFile(path, []byte(p.settings.Login.Config), 0o600)
err := os.WriteFile(path, []byte(p.settings.Login.Config), strictFilePerm)
if err != nil { if err != nil {
return fmt.Errorf("error writing config.json: %s", err) return fmt.Errorf("error writing config.json: %w", err)
} }
} }
// login to the Docker registry // login to the Docker registry
if p.settings.Login.Password != "" { if p.settings.Login.Password != "" {
cmd := commandLogin(p.settings.Login) cmd := commandLogin(p.settings.Login)
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
return fmt.Errorf("error authenticating: %s", err) return fmt.Errorf("error authenticating: %w", err)
} }
} }
if p.settings.Daemon.BuildkitConfig != "" { if p.settings.Daemon.BuildkitConfig != "" {
err := os.WriteFile(buildkitConfig, []byte(p.settings.Daemon.BuildkitConfig), 0o600) err := os.WriteFile(buildkitConfig, []byte(p.settings.Daemon.BuildkitConfig), strictFilePerm)
if err != nil { if err != nil {
return fmt.Errorf("error writing buildkit.toml: %s", err) return fmt.Errorf("error writing buildkit.toml: %w", err)
} }
} }
switch { switch {
case p.settings.Login.Password != "": case p.settings.Login.Password != "":
fmt.Println("Detected registry credentials") logrus.Info("Detected registry credentials")
case p.settings.Login.Config != "": case p.settings.Login.Config != "":
fmt.Println("Detected registry credentials file") logrus.Info("Detected registry credentials file")
default: default:
fmt.Println("Registry credentials or Docker config not provided. Guest mode enabled.") logrus.Info("Registry credentials or Docker config not provided. Guest mode enabled.")
} }
// add proxy build args // add proxy build args
addProxyBuildArgs(&p.settings.Build) addProxyBuildArgs(&p.settings.Build)
var cmds []*exec.Cmd var cmds []*execabs.Cmd
cmds = append(cmds, commandVersion()) // docker version cmds = append(cmds, commandVersion()) // docker version
cmds = append(cmds, commandInfo()) // docker info cmds = append(cmds, commandInfo()) // docker info
cmds = append(cmds, commandBuilder(p.settings.Daemon)) cmds = append(cmds, commandBuilder(p.settings.Daemon))

View File

@ -12,7 +12,7 @@ type Plugin struct {
} }
// New initializes a plugin from the given Settings, Pipeline, and Network. // New initializes a plugin from the given Settings, Pipeline, and Network.
func New(settings Settings, pipeline drone.Pipeline, network drone.Network) drone.Plugin { func New(settings Settings, pipeline drone.Pipeline, network drone.Network) *Plugin {
return &Plugin{ return &Plugin{
settings: settings, settings: settings,
pipeline: pipeline, pipeline: pipeline,

View File

@ -14,9 +14,11 @@ func DefaultTagSuffix(ref, suffix string) ([]string, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(suffix) == 0 { if len(suffix) == 0 {
return tags, nil return tags, nil
} }
for i, tag := range tags { for i, tag := range tags {
if tag == "latest" { if tag == "latest" {
tags[i] = suffix tags[i] = suffix
@ -24,13 +26,15 @@ func DefaultTagSuffix(ref, suffix string) ([]string, error) {
tags[i] = fmt.Sprintf("%s-%s", tag, suffix) tags[i] = fmt.Sprintf("%s-%s", tag, suffix)
} }
} }
return tags, nil return tags, nil
} }
func splitOff(input, delim string) string { func splitOff(input, delim string) string {
parts := strings.SplitN(input, delim, 2) const splits = 2
parts := strings.SplitN(input, delim, splits)
if len(parts) == 2 { if len(parts) == splits {
return parts[0] return parts[0]
} }
@ -43,42 +47,65 @@ func DefaultTags(ref string) ([]string, error) {
if !strings.HasPrefix(ref, "refs/tags/") { if !strings.HasPrefix(ref, "refs/tags/") {
return []string{"latest"}, nil return []string{"latest"}, nil
} }
v := stripTagPrefix(ref)
version, err := semver.NewVersion(v) rawVersion := stripTagPrefix(ref)
version, err := semver.NewVersion(rawVersion)
if err != nil { if err != nil {
return []string{"latest"}, err return []string{"latest"}, err
} }
if version.PreRelease != "" || version.Metadata != "" { if version.PreRelease != "" || version.Metadata != "" {
return []string{ return []string{
version.String(), version.String(),
}, nil }, nil
} }
v = stripTagPrefix(ref) rawVersion = stripTagPrefix(ref)
v = splitOff(splitOff(v, "+"), "-") rawVersion = splitOff(splitOff(rawVersion, "+"), "-")
dotParts := strings.SplitN(v, ".", 3) //nolint:gomnd
dotParts := strings.SplitN(rawVersion, ".", 3)
if version.Major == 0 { if version.Major == 0 {
return []string{ return []string{
fmt.Sprintf("%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor), 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), fmt.Sprintf(
}, nil "%0*d.%0*d.%0*d",
} len(dotParts[0]),
return []string{ version.Major,
fmt.Sprintf("%0*d", len(dotParts[0]), version.Major), len(dotParts[1]),
fmt.Sprintf("%0*d.%0*d", len(dotParts[0]), version.Major, len(dotParts[1]), version.Minor), 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), len(dotParts[2]),
version.Patch,
),
}, nil }, nil
} }
// UseDefaultTag for keep only default branch for latest tag 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
}
// UseDefaultTag to keep only default branch for latest tag.
func UseDefaultTag(ref, defaultBranch string) bool { func UseDefaultTag(ref, defaultBranch string) bool {
if strings.HasPrefix(ref, "refs/tags/") { if strings.HasPrefix(ref, "refs/tags/") {
return true return true
} }
if stripHeadPrefix(ref) == defaultBranch { if stripHeadPrefix(ref) == defaultBranch {
return true return true
} }
return false return false
} }
@ -89,5 +116,6 @@ func stripHeadPrefix(ref string) string {
func stripTagPrefix(ref string) string { func stripTagPrefix(ref string) string {
ref = strings.TrimPrefix(ref, "refs/tags/") ref = strings.TrimPrefix(ref, "refs/tags/")
ref = strings.TrimPrefix(ref, "v") ref = strings.TrimPrefix(ref, "v")
return ref return ref
} }

View File

@ -40,8 +40,10 @@ func TestDefaultTags(t *testing.T) {
tags, err := DefaultTags(test.Before) tags, err := DefaultTags(test.Before)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
continue continue
} }
got, want := tags, test.After got, want := tags, test.After
if !reflect.DeepEqual(got, want) { if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want) t.Errorf("Got tag %v, want %v", got, want)
@ -123,8 +125,10 @@ func TestDefaultTagSuffix(t *testing.T) {
tag, err := DefaultTagSuffix(test.Before, test.Suffix) tag, err := DefaultTagSuffix(test.Before, test.Suffix)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
continue continue
} }
got, want := tag, test.After got, want := tag, test.After
if !reflect.DeepEqual(got, want) { if !reflect.DeepEqual(got, want) {
t.Errorf("Got tag %v, want %v", got, want) t.Errorf("Got tag %v, want %v", got, want)
@ -136,6 +140,7 @@ func Test_stripHeadPrefix(t *testing.T) {
type args struct { type args struct {
ref string ref string
} }
tests := []struct { tests := []struct {
args args args args
want string want string
@ -147,6 +152,7 @@ func Test_stripHeadPrefix(t *testing.T) {
want: "main", want: "main",
}, },
} }
for _, tt := range tests { for _, tt := range tests {
if got := stripHeadPrefix(tt.args.ref); got != tt.want { if got := stripHeadPrefix(tt.args.ref); got != tt.want {
t.Errorf("stripHeadPrefix() = %v, want %v", got, tt.want) t.Errorf("stripHeadPrefix() = %v, want %v", got, tt.want)
@ -159,6 +165,7 @@ func TestUseDefaultTag(t *testing.T) {
ref string ref string
defaultBranch string defaultBranch string
} }
tests := []struct { tests := []struct {
name string name string
args args args args
@ -189,6 +196,7 @@ func TestUseDefaultTag(t *testing.T) {
want: false, want: false,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
if got := UseDefaultTag(tt.args.ref, tt.args.defaultBranch); got != tt.want { if got := UseDefaultTag(tt.args.ref, tt.args.defaultBranch); got != tt.want {
t.Errorf("%q. UseDefaultTag() = %v, want %v", tt.name, got, tt.want) t.Errorf("%q. UseDefaultTag() = %v, want %v", tt.name, got, tt.want)