next-version.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //go:build ignore
  2. // +build ignore
  3. package main
  4. import (
  5. "flag"
  6. "fmt"
  7. "os"
  8. "os/exec"
  9. "strconv"
  10. "strings"
  11. "github.com/coreos/go-semver/semver"
  12. )
  13. const suffix = "rc"
  14. func main() {
  15. pre := flag.Bool("pre", false, "Create a prerelease")
  16. flag.Parse()
  17. // Get the latest "v1.22.3" or "v1.22.3-rc.1" style tag.
  18. latestTag, err := cmd("git", "describe", "--abbrev=0", "--match", "v[0-9].*")
  19. if err != nil {
  20. fmt.Println(err)
  21. os.Exit(1)
  22. }
  23. latest, err := semver.NewVersion(latestTag[1:])
  24. if err != nil {
  25. fmt.Println(err)
  26. os.Exit(1)
  27. }
  28. // Get the latest "v1.22.3" style tag, excludeing prereleases.
  29. latestStableTag, err := cmd("git", "describe", "--abbrev=0", "--match", "v[0-9].*", "--exclude", "*-*")
  30. if err != nil {
  31. fmt.Println(err)
  32. os.Exit(1)
  33. }
  34. latestStable, err := semver.NewVersion(latestStableTag[1:])
  35. if err != nil {
  36. fmt.Println(err)
  37. os.Exit(1)
  38. }
  39. // Get the commit logs since the latest stable tag.
  40. logsSinceLatest, err := cmd("git", "log", "--pretty=format:%s", latestStableTag+"..HEAD")
  41. if err != nil {
  42. fmt.Println(err)
  43. os.Exit(1)
  44. }
  45. // Check if the next version should be a feature or a patch release
  46. nextIsFeature := false
  47. for _, line := range strings.Split(logsSinceLatest, "\n") {
  48. if strings.HasPrefix(line, "feat") {
  49. nextIsFeature = true
  50. break
  51. }
  52. }
  53. next := *latestStable
  54. if nextIsFeature {
  55. next.BumpMinor()
  56. } else {
  57. next.BumpPatch()
  58. }
  59. if latest.PreRelease != "" {
  60. if !*pre {
  61. // We want a stable release. Simply remove the prerelease
  62. // suffix.
  63. latest.PreRelease = ""
  64. fmt.Println(latest)
  65. return
  66. }
  67. // We want the next prerelease. We are already on a prerelease. If
  68. // it's the correct prerelease compared to the logs we just got, we
  69. // should just bump the prerelease counter.
  70. if next.LessThan(*latest) {
  71. parts := latest.PreRelease.Slice()
  72. for i, p := range parts {
  73. if v, err := strconv.Atoi(p); err == nil {
  74. parts[i] = strconv.Itoa(v + 1)
  75. latest.PreRelease = semver.PreRelease(strings.Join(parts, "."))
  76. fmt.Println(latest)
  77. return
  78. }
  79. }
  80. }
  81. // Otherwise we generate a new rc.1 for the correct next version.
  82. next.PreRelease = suffix + ".1"
  83. fmt.Println(next)
  84. return
  85. }
  86. if nextIsFeature {
  87. latest.BumpMinor()
  88. } else {
  89. latest.BumpPatch()
  90. }
  91. if *pre {
  92. latest.PreRelease = suffix + ".1"
  93. }
  94. fmt.Println(latest)
  95. }
  96. func cmd(name string, args ...string) (string, error) {
  97. cmd := exec.Command(name, args...)
  98. bs, err := cmd.CombinedOutput()
  99. if err != nil {
  100. return "", err
  101. }
  102. return strings.TrimSpace(string(bs)), nil
  103. }