Skip to content

Commit 7f7170e

Browse files
committed
Fix #3344
Signed-off-by: David Gageot <[email protected]>
1 parent 7115035 commit 7f7170e

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

pkg/skaffold/build/tag/git_commit.go

+24-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"os/exec"
2323
"path/filepath"
24+
"regexp"
2425
"strings"
2526

2627
"github.com/pkg/errors"
@@ -89,7 +90,29 @@ func (c *GitCommit) GenerateFullyQualifiedImageName(workingDir string, imageName
8990
return fmt.Sprintf("%s:%s-dirty", imageName, ref), nil
9091
}
9192

92-
return fmt.Sprintf("%s:%s", imageName, ref), nil
93+
return fmt.Sprintf("%s:%s", imageName, sanitizeTag(ref)), nil
94+
}
95+
96+
// sanitizeTag takes a git tag and converts it to a docker tag by removing
97+
// all the characters that are not allowed by docker.
98+
func sanitizeTag(tag string) string {
99+
// Replace unsupported characters with `_`
100+
sanitized := regexp.MustCompile(`[^a-zA-Z0-9-._]`).ReplaceAllString(tag, `_`)
101+
102+
// Remove leading `-`s and `.`s
103+
prefixSuffix := regexp.MustCompile(`([-.]*)(.*)`).FindStringSubmatch(sanitized)
104+
sanitized = strings.Repeat("_", len(prefixSuffix[1])) + prefixSuffix[2]
105+
106+
// Truncate to 128 characters
107+
if len(sanitized) > 128 {
108+
return sanitized[0:128]
109+
}
110+
111+
if tag != sanitized {
112+
logrus.Warnf("Using %q instead of %q as an image tag", sanitized, tag)
113+
}
114+
115+
return sanitized
93116
}
94117

95118
func (c *GitCommit) makeGitTag(workingDir string) (string, error) {

pkg/skaffold/build/tag/git_commit_test.go

+37
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"io/ioutil"
2323
"os"
2424
"path/filepath"
25+
"strings"
2526
"testing"
2627
"time"
2728

@@ -59,6 +60,25 @@ func TestGitCommit_GenerateFullyQualifiedImageName(t *testing.T) {
5960
commit("initial")
6061
},
6162
},
63+
{
64+
description: "clean worktree with tag containing a slash",
65+
variantTags: "test:v_2",
66+
variantCommitSha: "test:aea33bcc86b5af8c8570ff45d8a643202d63c808",
67+
variantAbbrevCommitSha: "test:aea33bc",
68+
variantTreeSha: "test:bc69d50cda6897a6f2054e64b9059f038dc6fb0e",
69+
variantAbbrevTreeSha: "test:bc69d50",
70+
createGitRepo: func(dir string) {
71+
gitInit(t, dir).
72+
write("source.go", "code").
73+
add("source.go").
74+
commit("initial").
75+
tag("v/1").
76+
write("other.go", "other").
77+
add("other.go").
78+
commit("second commit").
79+
tag("v/2")
80+
},
81+
},
6282
{
6383
description: "clean worktree with tags",
6484
variantTags: "test:v2",
@@ -341,6 +361,23 @@ func TestGitCommit_GenerateFullyQualifiedImageName(t *testing.T) {
341361
}
342362
}
343363

364+
func TestSanitizeTag(t *testing.T) {
365+
testutil.Run(t, "valid tags", func(t *testutil.T) {
366+
t.CheckDeepEqual("abcdefghijklmnopqrstuvwxyz", sanitizeTag("abcdefghijklmnopqrstuvwxyz"))
367+
t.CheckDeepEqual("ABCDEFGHIJKLMNOPQRSTUVWXYZ", sanitizeTag("ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
368+
t.CheckDeepEqual("0123456789-_.", sanitizeTag("0123456789-_."))
369+
t.CheckDeepEqual("_v1", sanitizeTag("_v1"))
370+
})
371+
372+
testutil.Run(t, "sanitized tags", func(t *testutil.T) {
373+
t.CheckDeepEqual("v_1", sanitizeTag("v/1"))
374+
t.CheckDeepEqual("v____1", sanitizeTag("v%$@!1"))
375+
t.CheckDeepEqual("__v1", sanitizeTag("--v1"))
376+
t.CheckDeepEqual("__v1", sanitizeTag("..v1"))
377+
t.CheckDeepEqual(128, len(sanitizeTag(strings.Repeat("0123456789", 20))))
378+
})
379+
}
380+
344381
// gitRepo deals with test git repositories
345382
type gitRepo struct {
346383
dir string

0 commit comments

Comments
 (0)