From 0ca479474594de7e798cd8631a06c6c9aa77bdff Mon Sep 17 00:00:00 2001 From: Jamie Magee <jamie.magee@gmail.com> Date: Wed, 24 Aug 2022 22:10:35 -0700 Subject: [PATCH] feat(versioning): add kubernetes-api versioning (#16570) Co-authored-by: Michael Kriese <michael.kriese@visualon.de> --- lib/modules/versioning/api.ts | 2 + .../versioning/kubernetes-api/index.spec.ts | 145 ++++++++++++++++++ .../versioning/kubernetes-api/index.ts | 22 +++ 3 files changed, 169 insertions(+) create mode 100644 lib/modules/versioning/kubernetes-api/index.spec.ts create mode 100644 lib/modules/versioning/kubernetes-api/index.ts diff --git a/lib/modules/versioning/api.ts b/lib/modules/versioning/api.ts index 7dfb74d219..7329e25b87 100644 --- a/lib/modules/versioning/api.ts +++ b/lib/modules/versioning/api.ts @@ -11,6 +11,7 @@ import * as helm from './helm'; import * as hermit from './hermit'; import * as hex from './hex'; import * as ivy from './ivy'; +import * as kubernetesApi from './kubernetes-api'; import * as loose from './loose'; import * as maven from './maven'; import * as node from './node'; @@ -46,6 +47,7 @@ api.set(helm.id, helm.api); api.set(hermit.id, hermit.api); api.set(hex.id, hex.api); api.set(ivy.id, ivy.api); +api.set(kubernetesApi.id, kubernetesApi.api); api.set(loose.id, loose.api); api.set(maven.id, maven.api); api.set(node.id, node.api); diff --git a/lib/modules/versioning/kubernetes-api/index.spec.ts b/lib/modules/versioning/kubernetes-api/index.spec.ts new file mode 100644 index 0000000000..82130abcb7 --- /dev/null +++ b/lib/modules/versioning/kubernetes-api/index.spec.ts @@ -0,0 +1,145 @@ +import { KubernetesApiVersioningApi } from './index'; + +describe('modules/versioning/kubernetes-api/index', () => { + const versioning = new KubernetesApiVersioningApi(); + + test.each` + version | expected + ${'v1'} | ${true} + ${'v2'} | ${true} + ${'v1alpha1'} | ${false} + ${'v1beta11'} | ${false} + `('isStable("$version") === $expected', ({ version, expected }) => { + expect(versioning.isStable(version)).toBe(expected); + }); + + test.each` + version | expected + ${'v1'} | ${true} + ${'v2'} | ${true} + ${'v10'} | ${true} + ${'v1.0'} | ${false} + ${'1'} | ${false} + ${'2'} | ${false} + ${'10'} | ${false} + ${'1.0'} | ${false} + ${'apps/v1'} | ${true} + ${'telemetry.istio.io/v1alpha1'} | ${true} + ${'k3d.io/v1alpha2'} | ${true} + ${'extensions/v1beta1'} | ${true} + ${'apps/v1beta2'} | ${true} + ${'autoscaling/v2'} | ${true} + ${'acme.cert-manager.io/v1'} | ${true} + `('isValid("$version") === $expected', ({ version, expected }) => { + expect(versioning.isValid(version)).toBe(expected); + }); + + test.each` + version | major | minor | patch + ${'v1'} | ${1} | ${0} | ${0} + ${'v2'} | ${2} | ${0} | ${0} + ${'v1alpha1'} | ${1} | ${0} | ${0} + ${'v1alpha2'} | ${1} | ${0} | ${0} + ${'v1beta1'} | ${1} | ${0} | ${0} + ${'v1beta2'} | ${1} | ${0} | ${0} + `( + 'getMajor, getMinor, getPatch for "$version"', + ({ version, major, minor, patch }) => { + expect(versioning.getMajor(version)).toBe(major); + expect(versioning.getMinor(version)).toBe(minor); + expect(versioning.getPatch(version)).toBe(patch); + } + ); + + test.each` + version | other | expected + ${'v1'} | ${'v1'} | ${true} + ${'v1'} | ${'v2'} | ${false} + ${'v1'} | ${'v1alpha1'} | ${false} + ${'v1'} | ${'v1alpha2'} | ${false} + ${'v1'} | ${'v1beta1'} | ${false} + ${'v1'} | ${'v1beta2'} | ${false} + ${'v1alpha1'} | ${'v1alpha1'} | ${true} + ${'v1alpha1'} | ${'v1alpha2'} | ${false} + ${'v1alpha1'} | ${'v1beta1'} | ${false} + ${'v1alpha1'} | ${'v1beta2'} | ${false} + ${'apps/v1'} | ${'apps/v1'} | ${true} + ${'apps/v1'} | ${'apps/v2'} | ${false} + ${'apps/v1'} | ${'apps/v1alpha1'} | ${false} + ${'apps/v1'} | ${'apps/v1beta1'} | ${false} + ${'apps/v1'} | ${'autoscaling/v1'} | ${true} + ${'apps/v1'} | ${'autoscaling/v2'} | ${false} + ${'apps/v1'} | ${'autoscaling/v1alpha1'} | ${false} + ${'apps/v1'} | ${'autoscaling/v1beta1'} | ${false} + `( + 'equals("$version", "$other") === $expected', + ({ version, other, expected }) => { + expect(versioning.equals(version, other)).toBe(expected); + } + ); + + test.each` + version | other | expected + ${'v1'} | ${'v1'} | ${true} + ${'v1'} | ${'v2'} | ${false} + ${'v1'} | ${'v1alpha1'} | ${false} + ${'v1'} | ${'v1alpha2'} | ${false} + ${'v1'} | ${'v1beta1'} | ${false} + ${'v1'} | ${'v1beta2'} | ${false} + ${'v1alpha1'} | ${'v1alpha1'} | ${true} + ${'v1alpha1'} | ${'v1alpha2'} | ${false} + ${'v1alpha1'} | ${'v1beta1'} | ${false} + ${'v1alpha1'} | ${'v1beta2'} | ${false} + `( + 'matches("$version", "$other") === $expected', + ({ version, other, expected }) => { + expect(versioning.matches(version, other)).toBe(expected); + } + ); + + test.each` + version | other | expected + ${'v1'} | ${'v2'} | ${false} + ${'v1'} | ${'v1alpha1'} | ${true} + ${'v1'} | ${'v1beta1'} | ${true} + ${'v2'} | ${'v1beta1'} | ${true} + ${'v1alpha1'} | ${'v1alpha2'} | ${false} + ${'v1beta1'} | ${'v1alpha1'} | ${true} + ${'v1beta2'} | ${'v1beta1'} | ${true} + `( + 'isGreaterThan("$version", "$other") === $expected', + ({ version, other, expected }) => { + expect(versioning.isGreaterThan(version, other)).toBe(expected); + } + ); + + it('sorts versions in an ascending order', () => { + expect( + [ + 'v10', + 'v2', + 'v2beta2', + 'v2beta1', + 'v2alpha2', + 'v2alpha1', + 'v1', + 'v1beta2', + 'v1beta1', + 'v1alpha2', + 'v1alpha1', + ].sort((a, b) => versioning.sortVersions(a, b)) + ).toEqual([ + 'v1alpha1', + 'v1alpha2', + 'v1beta1', + 'v1beta2', + 'v1', + 'v2alpha1', + 'v2alpha2', + 'v2beta1', + 'v2beta2', + 'v2', + 'v10', + ]); + }); +}); diff --git a/lib/modules/versioning/kubernetes-api/index.ts b/lib/modules/versioning/kubernetes-api/index.ts new file mode 100644 index 0000000000..c620991813 --- /dev/null +++ b/lib/modules/versioning/kubernetes-api/index.ts @@ -0,0 +1,22 @@ +import { RegExpVersioningApi } from '../regex'; +import type { VersioningApi } from '../types'; + +export const id = 'kubernetes-api'; +export const displayName = 'Kubernetes API'; +export const urls = [ + 'https://kubernetes.io/docs/reference/using-api/#api-versioning', +]; +export const supportsRanges = false; + +export class KubernetesApiVersioningApi extends RegExpVersioningApi { + private static readonly versionRegex = + '^(?:(?<compatibility>\\S+)\\/)?v(?<major>\\d+)(?<prerelease>(?:alpha|beta)\\d+)?$'; + + public constructor() { + super(KubernetesApiVersioningApi.versionRegex); + } +} + +export const api: VersioningApi = new KubernetesApiVersioningApi(); + +export default api; -- GitLab