@@ -11,12 +11,19 @@ import (
1111 "errors"
1212 "fmt"
1313 "io"
14+ "math"
1415 "os/exec"
1516 "regexp"
17+ "sort"
18+ "strconv"
19+ "strings"
20+
21+ "github.com/elastic/elastic-agent/pkg/version"
1622)
1723
1824var (
1925 ErrNotReleaseBranch = errors .New ("this is not a release branch" )
26+ // glob is not powerful enough to match exactly what we expect, so we have to use the regular expression too
2027 releaseBranchRegexp = regexp .MustCompile (`.*(\d+\.(\d+|x))$` )
2128)
2229
@@ -26,17 +33,44 @@ type outputReader func(io.Reader) error
2633// current repository ordered descending by creation date.
2734// e.g. 8.13, 8.12, etc.
2835func GetReleaseBranches (ctx context.Context ) ([]string , error ) {
29- c := exec .CommandContext (ctx , "git" , "branch" , "-r" , "--list " , "*/ [0-9]*.* [0-9x]" , "--sort=-creatordate " )
36+ c := exec .CommandContext (ctx , "git" , "for-each-ref " , "refs/remotes/origin/ [0-9]*.[0-9x]* " , "--format=%(refname:short) " )
3037
3138 branchList := []string {}
3239 err := runCommand (c , releaseBranchReader (& branchList ))
3340 if err != nil {
3441 return nil , err
3542 }
3643
44+ sort .Slice (branchList , less (branchList ))
45+
3746 return branchList , nil
3847}
3948
49+ // we use this to emulate the maximum possible version value aliased by `.x`
50+ var maxIntString = strconv .Itoa (math .MaxInt )
51+
52+ // less makes sure we have our release branches in the right order
53+ func less (branches []string ) func (i , j int ) bool {
54+ return func (i , j int ) bool {
55+ // we complete the versions, so we can parse semver and compare
56+ var (
57+ v1 = strings .ReplaceAll (branches [i ], "x" , maxIntString ) + ".0"
58+ v2 = strings .ReplaceAll (branches [j ], "x" , maxIntString ) + ".0"
59+ )
60+
61+ parsed1 , err1 := version .ParseVersion (v1 )
62+ parsed2 , err2 := version .ParseVersion (v2 )
63+ if err1 != nil {
64+ return false
65+ }
66+ if err2 != nil {
67+ return true
68+ }
69+ // descending order
70+ return ! parsed1 .Less (* parsed2 )
71+ }
72+ }
73+
4074// GetCurrentReleaseBranch returns the current branch of the repository
4175func GetCurrentReleaseBranch (ctx context.Context ) (string , error ) {
4276 c := exec .CommandContext (ctx , "git" , "symbolic-ref" , "--short" , "HEAD" )
@@ -71,7 +105,7 @@ func releaseBranchReader(out *[]string) outputReader {
71105 var seen = map [string ]struct {}{}
72106 scanner := bufio .NewScanner (r )
73107 for scanner .Scan () {
74- branch := scanner .Text ()
108+ branch := strings . TrimPrefix ( scanner .Text (), "origin/" )
75109 branch , err := extractReleaseBranch (branch )
76110 if err != nil {
77111 continue
0 commit comments