From 0e560486db6177ec7a7de618948422a5b5113131 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 2 Jun 2025 19:48:05 +0200 Subject: [PATCH] build: use own script instead of svu We use a slightly different handling of features between prereleases. --- .github/workflows/release-syncthing.yaml | 8 +- go.mod | 1 + go.sum | 2 + script/next-version.go | 118 +++++++++++++++++++++++ 4 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 script/next-version.go diff --git a/.github/workflows/release-syncthing.yaml b/.github/workflows/release-syncthing.yaml index 2dfd30164..59d0fe63d 100644 --- a/.github/workflows/release-syncthing.yaml +++ b/.github/workflows/release-syncthing.yaml @@ -25,16 +25,12 @@ jobs: with: go-version: stable - - name: Get svu - run: | - go install github.com/caarlos0/svu@latest - - name: Determine version to release run: | if [[ "$GITHUB_REF_NAME" == "release" ]] ; then - next=$(svu next) + next=$(go run ./script/next-version.go) else - next=$(svu prerelease --pre-release rc) + next=$(go run ./script/next-version.go --pre) fi echo "NEXT=$next" >> $GITHUB_ENV echo "Next version is $next" diff --git a/go.mod b/go.mod index 4174ce913..ba312eb1d 100644 --- a/go.mod +++ b/go.mod @@ -59,6 +59,7 @@ require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/coreos/go-semver v0.3.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/ebitengine/purego v0.8.3 // indirect diff --git a/go.sum b/go.sum index 28d7755d3..a552461c1 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,8 @@ github.com/chmduquesne/rollinghash v4.0.0+incompatible/go.mod h1:Uc2I36RRfTAf7Dg github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= +github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/d4l3k/messagediff v1.2.1 h1:ZcAIMYsUg0EAp9X+tt8/enBE/Q8Yd5kzPynLyKptt9U= diff --git a/script/next-version.go b/script/next-version.go new file mode 100644 index 000000000..f3052e360 --- /dev/null +++ b/script/next-version.go @@ -0,0 +1,118 @@ +//go:build ignore +// +build ignore + +package main + +import ( + "flag" + "fmt" + "os" + "os/exec" + "strconv" + "strings" + + "github.com/coreos/go-semver/semver" +) + +const suffix = "rc" + +func main() { + pre := flag.Bool("pre", false, "Create a prerelease") + flag.Parse() + + // Get the latest "v1.22.3" or "v1.22.3-rc.1" style tag. + latestTag, err := cmd("git", "describe", "--abbrev=0", "--match", "v[0-9].*") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + latest, err := semver.NewVersion(latestTag[1:]) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Get the latest "v1.22.3" style tag, excludeing prereleases. + latestStableTag, err := cmd("git", "describe", "--abbrev=0", "--match", "v[0-9].*", "--exclude", "*-*") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + latestStable, err := semver.NewVersion(latestStableTag[1:]) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Get the commit logs since the latest stable tag. + logsSinceLatest, err := cmd("git", "log", "--pretty=format:%s", latestStableTag+"..HEAD") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Check if the next version should be a feature or a patch release + nextIsFeature := false + for _, line := range strings.Split(logsSinceLatest, "\n") { + if strings.HasPrefix(line, "feat") { + nextIsFeature = true + break + } + } + next := *latestStable + if nextIsFeature { + next.BumpMinor() + } else { + next.BumpPatch() + } + + if latest.PreRelease != "" { + if !*pre { + // We want a stable release. Simply remove the prerelease + // suffix. + latest.PreRelease = "" + fmt.Println(latest) + return + } + + // We want the next prerelease. We are already on a prerelease. If + // it's the correct prerelease compared to the logs we just got, we + // should just bump the prerelease counter. + if next.LessThan(*latest) { + parts := latest.PreRelease.Slice() + for i, p := range parts { + if v, err := strconv.Atoi(p); err == nil { + parts[i] = strconv.Itoa(v + 1) + latest.PreRelease = semver.PreRelease(strings.Join(parts, ".")) + fmt.Println(latest) + return + } + } + } + + // Otherwise we generate a new rc.1 for the correct next version. + next.PreRelease = suffix + ".1" + fmt.Println(next) + return + } + + if nextIsFeature { + latest.BumpMinor() + } else { + latest.BumpPatch() + } + if *pre { + latest.PreRelease = suffix + ".1" + } + + fmt.Println(latest) +} + +func cmd(name string, args ...string) (string, error) { + cmd := exec.Command(name, args...) + bs, err := cmd.CombinedOutput() + if err != nil { + return "", err + } + return strings.TrimSpace(string(bs)), nil +}