1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ // package main implements prepare_rc script.
16+ //
17+ // Run this script to prepare the prometheus-engine files for the next release;
18+ // without regenerating them (!).
19+ //
20+ // Example use:
21+ //
22+ // go run ./... \
23+ // -tag=v0.15.4-rc.0 \
24+ // -dir=../../../prometheus-engine
1525package main
1626
1727import (
1828 "errors"
29+ "flag"
1930 "fmt"
2031 "os"
2132 "path/filepath"
@@ -24,8 +35,16 @@ import (
2435 "strings"
2536)
2637
27- const VersionFile = "pkg/export/export.go"
28- const ValuesFile = "charts/values.global.yaml"
38+ const (
39+ versionFile = "pkg/export/export.go"
40+ valuesFile = "charts/values.global.yaml"
41+ )
42+
43+ var (
44+ dir = flag .String ("dir" , "." , "The path with prometheus-engine repo/" )
45+ tag = flag .String ("tag" , "" , "Tag to release. Empty means the tag will be a next RC number from the last git tag in a given -branch." )
46+ branch = flag .String ("branch" , "" , "Branch to use for auto-detecting tag to release. Must be matching ^release/(\\ d+)\\ .(\\ d+)$. Can't be used with -tag." )
47+ )
2948
3049type Branch struct {
3150 major int
@@ -54,95 +73,24 @@ func getBranch(branch string) (*Branch, error) {
5473 }, nil
5574}
5675
57- type ReleaseCandidate struct {
58- branch * Branch
59- patch int
60- rc int
61- }
62-
63- func (b * Branch ) lastTag () (string , error ) {
76+ func (b * Branch ) currentTag () (Tag , error ) {
6477 tagRegex := fmt .Sprintf ("v%d.%d.*" , b .major , b .minor )
6578 tags , err := Cmd ("git" , "tag" , "--list" , tagRegex , "--sort=-v:refname" ).Run ()
66- return strings .SplitN (tags , "\n " , 2 )[0 ], err
67- }
68-
69- func (b * Branch ) lastReleaseCandidate () (* ReleaseCandidate , error ) {
70- tag , err := b .lastTag ()
71- if err != nil {
72- return nil , err
73- }
74- if tag == "" {
75- return nil , nil
76- }
77- re := regexp .MustCompile (`^v\d+.\d+.(\d+)-rc.(\d+)$` )
78- matches := re .FindStringSubmatch (tag )
79- if matches == nil {
80- return nil , fmt .Errorf ("malformatted tag name %q" , tag )
81- }
82- patchRaw , rcRaw := matches [1 ], matches [2 ]
83- patch , err := strconv .Atoi (patchRaw )
8479 if err != nil {
85- return nil , fmt . Errorf ( "malformatted tag name %q" , tag )
80+ return Tag {}, err
8681 }
87- rc , err := strconv .Atoi (rcRaw )
88- if err != nil {
89- return nil , fmt .Errorf ("malformatted tag name %q" , tag )
90- }
91- return & ReleaseCandidate {
92- branch : b ,
93- patch : patch ,
94- rc : rc ,
95- }, nil
82+ return NewTag (strings .SplitN (tags , "\n " , 2 )[0 ])
9683}
9784
98- func (b * Branch ) nextReleaseCandidate () (* ReleaseCandidate , error ) {
99- last , err := b .lastReleaseCandidate ()
100- if err != nil {
101- return nil , err
102- }
103- if last == nil {
104- return & ReleaseCandidate {
105- branch : b ,
106- patch : 0 ,
107- rc : 0 ,
108- }, nil
109- }
110- hasRelease , err := last .hasRelease ()
111- if err != nil {
112- return nil , err
113- }
114- if hasRelease {
115- return & ReleaseCandidate {
116- branch : last .branch ,
117- patch : last .patch + 1 ,
118- rc : 0 ,
119- }, nil
120- }
121- return & ReleaseCandidate {
122- branch : last .branch ,
123- patch : last .patch ,
124- rc : last .rc + 1 ,
125- }, nil
126- }
127-
128- func (rc * ReleaseCandidate ) version () string {
129- return fmt .Sprintf ("v%d.%d.%d" , rc .branch .major , rc .branch .minor , rc .patch )
130- }
131-
132- func (rc * ReleaseCandidate ) hasRelease () (bool , error ) {
133- out , err := Cmd ("git" , "tag" , "--list" , rc .version ()).Run ()
134- return out != "" , err
135- }
136-
137- func (rc * ReleaseCandidate ) updateVersionFile (repoPath string ) error {
138- path := filepath .Join (repoPath , VersionFile )
85+ func updateVersionFile (repoPath string , tag Tag ) error {
86+ path := filepath .Join (repoPath , versionFile )
13987 contentBytes , err := os .ReadFile (path )
14088 if err != nil {
14189 return fmt .Errorf ("failed to read file %s: %w" , path , err )
14290 }
14391 content := string (contentBytes )
14492 re := regexp .MustCompile (`(mainModuleVersion\s*=\s*)".*"` )
145- replacement := fmt .Sprintf (`${1}"%s"` , rc . version ())
93+ replacement := fmt .Sprintf (`${1}"%s"` , tag . String ())
14694 newContent := re .ReplaceAllString (content , replacement )
14795
14896 err = os .WriteFile (path , []byte (newContent ), 0664 )
@@ -152,18 +100,20 @@ func (rc *ReleaseCandidate) updateVersionFile(repoPath string) error {
152100 return nil
153101}
154102
155- func ( rc * ReleaseCandidate ) updateValuesFile (repoPath string ) error {
156- path := filepath .Join (repoPath , ValuesFile )
157- _ , err := Cmd ("go" , "tool" , "yq" , "e" ,
158- fmt .Sprintf (`.version = "%d.%d.%d"` , rc . branch . major , rc . branch . minor , rc . patch ),
103+ func updateValuesFile (repoPath string , tag Tag ) error {
104+ path := filepath .Join (repoPath , valuesFile )
105+ if _ , err := Cmd ("yq" , "e" ,
106+ fmt .Sprintf (`.version = "%d.%d.%d"` , tag . Major (), tag . Minor (), tag . Patch () ),
159107 "-i" , path ,
160- ).Run ()
161- if err != nil {
108+ ).Run (); err != nil {
162109 return err
163110 }
164111 for _ , image := range []string {"configReloader" , "operator" , "ruleEvaluator" , "datasourceSyncer" } {
165- _ , err := Cmd ("go" , "tool" , "yq" , "e" ,
166- fmt .Sprintf (`.images.%s.tag = "%s-gke.%d"` , image , rc .version (), rc .rc ),
112+ _ , err := Cmd ("yq" , "e" ,
113+ // This assumes RC number is always same as the GKE number -- this is not always
114+ // correct e.g. when we retry releases on Louhi side. It's the best guess though
115+ // and we can update manifests later on.
116+ fmt .Sprintf (`.images.%s.tag = "v%d.%d.%d-gke.%d"` , image , tag .Major (), tag .Minor (), tag .Patch (), tag .RC ()),
167117 "-i" , path ,
168118 ).Run ()
169119 if err != nil {
@@ -174,46 +124,73 @@ func (rc *ReleaseCandidate) updateValuesFile(repoPath string) error {
174124}
175125
176126func main () {
177- if len (os .Args ) < 3 {
178- fmt .Printf ("::error::Usage: %s <branch-name> <repo-path>\n " , os .Args [0 ])
179- fmt .Println ("::error::Error: Missing arguments" )
127+ flag .Parse ()
128+
129+ if * dir == "" {
130+ fmt .Println ("::error::Error: -dir has to be specified." )
131+ flag .Usage ()
180132 os .Exit (1 )
181133 }
182- if _ , err := Cmd ("git" , "fetch" , "--tags" , "-f" ).Run (); err != nil {
183- fmt .Printf ("::error::Failed to fetch tags: %v\n " , err )
184- }
185- branch , err := getBranch (os .Args [1 ])
186- if err != nil {
187- fmt .Printf ("::error::Failed to parse branch: %v\n " , err )
134+
135+ if * tag != "" && * branch != "" {
136+ fmt .Println ("::error::Error: -tag and -branch can't be specified in the same time." )
137+ flag .Usage ()
138+ os .Exit (1 )
188139 }
189- nextRc , err := branch .nextReleaseCandidate ()
190- if err != nil {
191- fmt .Printf ("::error::Failed to get next release candidate: %v\n " , err )
140+
141+ var releaseTag Tag
142+ if * tag != "" {
143+ var err error
144+ releaseTag , err = NewTag (* tag )
145+ if err != nil {
146+ fmt .Printf ("::error::Failed to parse the -tag: %v\n " , err )
147+ os .Exit (1 )
148+ }
149+ } else if * branch != "" {
150+ // TODO(bwplotka): Why we ask for repo directory if we this command require this
151+ // script to be in the current directory? Fix it.
152+ if _ , err := Cmd ("git" , "fetch" , "--tags" , "-f" ).Run (); err != nil {
153+ fmt .Printf ("::error::Failed to fetch tags: %v\n " , err )
154+ }
155+ branch , err := getBranch (os .Args [1 ])
156+ if err != nil {
157+ fmt .Printf ("::error::Failed to parse branch: %v\n " , err )
158+ }
159+ ct , err := branch .currentTag ()
160+ if err != nil {
161+ fmt .Printf ("::error::Failed to get next release candidate: %v\n " , err )
162+ }
163+ releaseTag = ct .NextRC ()
164+ } else {
165+ fmt .Println ("::error::Error: Either -tag or -branch has to be specified." )
166+ flag .Usage ()
167+ os .Exit (1 )
192168 }
193169
194- repoPath := os . Args [ 2 ]
195- if err := nextRc . updateVersionFile (repoPath ); err != nil {
170+ fmt . Println ( "Updating files to" , tag )
171+ if err := updateVersionFile (* dir , releaseTag ); err != nil {
196172 fmt .Printf ("::error::Failed to update version file: %v\n " , err )
173+ os .Exit (1 )
197174 }
198- if err := nextRc . updateValuesFile (repoPath ); err != nil {
175+ if err := updateValuesFile (* dir , releaseTag ); err != nil {
199176 fmt .Printf ("::error::Failed to update value file: %v\n " , err )
200- }
201- // For GH actions
202- outputPath := os .Getenv ("GITHUB_OUTPUT" )
203- if outputPath == "" {
204- fmt .Println ("::error::GITHUB_OUTPUT environment variable not set." )
205177 os .Exit (1 )
206178 }
207- outputFile , err := os .OpenFile (outputPath , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0644 )
208- if err != nil {
209- fmt .Printf ("::error::Failed to open GITHUB_OUTPUT: %v\n " , err )
210- return
211- }
212- defer outputFile .Close ()
213179
214- s := fmt .Sprintf ("full_rc_version=%s-rc.%d\n " , nextRc .version (), nextRc .rc )
215- _ , err = outputFile .WriteString (s )
216- if err != nil {
217- fmt .Printf ("::error::Failed to write to GITHUB_OUTPUT: %v\n " , err )
180+ // For GH actions, optionally.
181+ outputPath := os .Getenv ("GITHUB_OUTPUT" )
182+ if outputPath != "" {
183+ outputFile , err := os .OpenFile (outputPath , os .O_APPEND | os .O_CREATE | os .O_WRONLY , 0644 )
184+ if err != nil {
185+ fmt .Printf ("::error::Failed to open GITHUB_OUTPUT: %v\n " , err )
186+ return
187+ }
188+ defer outputFile .Close ()
189+
190+ s := fmt .Sprintf ("full_rc_version=%v\n " , releaseTag .String ())
191+ _ , err = outputFile .WriteString (s )
192+ if err != nil {
193+ fmt .Printf ("::error::Failed to write to GITHUB_OUTPUT: %v\n " , err )
194+ }
218195 }
219196}
0 commit comments