1
1
package chart
2
2
3
3
import (
4
+ "context"
4
5
"fmt"
5
- "io/fs"
6
6
"log"
7
7
"os"
8
8
"path/filepath"
9
9
10
10
"github.com/Masterminds/semver"
11
11
"github.com/alexellis/arkade/pkg/helm"
12
+ "github.com/alexellis/go-execute/v2"
12
13
"github.com/spf13/cobra"
13
14
)
14
15
@@ -25,15 +26,16 @@ func MakeBump() *cobra.Command {
25
26
Long : `Bump the version present in the Chart.yaml of a Helm chart.
26
27
If the provided directory contains multiple charts, then the --recursive flag
27
28
can be used to bump the version in all charts.` ,
28
- Example : `arkade bump --dir ./chart
29
- arkade --dir ./charts --recursive ` ,
29
+ Example : `arkade chart bump --dir ./chart
30
+ arkade chart bump --dir ./charts --check-for-value-updates values.yaml ` ,
30
31
SilenceUsage : true ,
31
32
}
32
33
33
34
command .Flags ().StringP ("dir" , "d" , "" , "Path to the Helm chart directory or a directory containing Helm charts" )
34
35
command .Flags ().BoolP ("recursive" , "r" , false , "Recursively iterate through directory while bumping chart versions" )
35
36
command .Flags ().BoolP ("verbose" , "v" , false , "Verbose output" )
36
37
command .Flags ().BoolP ("write" , "w" , false , "Write the updated values back to the file, or stdout when set to false" )
38
+ command .Flags ().String ("check-for-value-updates" , "" , "File name to check if the chart's values have been modified before bumping version" )
37
39
38
40
command .RunE = func (cmd * cobra.Command , args []string ) error {
39
41
chartDir , err := cmd .Flags ().GetString ("dir" )
@@ -44,80 +46,85 @@ can be used to bump the version in all charts.`,
44
46
return fmt .Errorf ("flag --dir is required" )
45
47
}
46
48
verbose , _ := cmd .Flags ().GetBool ("verbose" )
47
- recursive , err := cmd .Flags ().GetBool ("recursive" )
48
- if err != nil {
49
- return fmt .Errorf ("invalid value for --recursive" )
50
- }
51
49
write , err := cmd .Flags ().GetBool ("write" )
52
50
if err != nil {
53
51
return fmt .Errorf ("invalid value for --write" )
54
52
}
53
+ valuesFile , err := cmd .Flags ().GetString ("check-for-value-updates" )
54
+ if err != nil {
55
+ return fmt .Errorf ("invalid value for --check-for-value-updates" )
56
+ }
55
57
56
58
// Map with key as the path to Chart.yaml and the value as the parsed contents of Chart.yaml
57
- chartYamls := make (map [string ]helm.ValuesMap , 0 )
58
- if ! recursive {
59
- chartYamlPath := filepath .Join (chartDir , ChartYamlFileName )
60
- var values helm.ValuesMap
61
- // Try to read a Chart.yaml, but if thats unsuccessful then fall back to Chart.yml
59
+ chartYamlPath := filepath .Join (chartDir , ChartYamlFileName )
60
+ var values helm.ValuesMap
61
+ // Try to read a Chart.yaml, but if thats unsuccessful then fall back to Chart.yml
62
+ if values , err = helm .Load (chartYamlPath ); err != nil {
63
+ if verbose {
64
+ log .Printf ("unable to read %s, falling back to Chart.yml\n " , chartYamlPath )
65
+ }
66
+ chartYamlPath = filepath .Join (chartDir , ChartYmlFileName )
62
67
if values , err = helm .Load (chartYamlPath ); err != nil {
63
- if verbose {
64
- log .Printf ("unable to read %s, falling back to Chart.yml\n " , chartYamlPath )
65
- }
66
- chartYamlPath = filepath .Join (chartDir , ChartYmlFileName )
67
- if values , err = helm .Load (chartYamlPath ); err != nil {
68
- return fmt .Errorf ("unable to read Chart.yaml or Chart.yml in directory %s" , chartDir )
69
- }
68
+ return fmt .Errorf ("unable to read Chart.yaml or Chart.yml in directory %s" , chartDir )
70
69
}
71
- chartYamls [chartYamlPath ] = values
70
+ }
71
+
72
+ // If the yaml does not contain a `version` key then error out
73
+ if val , ok := values [versionKey ]; ! ok {
74
+ return fmt .Errorf ("unable to find a version in %s" , chartYamlPath )
72
75
} else {
73
- filepath .WalkDir (chartDir , func (path string , d fs.DirEntry , err error ) error {
76
+ version , ok := val .(string )
77
+ if ! ok {
78
+ log .Printf ("unable to find a valid version in %s" , chartYamlPath )
79
+ }
80
+ if valuesFile != "" {
81
+ absPath , err := filepath .Abs (chartDir )
74
82
if err != nil {
75
83
return err
76
84
}
77
- if d .Name () == ChartYamlFileName || d .Name () == ChartYmlFileName {
78
- values , err := helm .Load (path )
79
- if err != nil {
80
- return err
81
- }
82
- chartYamls [path ] = values
85
+ absValuesFile := filepath .Join (absPath , valuesFile )
86
+ _ , err = os .Stat (absValuesFile )
87
+ if err != nil {
88
+ return fmt .Errorf ("unable to find values file: %s" , absValuesFile )
89
+ }
90
+
91
+ // Run `git diff --exit-code <file>` to check if the values file has any changes.
92
+ // An exit code of 0 indicates that there are no changes, thus we skip bumping the
93
+ // version of the chart.
94
+ cmd := execute.ExecTask {
95
+ Command : "git" ,
96
+ Args : []string {"diff" , "--exit-code" , valuesFile },
97
+ Cwd : absPath ,
98
+ }
99
+ res , err := cmd .Execute (context .Background ())
100
+ if err != nil {
101
+ return fmt .Errorf ("could not check updates to chart values: %s" , err )
83
102
}
84
- return nil
85
- })
86
- if len (chartYamls ) > 0 {
87
- fmt .Printf ("Found %d chart(s)\n " , len (chartYamls ))
88
- }
89
- }
90
103
91
- for file , contents := range chartYamls {
92
- // If the yaml does not contain a `version` key then skip it.
93
- if val , ok := contents [versionKey ]; ! ok {
94
- continue
95
- } else {
96
- version , ok := val .(string )
97
- if ! ok {
98
- log .Printf ("unable to find a valid version in %s" , file )
99
- continue
104
+ if res .ExitCode == 0 {
105
+ fmt .Printf ("no changes detected in %s; skipping version bump\n " , filepath .Join (chartDir , valuesFile ))
106
+ os .Exit (0 )
107
+ }
108
+ }
109
+ ver , err := semver .NewVersion (version )
110
+ if err != nil {
111
+ return fmt .Errorf ("%s" , err )
112
+ }
113
+ newVer := ver .IncMinor ()
114
+ fmt .Printf ("%s %s => %s\n " , chartYamlPath , ver .String (), newVer .String ())
115
+ if write {
116
+ if verbose {
117
+ log .Printf ("Bumping version" )
118
+ }
119
+ update := map [string ]string {
120
+ fmt .Sprintf ("%s: %s" , versionKey , ver .String ()): fmt .Sprintf ("%s: %s" , versionKey , newVer .String ()),
100
121
}
101
- ver , err := semver . NewVersion ( version )
122
+ rawChartYaml , err := helm . ReplaceValuesInHelmValuesFile ( update , chartYamlPath )
102
123
if err != nil {
103
- continue
124
+ return fmt . Errorf ( "unable to bump chart version in %s" , chartYamlPath )
104
125
}
105
- newVer := ver .IncMinor ()
106
- fmt .Printf ("%s %s => %s\n " , file , ver .String (), newVer .String ())
107
- if write {
108
- if verbose {
109
- log .Printf ("Bumping version" )
110
- }
111
- update := map [string ]string {
112
- fmt .Sprintf ("%s: %s" , versionKey , ver .String ()): fmt .Sprintf ("%s: %s" , versionKey , newVer .String ()),
113
- }
114
- rawChartYaml , err := helm .ReplaceValuesInHelmValuesFile (update , file )
115
- if err != nil {
116
- return fmt .Errorf ("unable to bump chart version in %s" , file )
117
- }
118
- if err = os .WriteFile (file , []byte (rawChartYaml ), 0600 ); err != nil {
119
- return fmt .Errorf ("unable to write updated yaml to %s" , file )
120
- }
126
+ if err = os .WriteFile (chartYamlPath , []byte (rawChartYaml ), 0600 ); err != nil {
127
+ return fmt .Errorf ("unable to write updated yaml to %s" , chartYamlPath )
121
128
}
122
129
}
123
130
}
0 commit comments