mirror of https://github.com/helm/helm
Signed-off-by: Jan Braje <12571346+janluak@users.noreply.github.com>pull/32402/head
parent
06978bd8c5
commit
3120d85753
@ -0,0 +1,353 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package action
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
|
chart "helm.sh/helm/v4/pkg/chart/v2"
|
||||||
|
"helm.sh/helm/v4/pkg/chart/v2/loader"
|
||||||
|
"helm.sh/helm/v4/pkg/chart/v2/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Bump is the action for bumping a chart version.
|
||||||
|
//
|
||||||
|
// It provides the implementation of 'helm bump'.
|
||||||
|
type Bump struct {
|
||||||
|
ChartPathOptions
|
||||||
|
cfg *Configuration
|
||||||
|
|
||||||
|
bump string
|
||||||
|
chart *chart.Chart
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultBumpType = "patch"
|
||||||
|
|
||||||
|
// NewBump creates a new Bump object with the given configuration.
|
||||||
|
func NewBump(cfg *Configuration) *Bump {
|
||||||
|
return &Bump{
|
||||||
|
cfg: cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run executes 'helm bump' against the given chart.
|
||||||
|
func (b *Bump) Run(bumpType string, chartpath string) (string, error) {
|
||||||
|
if b.chart == nil {
|
||||||
|
chrt, err := loader.Load(chartpath)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
b.chart = chrt
|
||||||
|
}
|
||||||
|
cv, err := yaml.Marshal(b.chart.Metadata.Version)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// Determine new version based on bump type or explicit version
|
||||||
|
b.bump = bumpType
|
||||||
|
if b.bump == "" {
|
||||||
|
// Default to "patch" if no version specified
|
||||||
|
b.bump = defaultBumpType
|
||||||
|
}
|
||||||
|
|
||||||
|
currentVersion := strings.TrimSpace(string(cv))
|
||||||
|
if !isValidVersion(currentVersion) {
|
||||||
|
return "", fmt.Errorf("invalid origin version: %s", currentVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
var newVersion string
|
||||||
|
switch b.bump {
|
||||||
|
case "major":
|
||||||
|
newVersion, err = bumpMajor(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump major version: %w", err)
|
||||||
|
}
|
||||||
|
case "minor":
|
||||||
|
newVersion, err = bumpMinor(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump minor version: %w", err)
|
||||||
|
}
|
||||||
|
case "patch":
|
||||||
|
newVersion, err = bumpPatch(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump patch version: %w", err)
|
||||||
|
}
|
||||||
|
case "stable":
|
||||||
|
newVersion, err = bumpStable(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump stable version: %w", err)
|
||||||
|
}
|
||||||
|
case "alpha":
|
||||||
|
newVersion, err = bumpAlpha(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump alpha version: %w", err)
|
||||||
|
}
|
||||||
|
case "beta":
|
||||||
|
newVersion, err = bumpBeta(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump beta version: %w", err)
|
||||||
|
}
|
||||||
|
case "rc":
|
||||||
|
newVersion, err = bumpRC(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump rc version: %w", err)
|
||||||
|
}
|
||||||
|
case "post":
|
||||||
|
newVersion, err = bumpPost(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump post version: %w", err)
|
||||||
|
}
|
||||||
|
case "dev":
|
||||||
|
newVersion, err = bumpDev(currentVersion)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to bump dev version: %w", err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if !isValidVersion(b.bump) {
|
||||||
|
return "", fmt.Errorf("invalid bump type or version: %s", b.bump)
|
||||||
|
}
|
||||||
|
newVersion = b.bump
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the chart metadata with the new version
|
||||||
|
b.chart.Metadata.Version = newVersion
|
||||||
|
|
||||||
|
// Save the updated chart to disk (this will update Chart.yaml)
|
||||||
|
err = util.SaveChartfile(filepath.Join(chartpath, "Chart.yaml"), b.chart.Metadata)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to save updated chart: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return newVersion, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpMajor increases the major version number (e.g., 1.2.3 -> 2.0.0)
|
||||||
|
func bumpMajor(version string) (string, error) {
|
||||||
|
parts := strings.Split(version, ".")
|
||||||
|
if len(parts) < 3 {
|
||||||
|
return "", errors.New("invalid version format for major bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
major, err := strconv.Atoi(parts[0])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid major version number")
|
||||||
|
}
|
||||||
|
|
||||||
|
newMajor := major + 1
|
||||||
|
return fmt.Sprintf("%d.0.0", newMajor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpMinor increases the minor version number (e.g., 1.2.3 -> 1.3.0)
|
||||||
|
func bumpMinor(version string) (string, error) {
|
||||||
|
parts := strings.Split(version, ".")
|
||||||
|
if len(parts) < 3 {
|
||||||
|
return "", errors.New("invalid version format for minor bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
major, err := strconv.Atoi(parts[0])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid major version number")
|
||||||
|
}
|
||||||
|
|
||||||
|
minor, err := strconv.Atoi(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid minor version number")
|
||||||
|
}
|
||||||
|
|
||||||
|
newMinor := minor + 1
|
||||||
|
return fmt.Sprintf("%d.%d.0", major, newMinor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpPatch increases the patch version number (e.g., 1.2.3 -> 1.2.4)
|
||||||
|
func bumpPatch(version string) (string, error) {
|
||||||
|
parts := strings.Split(version, ".")
|
||||||
|
if len(parts) < 3 {
|
||||||
|
return "", errors.New("invalid version format for patch bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
major, err := strconv.Atoi(parts[0])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid major version number")
|
||||||
|
}
|
||||||
|
|
||||||
|
minor, err := strconv.Atoi(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid minor version number")
|
||||||
|
}
|
||||||
|
|
||||||
|
patch, err := strconv.Atoi(parts[2])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid patch version number")
|
||||||
|
}
|
||||||
|
|
||||||
|
newPatch := patch + 1
|
||||||
|
return fmt.Sprintf("%d.%d.%d", major, minor, newPatch), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpStable removes any pre-release suffix (e.g., 1.2.3-alpha -> 1.2.3)
|
||||||
|
func bumpStable(version string) (string, error) {
|
||||||
|
// Remove any pre-release suffixes (like -alpha, -beta, etc.)
|
||||||
|
re := regexp.MustCompile(`^(\d+\.\d+\.\d+)(-.+)?$`)
|
||||||
|
matches := re.FindStringSubmatch(version)
|
||||||
|
if len(matches) < 2 {
|
||||||
|
return "", errors.New("invalid version format for stable bump")
|
||||||
|
}
|
||||||
|
return matches[1], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpAlpha increases the pre-release version (e.g., 1.2.3-alpha -> 1.2.3-alpha.1)
|
||||||
|
func bumpAlpha(version string) (string, error) {
|
||||||
|
// Check if version has an alpha suffix - simple regex that works with all cases
|
||||||
|
re := regexp.MustCompile(`^(\d+\.\d+\.\d+)(-alpha(?:\.(\d+))?)?$`)
|
||||||
|
matches := re.FindStringSubmatch(version)
|
||||||
|
if len(matches) < 2 {
|
||||||
|
return "", errors.New("invalid version format for alpha bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
baseVersion := matches[1]
|
||||||
|
var preRelease string
|
||||||
|
if len(matches) >= 4 && matches[3] != "" {
|
||||||
|
// Increment the pre-release number
|
||||||
|
num, err := strconv.Atoi(matches[3])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid alpha pre-release number")
|
||||||
|
}
|
||||||
|
preRelease = fmt.Sprintf(".%d", num+1)
|
||||||
|
} else {
|
||||||
|
// Start with .1 if no pre-release number exists
|
||||||
|
preRelease = ".1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseVersion + "-alpha" + preRelease, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpBeta increases the pre-release version (e.g., 1.2.3-beta -> 1.2.3-beta.1)
|
||||||
|
func bumpBeta(version string) (string, error) {
|
||||||
|
// Check if version has a beta suffix - simple regex that works with all cases
|
||||||
|
re := regexp.MustCompile(`^(\d+\.\d+\.\d+)(-beta(?:\.(\d+))?)?$`)
|
||||||
|
matches := re.FindStringSubmatch(version)
|
||||||
|
if len(matches) < 2 {
|
||||||
|
return "", errors.New("invalid version format for beta bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
baseVersion := matches[1]
|
||||||
|
var preRelease string
|
||||||
|
if len(matches) >= 4 && matches[3] != "" {
|
||||||
|
// Increment the pre-release number
|
||||||
|
num, err := strconv.Atoi(matches[3])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid beta pre-release number")
|
||||||
|
}
|
||||||
|
preRelease = fmt.Sprintf(".%d", num+1)
|
||||||
|
} else {
|
||||||
|
// Start with .1 if no pre-release number exists
|
||||||
|
preRelease = ".1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseVersion + "-beta" + preRelease, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpRC increases the pre-release version (e.g., 1.2.3-rc -> 1.2.3-rc.1)
|
||||||
|
func bumpRC(version string) (string, error) {
|
||||||
|
// Check if version has a rc suffix - simple regex that works with all cases
|
||||||
|
re := regexp.MustCompile(`^(\d+\.\d+\.\d+)(-rc(?:\.(\d+))?)?$`)
|
||||||
|
matches := re.FindStringSubmatch(version)
|
||||||
|
if len(matches) < 2 {
|
||||||
|
return "", errors.New("invalid version format for rc bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
baseVersion := matches[1]
|
||||||
|
var preRelease string
|
||||||
|
if len(matches) >= 4 && matches[3] != "" {
|
||||||
|
// Increment the pre-release number
|
||||||
|
num, err := strconv.Atoi(matches[3])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid rc pre-release number")
|
||||||
|
}
|
||||||
|
preRelease = fmt.Sprintf(".%d", num+1)
|
||||||
|
} else {
|
||||||
|
// Start with .1 if no pre-release number exists
|
||||||
|
preRelease = ".1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseVersion + "-rc" + preRelease, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpPost increases the post-release version (e.g., 1.2.3-post -> 1.2.3-post.1)
|
||||||
|
func bumpPost(version string) (string, error) {
|
||||||
|
// Check if version has a post-suffix
|
||||||
|
re := regexp.MustCompile(`^(\d+\.\d+\.\d+)(-post(\.(\d+))?)?$`)
|
||||||
|
matches := re.FindStringSubmatch(version)
|
||||||
|
if len(matches) < 2 {
|
||||||
|
return "", errors.New("invalid version format for post bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
baseVersion := matches[1]
|
||||||
|
var preRelease string
|
||||||
|
if len(matches) >= 4 && matches[4] != "" {
|
||||||
|
// Increment the pre-release number
|
||||||
|
num, err := strconv.Atoi(matches[4])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid post pre-release number")
|
||||||
|
}
|
||||||
|
preRelease = fmt.Sprintf(".%d", num+1)
|
||||||
|
} else {
|
||||||
|
// Start with .1 if no pre-release number exists
|
||||||
|
preRelease = ".1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseVersion + "-post" + preRelease, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bumpDev increases the dev version (e.g., 1.2.3-dev -> 1.2.3-dev.1)
|
||||||
|
func bumpDev(version string) (string, error) {
|
||||||
|
// Check if version has a dev suffix
|
||||||
|
re := regexp.MustCompile(`^(\d+\.\d+\.\d+)(-dev(\.(\d+))?)?$`)
|
||||||
|
matches := re.FindStringSubmatch(version)
|
||||||
|
if len(matches) < 2 {
|
||||||
|
return "", errors.New("invalid version format for dev bump")
|
||||||
|
}
|
||||||
|
|
||||||
|
baseVersion := matches[1]
|
||||||
|
var preRelease string
|
||||||
|
if len(matches) >= 4 && matches[4] != "" {
|
||||||
|
// Increment the pre-release number
|
||||||
|
num, err := strconv.Atoi(matches[4])
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.New("invalid dev pre-release number")
|
||||||
|
}
|
||||||
|
preRelease = fmt.Sprintf(".%d", num+1)
|
||||||
|
} else {
|
||||||
|
// Start with .1 if no pre-release number exists
|
||||||
|
preRelease = ".1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseVersion + "-dev" + preRelease, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// isValidVersion checks if a string is a valid semantic version format
|
||||||
|
func isValidVersion(version string) bool {
|
||||||
|
re := regexp.MustCompile(`^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+(\.\d+)?)?$`)
|
||||||
|
return re.MatchString(version)
|
||||||
|
}
|
||||||
@ -0,0 +1,437 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package action
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
chart "helm.sh/helm/v4/pkg/chart/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewBump(t *testing.T) {
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
|
||||||
|
assert.NotNil(t, client)
|
||||||
|
require.Equal(t, cfg, client.cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Major(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Major bump with valid version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("major", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "2.0.0", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Major bump with invalid version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("major", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Major bump with invalid major version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.a"
|
||||||
|
result, err := client.Run("major", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Minor(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Minor bump with valid version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("minor", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.3.0", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Minor bump with invalid version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("minor", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Minor bump with invalid minor version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.a.3"
|
||||||
|
result, err := client.Run("minor", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Patch(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Patch bump with valid version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("patch", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.4", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Patch bump with invalid version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("patch", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Patch bump with invalid patch version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.a"
|
||||||
|
result, err := client.Run("patch", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Stable(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Stable bump with pre-release version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-alpha"
|
||||||
|
result, err := client.Run("stable", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Stable bump with pre-release version with number", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-alpha.1"
|
||||||
|
result, err := client.Run("stable", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Stable bump with invalid version format", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("stable", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Alpha(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Alpha bump with version without pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("alpha", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-alpha.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Alpha bump with version with pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-alpha"
|
||||||
|
result, err := client.Run("alpha", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-alpha.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Alpha bump with version with pre-release number", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-alpha.1"
|
||||||
|
result, err := client.Run("alpha", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-alpha.2", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Alpha bump with invalid version format", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("alpha", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Beta(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Beta bump with version without pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("beta", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-beta.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Beta bump with version with pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-beta"
|
||||||
|
result, err := client.Run("beta", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-beta.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Beta bump with version with pre-release number", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-beta.1"
|
||||||
|
result, err := client.Run("beta", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-beta.2", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Beta bump with invalid version format", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("beta", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_RC(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("RC bump with version without pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("rc", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-rc.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("RC bump with version with pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-rc"
|
||||||
|
result, err := client.Run("rc", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-rc.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("RC bump with version with pre-release number", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-rc.1"
|
||||||
|
result, err := client.Run("rc", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-rc.2", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("RC bump with invalid version format", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("rc", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Post(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Post bump with version without pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("post", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-post.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Post bump with version with post-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-post"
|
||||||
|
result, err := client.Run("post", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-post.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Post bump with version with pre-release number", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-post.1"
|
||||||
|
result, err := client.Run("post", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-post.2", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Post bump with invalid version format", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("post", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_Dev(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Dev bump with version without pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("dev", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-dev.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Dev bump with version with pre-release", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-dev"
|
||||||
|
result, err := client.Run("dev", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-dev.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Dev bump with version with pre-release number", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3-dev.1"
|
||||||
|
result, err := client.Run("dev", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.3-dev.2", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Dev bump with invalid version format", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2"
|
||||||
|
result, err := client.Run("dev", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_ExplicitVersion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("Explicit version with valid format", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("2.0.1", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "2.0.1", result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Explicit version with post version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("1.5.3-post.1", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.5.3-post.1", result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_InvalidVersion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// We cannot test actual bumping since chart loading is not implemented,
|
||||||
|
// but we can test error handling for invalid bump types
|
||||||
|
t.Run("Invalid bump type", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("invalid", "")
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Empty(t, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_IsValidVersion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
version string
|
||||||
|
expected bool
|
||||||
|
}{
|
||||||
|
{"1.2.3", true},
|
||||||
|
{"1.2.3-alpha", true},
|
||||||
|
{"1.2.3-beta.1", true},
|
||||||
|
{"1.2.3-rc.2", true},
|
||||||
|
{"1.2.3-post.1", true},
|
||||||
|
{"1.2.3-dev.1", true},
|
||||||
|
{"1.2", false},
|
||||||
|
{"invalid", false},
|
||||||
|
{"1.2.3.4", false},
|
||||||
|
{"1.a.3", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run("Version "+tc.version, func(t *testing.T) {
|
||||||
|
result := isValidVersion(tc.version)
|
||||||
|
require.Equal(t, tc.expected, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBump_Run_WithDefault(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
cfg := actionConfigFixture(t)
|
||||||
|
client := NewBump(cfg)
|
||||||
|
client.chart = &chart.Chart{
|
||||||
|
Metadata: &chart.Metadata{Name: "test"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that it properly handles the default case
|
||||||
|
t.Run("Patch bump with valid version", func(t *testing.T) {
|
||||||
|
client.chart.Metadata.Version = "1.2.3"
|
||||||
|
result, err := client.Run("patch", "")
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "1.2.4", result)
|
||||||
|
require.Equal(t, "patch", client.bump)
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"helm.sh/helm/v4/pkg/action"
|
||||||
|
"helm.sh/helm/v4/pkg/cmd/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
const bumpDesc = `
|
||||||
|
Bump the version of a chart.
|
||||||
|
`
|
||||||
|
|
||||||
|
type bumpOptions struct {
|
||||||
|
bumpType string
|
||||||
|
chart string
|
||||||
|
}
|
||||||
|
|
||||||
|
// newBumpCmd creates a new bump command with the given configuration and output writer.
|
||||||
|
func newBumpCmd(actionConfig *action.Configuration, out io.Writer) *cobra.Command {
|
||||||
|
o := &bumpOptions{}
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "bump [VERSION_TYPE] [CHART]",
|
||||||
|
Short: "bump the version of a chart",
|
||||||
|
Long: bumpDesc,
|
||||||
|
Args: require.MaximumNArgs(2),
|
||||||
|
ValidArgsFunction: noMoreArgsCompFunc,
|
||||||
|
RunE: func(_ *cobra.Command, args []string) error {
|
||||||
|
if len(args) == 2 {
|
||||||
|
o.bumpType = args[0]
|
||||||
|
o.chart = args[1]
|
||||||
|
} else {
|
||||||
|
o.bumpType = ""
|
||||||
|
o.chart = args[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.run(actionConfig, out)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
f := cmd.Flags()
|
||||||
|
f.StringVar(&o.chart, "chart", "", "path to the chart directory")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *bumpOptions) run(actionConfig *action.Configuration, out io.Writer) error {
|
||||||
|
// Resolve the chart path to an absolute path
|
||||||
|
absPath, err := filepath.Abs(o.chart)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to resolve chart path: %w", err)
|
||||||
|
}
|
||||||
|
o.chart = absPath
|
||||||
|
|
||||||
|
bump := action.NewBump(actionConfig)
|
||||||
|
|
||||||
|
newVersion, err := bump.Run(o.bumpType, o.chart)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(out, "changed chart version to %q\n", newVersion)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBump(t *testing.T) {
|
||||||
|
tempChartDir := t.TempDir()
|
||||||
|
|
||||||
|
testChartFile := filepath.Join("testdata", "testcharts", "empty", "Chart.yaml")
|
||||||
|
|
||||||
|
destFile := filepath.Join(tempChartDir, "Chart.yaml")
|
||||||
|
|
||||||
|
srcFile, err := os.Open(testChartFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error on opening test file: %v", err)
|
||||||
|
}
|
||||||
|
defer srcFile.Close()
|
||||||
|
|
||||||
|
destFileHandle, err := os.Create(destFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error on creating test file: %v", err)
|
||||||
|
}
|
||||||
|
defer destFileHandle.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(destFileHandle, srcFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error on copying test file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tests := []cmdTestCase{{
|
||||||
|
name: "default",
|
||||||
|
cmd: "bump " + tempChartDir,
|
||||||
|
golden: "output/bump-default.txt",
|
||||||
|
}, {
|
||||||
|
name: "with bump type",
|
||||||
|
cmd: "bump minor " + tempChartDir,
|
||||||
|
golden: "output/bump-minor.txt",
|
||||||
|
}, {
|
||||||
|
name: "with explicit version",
|
||||||
|
cmd: "bump 2.0.0 " + tempChartDir,
|
||||||
|
golden: "output/bump-explicit.txt",
|
||||||
|
}}
|
||||||
|
runTestCmd(t, tests)
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
changed chart version to "0.1.1"
|
||||||
@ -0,0 +1 @@
|
|||||||
|
changed chart version to "2.0.0"
|
||||||
@ -0,0 +1 @@
|
|||||||
|
changed chart version to "0.2.0"
|
||||||
Loading…
Reference in new issue