Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add semver tagging semantics #214

Merged
merged 36 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
360c428
woops, remove 'break' which made setup-images noop
vito Jun 21, 2020
3375643
check: introduce semver based version scheme
vito Jun 21, 2020
85dd02c
check: split table tests out, move types from main
vito Jul 9, 2020
1f7abb0
check: initial support for checking 'variants'
vito Jul 9, 2020
d46257f
check: make pre-releases opt-in
vito Jul 9, 2020
0787d06
check: respect 'from' version
vito Jul 9, 2020
8475516
check: slight refactor - dedupe registry mirror
vito Jul 9, 2020
47481a3
check: backfill tests for mirror + semver tags
vito Jul 9, 2020
5246138
check: refactor: branch in checkWithRetry
vito Jul 9, 2020
ea197da
refactor: move request/response types to top pkg
vito Jul 9, 2020
fa606e9
out: pushing version tags (optionally w/ variant)
vito Jul 9, 2020
6902917
out: add helpful error if no tag specified
vito Jul 10, 2020
b9e2f44
out: validate version value, sanitize away 'v'
vito Jul 10, 2020
a2e71e7
update README with new semver behavior
vito Jul 14, 2020
6651dd3
check: don't fetch digests for old versions
vito Jul 16, 2020
611afb7
check: re-use transport to prevent repeated auth
vito Jul 17, 2020
c63d1f0
out: fix failing 429 tests
vito Jul 17, 2020
c00b7af
check: only auth once for tag flow, too
vito Jul 22, 2020
5857d92
check: remove unused 'versions' var
vito Jul 24, 2020
f84d798
check: pull plumbing out into Source methods
vito Jul 24, 2020
b5d74b2
in tests: ensure each version has a tag field
vito Jul 24, 2020
1564f5c
in: backfill test for image tagging w/ mirror
vito Jul 24, 2020
8d2d59a
in: save tag/digest no matter what, refactor
vito Jul 24, 2020
b4028e1
Merge branch 'master' into semver-tags
vito Jul 31, 2020
77c9dea
structure: tag vs. ref naming consistency
vito Jul 31, 2020
2d4e623
structure: remove redundant WeakValidation args
vito Jul 31, 2020
ed69157
check: use HEAD requests to avoid rate limits
vito Sep 16, 2020
861e70e
Merge branch 'master' into semver-tags
vito Sep 16, 2020
cb25c2c
Merge branch 'master' into semver-tags
vito Nov 2, 2020
ed142fa
Merge branch 'master' into semver-tags
vito Nov 9, 2020
dd0d1a5
allow 1.2.3-rc1 and 1.2.3-rc as prereleases
vito Nov 9, 2020
db34ba0
final version tag takes priority over prereleases
vito Nov 9, 2020
e11ca27
revise README for prerelease prefix change
vito Nov 10, 2020
5071a4e
fix order dependence for final version precedence
vito Nov 10, 2020
2e1827d
include tag in response in tag checking mode
vito Nov 11, 2020
5f9d3a2
attempt to clarify `variant` + `tag` usage
vito Nov 11, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions check_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,66 @@ var _ = DescribeTable("tracking semver tags",
Versions: []string{"1", "2", "3"},
},
),
Entry("variants",
SemverTagExample{
Variant: "foo",

Tags: map[string]string{
"latest": "random-1",
"1.0.0": "random-1",
"0.9.0": "random-2",
"foo": "random-3",
"1.0.0-foo": "random-3",
"0.9.0-foo": "random-4",
"bar": "random-5",
"1.0.0-bar": "random-5",
"0.9.0-bar": "random-6",
},

Versions: []string{"0.9.0-foo", "1.0.0-foo"},
},
),
Entry("distinguishing additional variants from prereleases",
SemverTagExample{
Variant: "foo",

Tags: map[string]string{
"1.0.0-foo": "random-1",
"1.0.0-rc.1-foo": "random-2",
"1.0.0-alpha.1-foo": "random-3",
"1.0.0-beta.1-foo": "random-4",
"1.0.0-bar-foo": "random-5",
"1.0.0-rc.1-bar-foo": "random-6",
"1.0.0-alpha.1-bar-foo": "random-7",
"1.0.0-beta.1-bar-foo": "random-8",
},

Versions: []string{
"1.0.0-alpha.1-foo",
"1.0.0-beta.1-foo",
"1.0.0-rc.1-foo",
"1.0.0-foo",
},
},
),
Entry("variant with bare variant tag pointing to unique digest",
SemverTagExample{
Variant: "foo",

Tags: map[string]string{
"latest": "random-1",
"1.0.0": "random-1",
"0.9.0": "random-2",
"foo": "random-3",
"0.8.0-foo": "random-4",
"bar": "random-5",
"1.0.0-bar": "random-5",
"0.9.0-bar": "random-6",
},

Versions: []string{"0.8.0-foo", "foo"},
},
),
)

