refactor: update dependencies and use plugin boilerplate
This commit is contained in:
25
plugin/daemon.go
Normal file
25
plugin/daemon.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
const dockerExe = "/usr/local/bin/docker"
|
||||
const dockerdExe = "/usr/local/bin/dockerd"
|
||||
const dockerHome = "/root/.docker/"
|
||||
|
||||
func (p Plugin) startDaemon() {
|
||||
cmd := commandDaemon(p.settings.Daemon)
|
||||
if p.settings.Daemon.Debug {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
} else {
|
||||
cmd.Stdout = ioutil.Discard
|
||||
cmd.Stderr = ioutil.Discard
|
||||
}
|
||||
go func() {
|
||||
trace(cmd)
|
||||
cmd.Run()
|
||||
}()
|
||||
}
|
||||
233
plugin/docker.go
Normal file
233
plugin/docker.go
Normal file
@@ -0,0 +1,233 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// helper function to create the docker login command.
|
||||
func commandLogin(login Login) *exec.Cmd {
|
||||
if login.Email != "" {
|
||||
return commandLoginEmail(login)
|
||||
}
|
||||
return exec.Command(
|
||||
dockerExe, "login",
|
||||
"-u", login.Username,
|
||||
"-p", login.Password,
|
||||
login.Registry,
|
||||
)
|
||||
}
|
||||
|
||||
// helper to check if args match "docker pull <image>"
|
||||
func isCommandPull(args []string) bool {
|
||||
return len(args) > 2 && args[1] == "pull"
|
||||
}
|
||||
|
||||
func commandPull(repo string) *exec.Cmd {
|
||||
return exec.Command(dockerExe, "pull", repo)
|
||||
}
|
||||
|
||||
func commandLoginEmail(login Login) *exec.Cmd {
|
||||
return exec.Command(
|
||||
dockerExe, "login",
|
||||
"-u", login.Username,
|
||||
"-p", login.Password,
|
||||
"-e", login.Email,
|
||||
login.Registry,
|
||||
)
|
||||
}
|
||||
|
||||
// helper function to create the docker info command.
|
||||
func commandVersion() *exec.Cmd {
|
||||
return exec.Command(dockerExe, "version")
|
||||
}
|
||||
|
||||
// helper function to create the docker info command.
|
||||
func commandInfo() *exec.Cmd {
|
||||
return exec.Command(dockerExe, "info")
|
||||
}
|
||||
|
||||
func commandBuilder() *exec.Cmd {
|
||||
return exec.Command(dockerExe, "buildx", "create", "--use")
|
||||
}
|
||||
|
||||
func commandBuildx() *exec.Cmd {
|
||||
return exec.Command(dockerExe, "buildx", "ls")
|
||||
}
|
||||
|
||||
// helper function to create the docker build command.
|
||||
func commandBuild(build Build) *exec.Cmd {
|
||||
args := []string{
|
||||
"buildx",
|
||||
"build",
|
||||
"--load",
|
||||
"--rm=true",
|
||||
"-f", build.Dockerfile,
|
||||
"-t", build.Name,
|
||||
}
|
||||
|
||||
args = append(args, build.Context)
|
||||
if build.Squash {
|
||||
args = append(args, "--squash")
|
||||
}
|
||||
if build.Compress {
|
||||
args = append(args, "--compress")
|
||||
}
|
||||
if build.Pull {
|
||||
args = append(args, "--pull=true")
|
||||
}
|
||||
if build.NoCache {
|
||||
args = append(args, "--no-cache")
|
||||
}
|
||||
for _, arg := range build.CacheFrom.Value() {
|
||||
args = append(args, "--cache-from", arg)
|
||||
}
|
||||
for _, arg := range build.ArgsEnv.Value() {
|
||||
addProxyValue(&build, arg)
|
||||
}
|
||||
for _, arg := range build.Args.Value() {
|
||||
args = append(args, "--build-arg", arg)
|
||||
}
|
||||
for _, host := range build.AddHost.Value() {
|
||||
args = append(args, "--add-host", host)
|
||||
}
|
||||
if build.Target != "" {
|
||||
args = append(args, "--target", build.Target)
|
||||
}
|
||||
if build.Quiet {
|
||||
args = append(args, "--quiet")
|
||||
}
|
||||
|
||||
if len(build.Platforms.Value()) > 0 {
|
||||
args = append(args, "--platform", strings.Join(build.Platforms.Value()[:], ","))
|
||||
}
|
||||
|
||||
return exec.Command(dockerExe, args...)
|
||||
}
|
||||
|
||||
// helper function to add proxy values from the environment
|
||||
func addProxyBuildArgs(build *Build) {
|
||||
addProxyValue(build, "http_proxy")
|
||||
addProxyValue(build, "https_proxy")
|
||||
addProxyValue(build, "no_proxy")
|
||||
}
|
||||
|
||||
// helper function to add the upper and lower case version of a proxy value.
|
||||
func addProxyValue(build *Build, key string) {
|
||||
value := getProxyValue(key)
|
||||
|
||||
if len(value) > 0 && !hasProxyBuildArg(build, key) {
|
||||
args := build.Args.Value()
|
||||
args = append(build.Args.Value(), fmt.Sprintf("%s=%s", key, value))
|
||||
args = append(build.Args.Value(), fmt.Sprintf("%s=%s", strings.ToUpper(key), value))
|
||||
build.Args = *cli.NewStringSlice(args...)
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to get a proxy value from the environment.
|
||||
//
|
||||
// assumes that the upper and lower case versions of are the same.
|
||||
func getProxyValue(key string) string {
|
||||
value := os.Getenv(key)
|
||||
|
||||
if len(value) > 0 {
|
||||
return value
|
||||
}
|
||||
|
||||
return os.Getenv(strings.ToUpper(key))
|
||||
}
|
||||
|
||||
// helper function that looks to see if a proxy value was set in the build args.
|
||||
func hasProxyBuildArg(build *Build, key string) bool {
|
||||
keyUpper := strings.ToUpper(key)
|
||||
|
||||
for _, s := range build.Args.Value() {
|
||||
if strings.HasPrefix(s, key) || strings.HasPrefix(s, keyUpper) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// helper function to create the docker tag command.
|
||||
func commandTag(build Build, tag string) *exec.Cmd {
|
||||
var (
|
||||
source = build.Name
|
||||
target = fmt.Sprintf("%s:%s", build.Repo, tag)
|
||||
)
|
||||
return exec.Command(
|
||||
dockerExe, "tag", source, target,
|
||||
)
|
||||
}
|
||||
|
||||
// helper function to create the docker push command.
|
||||
func commandPush(build Build, tag string) *exec.Cmd {
|
||||
target := fmt.Sprintf("%s:%s", build.Repo, tag)
|
||||
return exec.Command(dockerExe, "push", target)
|
||||
}
|
||||
|
||||
// helper function to create the docker daemon command.
|
||||
func commandDaemon(daemon Daemon) *exec.Cmd {
|
||||
args := []string{
|
||||
"--data-root", daemon.StoragePath,
|
||||
"--host=unix:///var/run/docker.sock",
|
||||
}
|
||||
|
||||
if daemon.StorageDriver != "" {
|
||||
args = append(args, "-s", daemon.StorageDriver)
|
||||
}
|
||||
if daemon.Insecure && daemon.Registry != "" {
|
||||
args = append(args, "--insecure-registry", daemon.Registry)
|
||||
}
|
||||
if daemon.IPv6 {
|
||||
args = append(args, "--ipv6")
|
||||
}
|
||||
if len(daemon.Mirror) != 0 {
|
||||
args = append(args, "--registry-mirror", daemon.Mirror)
|
||||
}
|
||||
if len(daemon.Bip) != 0 {
|
||||
args = append(args, "--bip", daemon.Bip)
|
||||
}
|
||||
for _, dns := range daemon.DNS.Value() {
|
||||
args = append(args, "--dns", dns)
|
||||
}
|
||||
for _, dnsSearch := range daemon.DNSSearch.Value() {
|
||||
args = append(args, "--dns-search", dnsSearch)
|
||||
}
|
||||
if len(daemon.MTU) != 0 {
|
||||
args = append(args, "--mtu", daemon.MTU)
|
||||
}
|
||||
if daemon.Experimental {
|
||||
args = append(args, "--experimental")
|
||||
}
|
||||
return exec.Command(dockerdExe, args...)
|
||||
}
|
||||
|
||||
// helper to check if args match "docker prune"
|
||||
func isCommandPrune(args []string) bool {
|
||||
return len(args) > 3 && args[2] == "prune"
|
||||
}
|
||||
|
||||
func commandPrune() *exec.Cmd {
|
||||
return exec.Command(dockerExe, "system", "prune", "-f")
|
||||
}
|
||||
|
||||
// helper to check if args match "docker rmi"
|
||||
func isCommandRmi(args []string) bool {
|
||||
return len(args) > 2 && args[1] == "rmi"
|
||||
}
|
||||
|
||||
func commandRmi(tag string) *exec.Cmd {
|
||||
return exec.Command(dockerExe, "rmi", tag)
|
||||
}
|
||||
|
||||
// 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.
|
||||
func trace(cmd *exec.Cmd) {
|
||||
fmt.Fprintf(os.Stdout, "+ %s\n", strings.Join(cmd.Args, " "))
|
||||
}
|
||||
1
plugin/docker_test.go
Normal file
1
plugin/docker_test.go
Normal file
@@ -0,0 +1 @@
|
||||
package plugin
|
||||
203
plugin/impl.go
Normal file
203
plugin/impl.go
Normal file
@@ -0,0 +1,203 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// Daemon defines Docker daemon parameters.
|
||||
type Daemon struct {
|
||||
Registry string // Docker registry
|
||||
Mirror string // Docker registry mirror
|
||||
Insecure bool // Docker daemon enable insecure registries
|
||||
StorageDriver string // Docker daemon storage driver
|
||||
StoragePath string // Docker daemon storage path
|
||||
Disabled bool // DOcker daemon is disabled (already running)
|
||||
Debug bool // Docker daemon started in debug mode
|
||||
Bip string // Docker daemon network bridge IP address
|
||||
DNS cli.StringSlice // Docker daemon dns server
|
||||
DNSSearch cli.StringSlice // Docker daemon dns search domain
|
||||
MTU string // Docker daemon mtu setting
|
||||
IPv6 bool // Docker daemon IPv6 networking
|
||||
Experimental bool // Docker daemon enable experimental mode
|
||||
}
|
||||
|
||||
// Login defines Docker login parameters.
|
||||
type Login struct {
|
||||
Registry string // Docker registry address
|
||||
Username string // Docker registry username
|
||||
Password string // Docker registry password
|
||||
Email string // Docker registry email
|
||||
Config string // Docker Auth Config
|
||||
}
|
||||
|
||||
// Build defines Docker build parameters.
|
||||
type Build struct {
|
||||
Remote string // Git remote URL
|
||||
Name string // Git commit sha used as docker default named tag
|
||||
Ref string // Git commit ref
|
||||
Branch string // Git repository branch
|
||||
Dockerfile string // Docker build Dockerfile
|
||||
Context string // Docker build context
|
||||
TagsAuto bool // Docker build auto tag
|
||||
TagsSuffix string // Docker build tags with suffix
|
||||
Tags cli.StringSlice // Docker build tags
|
||||
Platforms cli.StringSlice // Docker build target platforms
|
||||
Args cli.StringSlice // Docker build args
|
||||
ArgsEnv cli.StringSlice // Docker build args from env
|
||||
Target string // Docker build target
|
||||
Squash bool // Docker build squash
|
||||
Pull bool // Docker build pull
|
||||
CacheFrom cli.StringSlice // Docker build cache-from
|
||||
Compress bool // Docker build compress
|
||||
Repo string // Docker build repository
|
||||
NoCache bool // Docker build no-cache
|
||||
AddHost cli.StringSlice // Docker build add-host
|
||||
Quiet bool // Docker build quiet
|
||||
}
|
||||
|
||||
// Settings for the Plugin.
|
||||
type Settings struct {
|
||||
Daemon Daemon
|
||||
Login Login
|
||||
Build Build
|
||||
Dryrun bool
|
||||
Cleanup bool
|
||||
}
|
||||
|
||||
// Validate handles the settings validation of the plugin.
|
||||
func (p *Plugin) Validate() error {
|
||||
p.settings.Daemon.Registry = p.settings.Login.Registry
|
||||
|
||||
if p.settings.Build.TagsAuto {
|
||||
// return true if tag event or default branch
|
||||
if UseDefaultTag(
|
||||
p.settings.Build.Ref,
|
||||
p.settings.Build.Branch,
|
||||
) {
|
||||
tag, err := DefaultTagSuffix(
|
||||
p.settings.Build.Ref,
|
||||
p.settings.Build.TagsSuffix,
|
||||
)
|
||||
if err != nil {
|
||||
logrus.Printf("cannot build docker image for %s, invalid semantic version", p.settings.Build.Ref)
|
||||
return err
|
||||
}
|
||||
p.settings.Build.Tags = *cli.NewStringSlice(tag...)
|
||||
} else {
|
||||
logrus.Printf("skipping automated docker build for %s", p.settings.Build.Ref)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Execute provides the implementation of the plugin.
|
||||
func (p *Plugin) Execute() error {
|
||||
// start the Docker daemon server
|
||||
if !p.settings.Daemon.Disabled {
|
||||
p.startDaemon()
|
||||
}
|
||||
|
||||
// poll the docker daemon until it is started. This ensures the daemon is
|
||||
// ready to accept connections before we proceed.
|
||||
for i := 0; i < 15; i++ {
|
||||
cmd := commandInfo()
|
||||
err := cmd.Run()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
||||
|
||||
// Create Auth Config File
|
||||
if p.settings.Login.Config != "" {
|
||||
os.MkdirAll(dockerHome, 0600)
|
||||
|
||||
path := filepath.Join(dockerHome, "config.json")
|
||||
err := ioutil.WriteFile(path, []byte(p.settings.Login.Config), 0600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing config.json: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// login to the Docker registry
|
||||
if p.settings.Login.Password != "" {
|
||||
cmd := commandLogin(p.settings.Login)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error authenticating: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case p.settings.Login.Password != "":
|
||||
fmt.Println("Detected registry credentials")
|
||||
case p.settings.Login.Config != "":
|
||||
fmt.Println("Detected registry credentials file")
|
||||
default:
|
||||
fmt.Println("Registry credentials or Docker config not provided. Guest mode enabled.")
|
||||
}
|
||||
|
||||
if p.settings.Build.Squash && !p.settings.Daemon.Experimental {
|
||||
fmt.Println("Squash build flag is only available when Docker deamon is started with experimental flag. Ignoring...")
|
||||
p.settings.Build.Squash = false
|
||||
}
|
||||
|
||||
// add proxy build args
|
||||
addProxyBuildArgs(&p.settings.Build)
|
||||
|
||||
var cmds []*exec.Cmd
|
||||
cmds = append(cmds, commandVersion()) // docker version
|
||||
cmds = append(cmds, commandInfo()) // docker info
|
||||
cmds = append(cmds, commandBuilder())
|
||||
cmds = append(cmds, commandBuildx())
|
||||
|
||||
// pre-pull cache images
|
||||
for _, img := range p.settings.Build.CacheFrom.Value() {
|
||||
cmds = append(cmds, commandPull(img))
|
||||
}
|
||||
|
||||
cmds = append(cmds, commandBuild(p.settings.Build)) // docker build
|
||||
|
||||
for _, tag := range p.settings.Build.Tags.Value() {
|
||||
cmds = append(cmds, commandTag(p.settings.Build, tag)) // docker tag
|
||||
|
||||
if !p.settings.Dryrun {
|
||||
cmds = append(cmds, commandPush(p.settings.Build, tag)) // docker push
|
||||
}
|
||||
}
|
||||
|
||||
if p.settings.Cleanup {
|
||||
cmds = append(cmds, commandRmi(p.settings.Build.Name)) // docker rmi
|
||||
cmds = append(cmds, commandPrune()) // docker system prune -f
|
||||
}
|
||||
|
||||
// execute all commands in batch mode.
|
||||
for _, cmd := range cmds {
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
trace(cmd)
|
||||
|
||||
err := cmd.Run()
|
||||
if err != nil && isCommandPull(cmd.Args) {
|
||||
fmt.Printf("Could not pull cache-from image %s. Ignoring...\n", cmd.Args[2])
|
||||
} else if err != nil && isCommandPrune(cmd.Args) {
|
||||
fmt.Printf("Could not prune system containers. Ignoring...\n")
|
||||
} else if err != nil && isCommandRmi(cmd.Args) {
|
||||
fmt.Printf("Could not remove image %s. Ignoring...\n", cmd.Args[2])
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
21
plugin/plugin.go
Normal file
21
plugin/plugin.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"github.com/drone-plugins/drone-plugin-lib/drone"
|
||||
)
|
||||
|
||||
// Plugin implements drone.Plugin to provide the plugin implementation.
|
||||
type Plugin struct {
|
||||
settings Settings
|
||||
pipeline drone.Pipeline
|
||||
network drone.Network
|
||||
}
|
||||
|
||||
// New initializes a plugin from the given Settings, Pipeline, and Network.
|
||||
func New(settings Settings, pipeline drone.Pipeline, network drone.Network) drone.Plugin {
|
||||
return &Plugin{
|
||||
settings: settings,
|
||||
pipeline: pipeline,
|
||||
network: network,
|
||||
}
|
||||
}
|
||||
93
plugin/tags.go
Normal file
93
plugin/tags.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/go-semver/semver"
|
||||
)
|
||||
|
||||
// DefaultTagSuffix returns a set of default suggested tags
|
||||
// based on the commit ref with an attached suffix.
|
||||
func DefaultTagSuffix(ref, suffix string) ([]string, error) {
|
||||
tags, err := DefaultTags(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
|
||||
}
|
||||
|
||||
// DefaultTags returns a set of default suggested tags based on
|
||||
// the commit ref.
|
||||
func DefaultTags(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
|
||||
}
|
||||
|
||||
// UseDefaultTag for keep only default branch for latest tag
|
||||
func UseDefaultTag(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
|
||||
}
|
||||
197
plugin/tags_test.go
Normal file
197
plugin/tags_test.go
Normal file
@@ -0,0 +1,197 @@
|
||||
package plugin
|
||||
|
||||
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 TestDefaultTags(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 := DefaultTags(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 TestDefaultTagsError(t *testing.T) {
|
||||
var tests = []string{
|
||||
"refs/tags/x1.0.0",
|
||||
"refs/tags/20190203",
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
_, err := DefaultTags(test)
|
||||
if err == nil {
|
||||
t.Errorf("Expect tag error for %s", test)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultTagSuffix(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 := DefaultTagSuffix(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 TestUseDefaultTag(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 := UseDefaultTag(tt.args.ref, tt.args.defaultBranch); got != tt.want {
|
||||
t.Errorf("%q. UseDefaultTag() = %v, want %v", tt.name, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user