Skip to content

Commit 9b6c149

Browse files
authored
Merge pull request #248 from nicholasSUSE/auto-chart-bump-net-new-chart-add
Auto chart bump net new chart add
2 parents f114953 + 49c3c9e commit 9b6c149

6 files changed

Lines changed: 97 additions & 39 deletions

File tree

main.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ const (
7676
defaultPrimeUserEnvironmentVariable = "PRIME_USER"
7777
defaultPrimePasswordEnvironmentVariable = "PRIME_PASSWORD"
7878
defaultPrimeURLEnvironmentVariable = "PRIME_URL"
79+
// New Chart Options for Autobump
80+
defaultNewChartVariable = "NEW_CHART"
7981
)
8082

8183
var (
@@ -133,6 +135,8 @@ var (
133135
PrimePassword string
134136
// PrimeURL of SUSE Prime registry
135137
PrimeURL string
138+
// NewChart boolean option for creating a net-new chart with auto-bump
139+
NewChart bool
136140
)
137141

138142
func init() {
@@ -383,6 +387,15 @@ func main() {
383387
Destination: &OverrideVersion,
384388
EnvVar: defaultOverrideVersionEnvironmentVariable,
385389
}
390+
newChartFlag := cli.BoolFlag{
391+
Name: "new-chart",
392+
Usage: `Usage:
393+
-new-chart=<false or true>
394+
`,
395+
Required: false,
396+
Destination: &NewChart,
397+
EnvVar: defaultNewChartVariable,
398+
}
386399

387400
// Commands
388401
app.Commands = []cli.Command{
@@ -547,7 +560,7 @@ func main() {
547560
Usage: `Generate a new chart bump PR.`,
548561
Action: chartBump,
549562
Before: setupCache,
550-
Flags: []cli.Flag{packageFlag, branchFlag, overrideVersionFlag, multiRCFlag},
563+
Flags: []cli.Flag{packageFlag, branchFlag, overrideVersionFlag, multiRCFlag, newChartFlag},
551564
},
552565
}
553566

@@ -979,7 +992,7 @@ func lifecycleStatus(c *cli.Context) {
979992

980993
getRepoRoot()
981994
rootFs := filesystem.GetFilesystem(RepoRoot)
982-
lifeCycleDep, err := lifecycle.InitDependencies(ctx, RepoRoot, rootFs, c.String("branch-version"), CurrentChart)
995+
lifeCycleDep, err := lifecycle.InitDependencies(ctx, rootFs, RepoRoot, c.String("branch-version"), CurrentChart, false)
983996
if err != nil {
984997
logger.Fatal(ctx, fmt.Errorf("encountered error while initializing dependencies: %w", err).Error())
985998
}
@@ -1005,7 +1018,7 @@ func autoForwardPort(c *cli.Context) {
10051018
getRepoRoot()
10061019
rootFs := filesystem.GetFilesystem(RepoRoot)
10071020

1008-
lifeCycleDep, err := lifecycle.InitDependencies(ctx, RepoRoot, rootFs, c.String("branch-version"), CurrentChart)
1021+
lifeCycleDep, err := lifecycle.InitDependencies(ctx, rootFs, RepoRoot, c.String("branch-version"), CurrentChart, false)
10091022
if err != nil {
10101023
logger.Fatal(ctx, fmt.Errorf("encountered error while initializing dependencies: %w", err).Error())
10111024
}
@@ -1042,7 +1055,7 @@ func release(c *cli.Context) {
10421055
getRepoRoot()
10431056
rootFs := filesystem.GetFilesystem(RepoRoot)
10441057

1045-
dependencies, err := lifecycle.InitDependencies(ctx, RepoRoot, rootFs, c.String("branch-version"), CurrentChart)
1058+
dependencies, err := lifecycle.InitDependencies(ctx, rootFs, RepoRoot, c.String("branch-version"), CurrentChart, false)
10461059
if err != nil {
10471060
logger.Fatal(ctx, fmt.Errorf("encountered error while initializing dependencies: %w", err).Error())
10481061
}
@@ -1101,7 +1114,7 @@ func validateRelease(c *cli.Context) {
11011114
logger.Fatal(ctx, "branch must be in the format release-v2.x")
11021115
}
11031116

1104-
dependencies, err := lifecycle.InitDependencies(ctx, RepoRoot, rootFs, strings.TrimPrefix(Branch, "release-v"), "")
1117+
dependencies, err := lifecycle.InitDependencies(ctx, rootFs, RepoRoot, strings.TrimPrefix(Branch, "release-v"), "", false)
11051118
if err != nil {
11061119
logger.Fatal(ctx, fmt.Errorf("encountered error while initializing dependencies: %w", err).Error())
11071120
}
@@ -1149,12 +1162,12 @@ func chartBump(c *cli.Context) {
11491162
ChartsScriptOptionsFile = path.ConfigurationYamlFile
11501163
chartsScriptOptions := parseScriptOptions(ctx)
11511164

1152-
bump, err := auto.SetupBump(ctx, RepoRoot, CurrentPackage, Branch, chartsScriptOptions)
1165+
bump, err := auto.SetupBump(ctx, RepoRoot, CurrentPackage, Branch, chartsScriptOptions, NewChart)
11531166
if err != nil {
11541167
logger.Fatal(ctx, fmt.Errorf("failed to setup: %w", err).Error())
11551168
}
11561169

1157-
if err := bump.BumpChart(ctx, OverrideVersion, MultiRC); err != nil {
1170+
if err := bump.BumpChart(ctx, OverrideVersion, MultiRC, NewChart); err != nil {
11581171
logger.Fatal(ctx, fmt.Errorf("failed to bump: %w", err).Error())
11591172
}
11601173
}

pkg/auto/chart_bump.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var ChartTargetsMap = map[string][]string{
5151
"sriov": {"sriov", "sriov-crd"},
5252
"system-upgrade-controller": {"system-upgrade-controller"},
5353
"ui-plugin-operator": {"ui-plugin-operator", "ui-plugin-operator-crd"},
54+
"rancher-turtles": {"rancher-turtles"},
5455
}
5556

5657
// Bump represents the chart bump process for a single chart
@@ -124,7 +125,7 @@ var (
124125
*/
125126

126127
// SetupBump will load and parse all related information to the chart that should be bumped.
127-
func SetupBump(ctx context.Context, repoRoot, targetPackage, targetBranch string, chScriptOpts *options.ChartsScriptOptions) (*Bump, error) {
128+
func SetupBump(ctx context.Context, repoRoot, targetPackage, targetBranch string, chScriptOpts *options.ChartsScriptOptions, newChart bool) (*Bump, error) {
128129
logger.Log(ctx, slog.LevelInfo, "setup auto-chart-bump")
129130

130131
bump := &Bump{
@@ -144,7 +145,7 @@ func SetupBump(ctx context.Context, repoRoot, targetPackage, targetBranch string
144145
}
145146

146147
//Initialize the lifecycle dependencies because of the versioning rules and the index.yaml mapping.
147-
dependencies, err := lifecycle.InitDependencies(ctx, repoRoot, filesystem.GetFilesystem(repoRoot), branch, bump.target.main)
148+
dependencies, err := lifecycle.InitDependencies(ctx, filesystem.GetFilesystem(repoRoot), repoRoot, branch, bump.target.main, newChart)
148149
if err != nil {
149150
err = fmt.Errorf("failure at SetupBump: %w ", err)
150151
return bump, err
@@ -210,9 +211,12 @@ func SetupBump(ctx context.Context, repoRoot, targetPackage, targetBranch string
210211
slog.Bool("DoNotRelease", bump.Pkg.DoNotRelease),
211212
slog.Bool("Auto", bump.Pkg.Auto),
212213
),
213-
slog.String("last version", bump.assetsVersionsMap[bump.target.main][0].Version),
214214
))
215215

216+
if !newChart {
217+
logger.Log(ctx, slog.LevelInfo, "", slog.String("last version", bump.assetsVersionsMap[bump.target.main][0].Version))
218+
}
219+
216220
return bump, nil
217221
}
218222

@@ -319,15 +323,15 @@ func checkUpstreamOptions(options *options.UpstreamOptions) error {
319323

320324
// BumpChart will execute a similar approach as the defined development workflow for chartowners.
321325
// The main difference is that between the steps: (make prepare and make patch) we will calculate the next version to release.
322-
func (b *Bump) BumpChart(ctx context.Context, versionOverride string, multiRCs bool) error {
326+
func (b *Bump) BumpChart(ctx context.Context, versionOverride string, multiRCs, newChart bool) error {
323327
logger.Log(ctx, slog.LevelInfo, "start auto-chart-bump")
324328

325329
if err := b.prepare(ctx); err != nil {
326330
return err
327331
}
328332

329333
// Calculate the next version to release
330-
if err := b.calculateNextVersion(ctx, versionOverride); err != nil {
334+
if err := b.calculateNextVersion(ctx, versionOverride, newChart); err != nil {
331335
return err
332336
}
333337

@@ -348,7 +352,7 @@ func (b *Bump) BumpChart(ctx context.Context, versionOverride string, multiRCs b
348352
}
349353

350354
// check if should remove previous RCs versions
351-
if !multiRCs {
355+
if !multiRCs && !newChart {
352356
logger.Log(ctx, slog.LevelWarn, "removing existing RC's")
353357
if err := b.checkMultiRC(ctx); err != nil {
354358
return err

pkg/auto/versioning.go

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"log/slog"
7+
"strconv"
78
"strings"
89

910
"github.com/blang/semver"
@@ -53,32 +54,41 @@ func (v *version) updateTxt() {
5354
// if the chart had a patch bump, it will increment the patch version for the repoPrefixVersion
5455
// if the chart had a minor or major bump, it will increment the minor version for the repoPrefixVersion
5556
// the major repoPrefixVersion is only bumped when Rancher version is bumped.
56-
func (b *Bump) calculateNextVersion(ctx context.Context, versionOverride string) error {
57+
func (b *Bump) calculateNextVersion(ctx context.Context, versionOverride string, newChart bool) error {
5758
logger.Log(ctx, slog.LevelInfo, "calculate next version")
5859

59-
// load versions and parse the repository prefix versions from them
60-
if err := b.loadVersions(); err != nil {
61-
return err
62-
}
60+
if newChart {
61+
if err := b.netNewVersion(); err != nil {
62+
return err
63+
}
64+
} else {
65+
// load versions and parse the repository prefix versions from them
66+
if err := b.loadVersions(); err != nil {
67+
return err
68+
}
6369

64-
// check and parse the versions before building the new version
65-
if err := b.applyVersionRules(versionOverride); err != nil {
66-
return err
67-
}
70+
// check and parse the versions before building the new version
71+
if err := b.applyVersionRules(versionOverride); err != nil {
72+
return err
73+
}
6874

69-
logger.Log(ctx, slog.LevelInfo, "checking current RC's")
70-
currentRCs, err := getCurrentRCsFromIndex(b.assetsVersionsMap[b.target.main], b.versions.toReleaseRepoPrefix.txt)
71-
if err != nil {
72-
logger.Log(ctx, slog.LevelError, "failed checking RC's", logger.Err(err), slog.String("version", b.target.main))
73-
return err
74-
}
75-
if currentRCs != nil && len(currentRCs) > 0 {
76-
b.versions.currentRCs = currentRCs
77-
logger.Log(ctx, slog.LevelWarn, "RCs present", slog.Any("amount", len(currentRCs)))
78-
for _, rc := range currentRCs {
79-
rcVersion := rc.repoPrefix.txt + "+up" + rc.appVersion.txt
80-
logger.Log(ctx, slog.LevelDebug, "", slog.String("version", rcVersion))
75+
logger.Log(ctx, slog.LevelInfo, "checking current RC's")
76+
currentRCs, err := getCurrentRCsFromIndex(b.assetsVersionsMap[b.target.main], b.versions.toReleaseRepoPrefix.txt)
77+
if err != nil {
78+
logger.Log(ctx, slog.LevelError, "failed checking RC's", logger.Err(err), slog.String("version", b.target.main))
79+
return err
8180
}
81+
if currentRCs != nil && len(currentRCs) > 0 {
82+
b.versions.currentRCs = currentRCs
83+
logger.Log(ctx, slog.LevelWarn, "RCs present", slog.Any("amount", len(currentRCs)))
84+
for _, rc := range currentRCs {
85+
rcVersion := rc.repoPrefix.txt + "+up" + rc.appVersion.txt
86+
logger.Log(ctx, slog.LevelDebug, "", slog.String("version", rcVersion))
87+
}
88+
}
89+
90+
logger.Log(ctx, slog.LevelDebug, "", slog.String("latestVersion", b.versions.latest.txt))
91+
logger.Log(ctx, slog.LevelDebug, "", slog.String("latestRepoVersion", b.versions.latestRepoPrefix.txt))
8292
}
8393

8494
// build: toRelease full version
@@ -87,14 +97,35 @@ func (b *Bump) calculateNextVersion(ctx context.Context, versionOverride string)
8797
b.releaseYaml.ChartVersion = targetVersion
8898
b.Pkg.AutoGeneratedBumpVersion = &targetSemver
8999

90-
logger.Log(ctx, slog.LevelDebug, "", slog.String("latestVersion", b.versions.latest.txt))
91-
logger.Log(ctx, slog.LevelDebug, "", slog.String("latestRepoVersion", b.versions.latestRepoPrefix.txt))
92100
logger.Log(ctx, slog.LevelDebug, "", slog.String("toReleaseVersion", b.versions.toRelease.txt))
93101
logger.Log(ctx, slog.LevelDebug, "", slog.String("toReleaseRepoVersion", b.versions.toReleaseRepoPrefix.txt))
94102
logger.Log(ctx, slog.LevelInfo, "calculated bump", slog.String("version", b.Pkg.AutoGeneratedBumpVersion.String()))
95103
return nil
96104
}
97105

106+
// netNewVersion will calculate the first version for a previous non-existing chart
107+
func (b *Bump) netNewVersion() error {
108+
b.versions = &versions{
109+
toRelease: &version{},
110+
toReleaseRepoPrefix: &version{},
111+
}
112+
113+
b.versions.toRelease.txt = b.Pkg.Chart.GetUpstreamVersion()
114+
if b.versions.toRelease.txt == "" {
115+
return errChartUpstreamVersion
116+
}
117+
if err := b.versions.toRelease.updateSemver(); err != nil {
118+
return err
119+
}
120+
121+
b.versions.toReleaseRepoPrefix.txt = strconv.Itoa(b.versionRules.MaxVersion-1) + ".0.0"
122+
if err := b.versions.toReleaseRepoPrefix.updateSemver(); err != nil {
123+
return err
124+
}
125+
126+
return nil
127+
}
128+
98129
// loadVersions will load the latest version from the index.yaml and the version to release from the chart owner upstream repository
99130
// rules:
100131
// - latest version might not contain a repoPrefixVersion

pkg/auto/versioning_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ func Test_calculateNextVersion(t *testing.T) {
402402

403403
for _, tc := range tests {
404404
t.Run(tc.name, func(t *testing.T) {
405-
err := tc.input.b.calculateNextVersion(context.Background(), tc.input.versionOverride)
405+
err := tc.input.b.calculateNextVersion(context.Background(), tc.input.versionOverride, false)
406406
assertError(t, err, tc.expected.err)
407407
if tc.expected.err == nil {
408408
assert.Equal(t, tc.expected.b.releaseYaml.ChartVersion, tc.input.b.releaseYaml.ChartVersion)

pkg/lifecycle/lifecycle.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ type WalkDirFunc func(ctx context.Context, fs billy.Filesystem, dirPath string,
3939
// InitDependencies will check the filesystem, branch version,
4040
// git status, initialize the Dependencies struct and populate it.
4141
// If anything fails the operation will be aborted.
42-
func InitDependencies(ctx context.Context, repoRoot string, rootFs billy.Filesystem, branchVersion string, currentChart string) (*Dependencies, error) {
42+
func InitDependencies(ctx context.Context, rootFs billy.Filesystem, repoRoot, branchVersion, currentChart string, newChart bool) (*Dependencies, error) {
43+
if newChart && currentChart == "" {
44+
return nil, errors.New("can't create a new empty chart")
45+
}
46+
4347
var err error
4448

4549
workDir := repoRoot
@@ -76,6 +80,12 @@ func InitDependencies(ctx context.Context, repoRoot string, rootFs billy.Filesys
7680
return nil, err
7781
}
7882

83+
if newChart {
84+
dep.AssetsVersionsMap = make(map[string][]Asset)
85+
dep.AssetsVersionsMap[currentChart] = []Asset{}
86+
return dep, nil
87+
}
88+
7989
// Get the absolute path of the Helm index file and assets versions map to apply rules
8090
helmIndexPath := filesystem.GetAbsPath(dep.RootFs, path.RepositoryHelmIndexFile)
8191
dep.AssetsVersionsMap, err = getAssetsMapFromIndex(helmIndexPath, currentChart)

pkg/validate/validate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func CompareGeneratedAssets(ctx context.Context, repoRoot string, repoFs billy.F
7575
}
7676

7777
// Initialize lifecycle package for validating with assets lifecycle rules
78-
lifeCycleDep, err := lifecycle.InitDependencies(ctx, repoRoot, repoFs, lifecycle.ExtractBranchVersion(branch), "")
78+
lifeCycleDep, err := lifecycle.InitDependencies(ctx, repoFs, repoRoot, lifecycle.ExtractBranchVersion(branch), "", false)
7979
if err != nil {
8080
logger.Log(ctx, slog.LevelError, "failed to initialize lifecycle dependencies", logger.Err(err))
8181
return response, err

0 commit comments

Comments
 (0)