From b42d7a2e97b78469bee037c887813eaa32e1adc8 Mon Sep 17 00:00:00 2001 From: Michael McCallum Date: Mon, 29 Jun 2020 14:17:47 +1200 Subject: [PATCH 1/2] Allow 2 point versions in images: We only use 2 points X.Y always unless there is really a patch which is extremely uncommon. Developers choose the X and tooling chooses the Y. That is the developers only ever have to make a simple decision did I break it or not. * these are still semver but just treat the patch as optional * add tests for various combinations of updates --- internal/policy/semver.go | 2 +- internal/policy/semver_test.go | 50 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/internal/policy/semver.go b/internal/policy/semver.go index 50f65cd5..d7bf2952 100644 --- a/internal/policy/semver.go +++ b/internal/policy/semver.go @@ -69,7 +69,7 @@ func shouldUpdate(spt SemverPolicyType, matchPreRelease bool, current, new strin } parts := strings.SplitN(new, ".", 3) - if len(parts) != 3 { + if len(parts) != 2 && len(parts) != 3 { return false, ErrNoMajorMinorPatchElementsFound } diff --git a/internal/policy/semver_test.go b/internal/policy/semver_test.go index 5222050f..7bfbd8cd 100644 --- a/internal/policy/semver_test.go +++ b/internal/policy/semver_test.go @@ -47,6 +47,16 @@ func Test_shouldUpdate(t *testing.T) { want: false, wantErr: false, }, + { + name: "minor increase - 2 points, policy all", + args: args{ + current: "1.4", + new: "1.5", + spt: SemverPolicyTypeAll, + }, + want: true, + wantErr: false, + }, { name: "minor increase, policy major", args: args{ @@ -77,6 +87,26 @@ func Test_shouldUpdate(t *testing.T) { want: true, wantErr: false, }, + { + name: "patch release, policy patch", + args: args{ + current: "1.4", + new: "1.4.6", + spt: SemverPolicyTypePatch, + }, + want: true, + wantErr: false, + }, + { + name: "minor and patch release, policy patch", + args: args{ + current: "1.4", + new: "1.5.6", + spt: SemverPolicyTypePatch, + }, + want: false, + wantErr: false, + }, { name: "patch decrease, policy patch", args: args{ @@ -87,6 +117,16 @@ func Test_shouldUpdate(t *testing.T) { want: false, wantErr: false, }, + { + name: "2 points minor change, policy patch", + args: args{ + current: "1.4", + new: "1.5", + spt: SemverPolicyTypePatch, + }, + want: false, + wantErr: false, + }, { name: "patch AND major increase, policy patch", args: args{ @@ -117,6 +157,16 @@ func Test_shouldUpdate(t *testing.T) { want: true, wantErr: false, }, + { + name: "minor increase 2 points, policy minor", + args: args{ + current: "1.4", + new: "1.5", + spt: SemverPolicyTypeMinor, + }, + want: true, + wantErr: false, + }, { name: "patch increase, policy minor", args: args{ From 1f90e6cb76d1f5876deaa66ff830d671bc8a271a Mon Sep 17 00:00:00 2001 From: Michael McCallum Date: Mon, 29 Jun 2020 18:10:59 +1200 Subject: [PATCH 2/2] Validate the tag watching respects 2 point versions --- trigger/poll/multi_tags_watcher.go | 2 +- trigger/poll/multi_tags_watcher_test.go | 15 +++++++++++++++ util/version/version.go | 2 +- util/version/version_test.go | 6 ++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/trigger/poll/multi_tags_watcher.go b/trigger/poll/multi_tags_watcher.go index eb5b6344..5471d256 100644 --- a/trigger/poll/multi_tags_watcher.go +++ b/trigger/poll/multi_tags_watcher.go @@ -152,7 +152,7 @@ func exists(tag string, events []types.Event) bool { func semverSort(tags []string) []*semver.Version { var versions []*semver.Version for _, t := range tags { - if len(strings.SplitN(t, ".", 3)) < 3 { + if len(strings.SplitN(t, ".", 3)) < 2 { // Keep only X.Y.Z+ semver continue } diff --git a/trigger/poll/multi_tags_watcher_test.go b/trigger/poll/multi_tags_watcher_test.go index 7daa40eb..300aaee3 100644 --- a/trigger/poll/multi_tags_watcher_test.go +++ b/trigger/poll/multi_tags_watcher_test.go @@ -130,6 +130,14 @@ func testRunHelper(testCases []runTestCase, availableTags []string, t *testing.T } } + +func TestWatchAllTagsJobWith2pointSemver(t *testing.T) { + availableTags := []string{"1.3", "2.5", "2.7", "3.8"} + testRunHelper([]runTestCase{{"1.3", "3.8", policy.NewSemverPolicy(policy.SemverPolicyTypeMajor, false)}}, availableTags, t) + testRunHelper([]runTestCase{{"2.5", "3.8", policy.NewSemverPolicy(policy.SemverPolicyTypeMajor, false)}}, availableTags, t) + testRunHelper([]runTestCase{{"2.5", "2.7", policy.NewSemverPolicy(policy.SemverPolicyTypeMinor, false)}}, availableTags, t) +} + func TestWatchAllTagsJobWithSemver(t *testing.T) { availableTags := []string{"1.3.0-dev", "1.5.0", "1.8.0-alpha"} testCases := []runTestCase{{"1.1.0", "1.5.0", policy.NewSemverPolicy(policy.SemverPolicyTypeMajor, true)}} @@ -155,6 +163,13 @@ func TestWatchAllTagsFullSemver(t *testing.T) { } +func TestWatchAllTagsHiddenMinorWith2PointVersions(t *testing.T) { + availableTags := []string{"1.3", "1.5", "2.0", "1.2.1"} + testRunHelper([]runTestCase{{"1.2", "1.2.1", policy.NewSemverPolicy(policy.SemverPolicyTypePatch, false)}}, availableTags, t) + testRunHelper([]runTestCase{{"1.2", "1.5", policy.NewSemverPolicy(policy.SemverPolicyTypeMinor, false)}}, availableTags, t) + testRunHelper([]runTestCase{{"1.2", "2.0", policy.NewSemverPolicy(policy.SemverPolicyTypeMajor, false)}}, availableTags, t) +} + // Bug #490: new major version "hiding" minor one func TestWatchAllTagsHiddenMinor(t *testing.T) { availableTags := []string{"1.3.0", "1.5.0", "2.0.0", "1.2.1"} diff --git a/util/version/version.go b/util/version/version.go index f9c8fdfd..8810caf8 100644 --- a/util/version/version.go +++ b/util/version/version.go @@ -32,7 +32,7 @@ func MustParse(version string) *types.Version { func GetVersion(version string) (*types.Version, error) { parts := strings.SplitN(version, ".", 3) - if len(parts) != 3 { + if len(parts) != 2 && len(parts) != 3 { return nil, ErrNoMajorMinorPatchElementsFound } diff --git a/util/version/version_test.go b/util/version/version_test.go index bf39527d..13fe1cb2 100644 --- a/util/version/version_test.go +++ b/util/version/version_test.go @@ -45,6 +45,12 @@ func TestGetVersionFromImageName(t *testing.T) { want: MustParse("0.1.14"), wantErr: false, }, + { + name: "2 point semver, missing minor", + args: args{name: "index.docker.io/application:12.14"}, + want: MustParse("12.14"), + wantErr: false, + }, { name: "non semver, missing minor and patch", args: args{name: "index.docker.io/application:42"},