1
0
mirror of https://github.com/ko-build/ko.git synced 2025-02-07 19:30:23 +02:00

Add a tag-only flag to publisher. (#332)

Co-authored-by: chhsia0 <chhsiao@mesosphere.io>
This commit is contained in:
Chun-Hung Hsiao 2021-05-17 08:26:15 -07:00 committed by GitHub
parent a68d0ab75f
commit bc92184f85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 0 deletions

View File

@ -36,6 +36,8 @@ type PublishOptions struct {
LocalDomain string
Tags []string
// TagOnly resolves images into tag-only references.
TagOnly bool
// Push publishes images to a registry.
Push bool
@ -65,6 +67,8 @@ func AddPublishArg(cmd *cobra.Command, po *PublishOptions) {
cmd.Flags().StringSliceVarP(&po.Tags, "tags", "t", []string{"latest"},
"Which tags to use for the produced image instead of the default 'latest' tag "+
"(may not work properly with --base-import-paths or --bare).")
cmd.Flags().BoolVar(&po.TagOnly, "tag-only", false,
"Include tags but not digests in resolved image references. Useful when digests are not preserved when images are repopulated.")
cmd.Flags().BoolVar(&po.Push, "push", true, "Push images to KO_DOCKER_REPO")

View File

@ -173,6 +173,7 @@ func makePublisher(po *options.PublishOptions) (publish.Interface, error) {
publish.WithAuthFromKeychain(authn.DefaultKeychain),
publish.WithNamer(namer),
publish.WithTags(po.Tags),
publish.WithTagOnly(po.TagOnly),
publish.Insecure(po.InsecureRegistry))
if err != nil {
return nil, err

View File

@ -16,6 +16,7 @@ package publish
import (
"context"
"errors"
"fmt"
"log"
"net/http"
@ -38,6 +39,7 @@ type defalt struct {
auth authn.Authenticator
namer Namer
tags []string
tagOnly bool
insecure bool
}
@ -51,6 +53,7 @@ type defaultOpener struct {
auth authn.Authenticator
namer Namer
tags []string
tagOnly bool
insecure bool
}
@ -69,6 +72,15 @@ func identity(base, in string) string { return path.Join(base, in) }
var defaultTags = []string{"latest"}
func (do *defaultOpener) Open() (Interface, error) {
if do.tagOnly {
if len(do.tags) != 1 {
return nil, errors.New("must specify exactly one tag to resolve images into tag-only references")
}
if do.tags[0] == defaultTags[0] {
return nil, errors.New("latest tag cannot be used in tag-only references")
}
}
return &defalt{
base: do.base,
t: do.t,
@ -76,6 +88,7 @@ func (do *defaultOpener) Open() (Interface, error) {
auth: do.auth,
namer: do.namer,
tags: do.tags,
tagOnly: do.tagOnly,
insecure: do.insecure,
}, nil
}
@ -156,6 +169,15 @@ func (d *defalt) Publish(ctx context.Context, br build.Result, s string) (name.R
}
}
if d.tagOnly {
// We have already validated that there is a single tag (not latest).
tag, err := name.NewTag(fmt.Sprintf("%s:%s", d.namer(d.base, s), d.tags[0]))
if err != nil {
return nil, err
}
return &tag, nil
}
h, err := br.Digest()
if err != nil {
return nil, err

View File

@ -224,4 +224,21 @@ func TestDefaultWithReleaseTag(t *testing.T) {
if _, ok := createdTags["v1.2.3"]; !ok {
t.Errorf("Tag v1.2.3 was not created.")
}
def, err = NewDefault(repoName, WithTags([]string{releaseTag}), WithTagOnly(true))
if err != nil {
t.Errorf("NewDefault() = %v", err)
}
if d, err := def.Publish(context.Background(), img, build.StrictScheme+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)
} else if strings.Contains(d.String(), "@sha256:") {
t.Errorf("Publish() = %v, wanted no digest", d.String())
}
}

View File

@ -94,6 +94,14 @@ func WithTags(tags []string) Option {
}
}
// WithTagOnly is a functional option for resolving images into tag-only references
func WithTagOnly(tagOnly bool) Option {
return func(i *defaultOpener) error {
i.tagOnly = tagOnly
return nil
}
}
func Insecure(b bool) Option {
return func(i *defaultOpener) error {
i.insecure = b