1
0
mirror of https://github.com/ko-build/ko.git synced 2025-01-20 18:28:32 +02:00

Include tag in resolved references

If a single tag is explicitly set (i.e. it's not "latest"), include that
in the reference that gets rendered in the yaml.

This is really useful for tracking releases.
This commit is contained in:
Jon Johnson 2019-11-07 13:40:11 -08:00
parent 4833bb4a3e
commit e9800719c2
2 changed files with 95 additions and 12 deletions

View File

@ -97,22 +97,28 @@ func (d *defalt) Publish(img v1.Image, s string) (name.Reference, error) {
// https://github.com/google/go-containerregistry/issues/212
s = strings.ToLower(s)
for _, tagName := range d.tags {
ro := []remote.Option{remote.WithAuth(d.auth), remote.WithTransport(d.t)}
no := []name.Option{}
if d.insecure {
no = append(no, name.Insecure)
}
var os []name.Option
if d.insecure {
os = []name.Option{name.Insecure}
}
tag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", d.base, d.namer(s), tagName), os...)
for i, tagName := range d.tags {
tag, err := name.NewTag(fmt.Sprintf("%s/%s:%s", d.base, d.namer(s), tagName), no...)
if err != nil {
return nil, err
}
log.Printf("Publishing %v", tag)
// TODO: This is slow because we have to load the image multiple times.
// Figure out some way to publish the manifest with another tag.
if err := remote.Write(tag, img, remote.WithAuth(d.auth), remote.WithTransport(d.t)); err != nil {
return nil, err
if i == 0 {
log.Printf("Publishing %v", tag)
if err := remote.Write(tag, img, ro...); err != nil {
return nil, err
}
} else {
log.Printf("Tagging %v", tag)
if err := remote.Tag(tag, img, ro...); err != nil {
return nil, err
}
}
}
@ -120,7 +126,13 @@ func (d *defalt) Publish(img v1.Image, s string) (name.Reference, error) {
if err != nil {
return nil, err
}
dig, err := name.NewDigest(fmt.Sprintf("%s/%s@%s", d.base, d.namer(s), h))
ref := fmt.Sprintf("%s/%s@%s", d.base, d.namer(s), h)
if len(d.tags) == 1 && d.tags[0] != defaultTags[0] {
// If a single tag is explicitly set (not latest), then this
// is probably a release, so include the tag in the reference.
ref = fmt.Sprintf("%s/%s:%s@%s", d.base, d.namer(s), d.tags[0], h)
}
dig, err := name.NewDigest(ref)
if err != nil {
return nil, err
}

View File

@ -221,3 +221,74 @@ func TestDefaultWithTags(t *testing.T) {
t.Errorf("Tag v1.2.3 was not created.")
}
}
func TestDefaultWithReleaseTag(t *testing.T) {
img, err := random.Image(1024, 1)
if err != nil {
t.Fatalf("random.Image() = %v", err)
}
base := "blah"
releaseTag := "v1.2.3"
importpath := "github.com/Google/go-containerregistry/cmd/crane"
expectedRepo := fmt.Sprintf("%s/%s", base, strings.ToLower(importpath))
headPathPrefix := fmt.Sprintf("/v2/%s/blobs/", expectedRepo)
initiatePath := fmt.Sprintf("/v2/%s/blobs/uploads/", expectedRepo)
manifestPath := fmt.Sprintf("/v2/%s/manifests/", expectedRepo)
createdTags := make(map[string]struct{})
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodHead && strings.HasPrefix(r.URL.Path, headPathPrefix) && r.URL.Path != initiatePath {
http.Error(w, "NotFound", http.StatusNotFound)
return
}
switch {
case r.URL.Path == "/v2/":
w.WriteHeader(http.StatusOK)
case r.URL.Path == initiatePath:
if r.Method != http.MethodPost {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPost)
}
http.Error(w, "Mounted", http.StatusCreated)
case strings.HasPrefix(r.URL.Path, manifestPath):
if r.Method != http.MethodPut {
t.Errorf("Method; got %v, want %v", r.Method, http.MethodPut)
}
createdTags[strings.TrimPrefix(r.URL.Path, manifestPath)] = struct{}{}
http.Error(w, "Created", http.StatusCreated)
default:
t.Fatalf("Unexpected path: %v", r.URL.Path)
}
}))
defer server.Close()
u, err := url.Parse(server.URL)
if err != nil {
t.Fatalf("url.Parse(%v) = %v", server.URL, err)
}
tag, err := name.NewTag(fmt.Sprintf("%s/%s:notLatest", u.Host, expectedRepo))
if err != nil {
t.Fatalf("NewTag() = %v", err)
}
repoName := fmt.Sprintf("%s/%s", u.Host, base)
def, err := NewDefault(repoName, WithTags([]string{releaseTag}))
if err != nil {
t.Errorf("NewDefault() = %v", err)
}
if d, err := def.Publish(img, importpath); err != nil {
t.Errorf("Publish() = %v", err)
} else if !strings.HasPrefix(d.String(), repoName) {
t.Errorf("Publish() = %v, wanted prefix %v", d, tag.Repository)
} else if !strings.HasSuffix(d.Context().String(), strings.ToLower(importpath)) {
t.Errorf("Publish() = %v, wanted suffix %v", d.Context(), md5Hash(importpath))
} else if !strings.Contains(d.String(), releaseTag) {
t.Errorf("Publish() = %v, wanted tag included: %v", d.String(), releaseTag)
}
if _, ok := createdTags["v1.2.3"]; !ok {
t.Errorf("Tag v1.2.3 was not created.")
}
}