type SemverTagExample struct {
Expand Down Expand Up @@ -602,6 +662,7 @@ func (example SemverTagExample) Run() {
req := resource.CheckRequest{
Source: resource.Source{
Repository: repo.Name(),
Variant: example.Variant,
},
}

Expand Down
45 changes: 36 additions & 9 deletions cmd/check/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func main() {

repo.Registry = mirror

response, err = checkRepositoryWithRetry(req.Source.RegistryMirror.BasicCredentials, req.Version, repo)
response, err = checkRepositoryWithRetry(req.Source.RegistryMirror.BasicCredentials, req.Source.Variant, req.Version, repo)
if err != nil {
logrus.Warnf("checking mirror %s failed: %s", mirror.RegistryStr(), err)
} else if len(response) == 0 {
Expand All @@ -109,7 +109,7 @@ func main() {
}

if len(response) == 0 {
response, err = checkRepositoryWithRetry(req.Source.BasicCredentials, req.Version, repo)
response, err = checkRepositoryWithRetry(req.Source.BasicCredentials, req.Source.Variant, req.Version, repo)
if err != nil {
logrus.Errorf("checking origin failed: %s", err)
os.Exit(1)
Expand All @@ -121,11 +121,11 @@ func main() {
json.NewEncoder(os.Stdout).Encode(response)
}

func checkRepositoryWithRetry(principal resource.BasicCredentials, version *resource.Version, ref name.Repository) (resource.CheckResponse, error) {
func checkRepositoryWithRetry(principal resource.BasicCredentials, variant string, version *resource.Version, ref name.Repository) (resource.CheckResponse, error) {
var response resource.CheckResponse
err := resource.RetryOnRateLimit(func() error {
var err error
response, err = checkRepository(principal, version, ref)
response, err = checkRepository(principal, variant, version, ref)
return err
})
return response, err
Expand All @@ -141,7 +141,7 @@ func checkTagWithRetry(principal resource.BasicCredentials, version *resource.Ve
return response, err
}

func checkRepository(principal resource.BasicCredentials, version *resource.Version, ref name.Repository) (resource.CheckResponse, error) {
func checkRepository(principal resource.BasicCredentials, variant string, version *resource.Version, ref name.Repository) (resource.CheckResponse, error) {
auth := &authn.Basic{
Username: principal.Username,
Password: principal.Password,
Expand All @@ -158,6 +158,11 @@ func checkRepository(principal resource.BasicCredentials, version *resource.Vers
return resource.CheckResponse{}, fmt.Errorf("list repository tags: %w", err)
}

bareTag := "latest"
if variant != "" {
bareTag = variant
}

var latestTag string

versions := []*semver.Version{}
Expand All @@ -166,16 +171,38 @@ func checkRepository(principal resource.BasicCredentials, version *resource.Vers
digestVersions := map[string]*semver.Version{}
for _, identifier := range tags {
var ver *semver.Version
if identifier == "latest" {
// TODO: handle variants, e.g. 'alpine' is latest for
// 'x.x.x-alpine'
if identifier == bareTag {
latestTag = identifier
} else {
ver, err = semver.NewVersion(identifier)
verStr := identifier
if variant != "" {
if !strings.HasSuffix(identifier, "-"+variant) {
continue
}

verStr = strings.TrimSuffix(identifier, "-"+variant)
}

ver, err = semver.NewVersion(verStr)
if err != nil {
// not a version
continue
}

pre := ver.Prerelease()
if pre != "" {
// contains additional variant
if strings.Contains(pre, "-") {
continue
}

if !strings.HasPrefix(pre, "alpha.") &&
!strings.HasPrefix(pre, "beta.") &&
!strings.HasPrefix(pre, "rc.") {
aoldershaw marked this conversation as resolved.
Show resolved Hide resolved
// additional variant, not a prerelease segment
continue
}
}
}

tagRef := ref.Tag(identifier)
Expand Down
1 change: 1 addition & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type RegistryMirror struct {

type Source struct {
Repository string `json:"repository"`
Variant string `json:"variant,omitempty"`
Tag Tag `json:"tag,omitempty"`

BasicCredentials
Expand Down