Skip to content

Commit 3dbd25b

Browse files
committed
feat: add check metadata version CLI utility
This adds a CLI utility which given a version number will check that there is a release series defined in a metadata file for that version. The main use case for this is a CI check. When building a release of a provider that is for a new major or minor version its required that a new release series is added to the providers metadata file. This ensures that the correct version of the provider is installed when initializing a management cluster. A common failure for release pipelines is that the metadata file hasn't been updated. Signed-off-by: Richard Case <[email protected]>
1 parent d43e0ac commit 3dbd25b

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Metadata Version Validator
2+
3+
## Purpose
4+
5+
A small utility that given a version number it will check that a release series is defined in the passed in metadata.yaml file.
6+
7+
This is primarily for use in release pipelines.
8+
9+
## Usage
10+
11+
First create the binary by:
12+
13+
```bash
14+
cd hack/tools
15+
go build -tags=tools -o bin/metadata-version-validator sigs.k8s.io/cluster-api/hack/tools/metadata-version-validator
16+
```
17+
18+
Then run the binary to check a version:
19+
20+
```bash
21+
bin/metadata-version-validator --file ../../cluster-api-provider-aws/metadata.yaml --version v2.8.0
22+
```
23+
24+
If there is no release series defined there will be an error message and also a non-zero exit code.
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// main is the main package for metadata-version-validator.
18+
package main
19+
20+
import (
21+
"flag"
22+
"fmt"
23+
"os"
24+
"strings"
25+
26+
"github.com/blang/semver/v4"
27+
"k8s.io/apimachinery/pkg/runtime"
28+
"k8s.io/apimachinery/pkg/runtime/serializer"
29+
"k8s.io/klog/v2"
30+
31+
clusterctlv1 "sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3"
32+
)
33+
34+
func main() {
35+
file := flag.String("file", "", "Path to metadata.yaml file to check")
36+
version := flag.String("version", "metadata.yaml", "The version number to check against the metadata file")
37+
38+
flag.Parse()
39+
40+
if *file == "" {
41+
klog.Exit("--file must be specified")
42+
}
43+
if *version == "" {
44+
klog.Exit("--version must be specified")
45+
}
46+
47+
if err := runCheckMetadata(*file, *version); err != nil {
48+
klog.Exitf("failed checking metadata: %v", err)
49+
}
50+
}
51+
52+
func runCheckMetadata(file, version string) error {
53+
versionToCheck := strings.TrimPrefix(version, "v")
54+
55+
ver, err := semver.Parse(versionToCheck)
56+
if err != nil {
57+
return fmt.Errorf("failed parsing %s as semver version: %w", version, err)
58+
}
59+
60+
fileData, err := os.ReadFile(file) //nolint:gosec
61+
if err != nil {
62+
return fmt.Errorf("failed reading file %s: %w", file, err)
63+
}
64+
65+
scheme := runtime.NewScheme()
66+
if err := clusterctlv1.AddToScheme(scheme); err != nil {
67+
return fmt.Errorf("failed to add metadata type to scheme: %w", err)
68+
}
69+
metadata := &clusterctlv1.Metadata{}
70+
codecFactory := serializer.NewCodecFactory(scheme)
71+
72+
if err := runtime.DecodeInto(codecFactory.UniversalDecoder(), fileData, metadata); err != nil {
73+
return fmt.Errorf("failed decoding metadata from file: %w", err)
74+
}
75+
76+
for _, series := range metadata.ReleaseSeries {
77+
if series.Major == int32(ver.Major) && series.Minor == int32(ver.Minor) {
78+
klog.Info("Success, there is a release series defined in the metadata file")
79+
return nil
80+
}
81+
}
82+
83+
return fmt.Errorf("failed to find release series for version %s in metadata files %s", version, file)
84+
}

0 commit comments

Comments
 (0)