Files
coder/scripts/release-action/version.go
T
Garrett Delfosse b95697a370 ci: rewrite release workflow to be fully GitHub Actions-driven (#25162)
Replace the local interactive release CLI and legacy shell scripts with
a non-interactive Go tool (`scripts/release-action/`) and a rewritten
`release.yaml` workflow. Release managers trigger releases from the
GitHub Actions UI by selecting a branch, picking a release type (`rc`,
`release`, or `create-release-branch`), and optionally providing a
commit SHA.

The Go tool has four subcommands: `calculate-version` (computes next
version from git state), `generate-notes` (release notes from commit log
and PR metadata), `publish` (creates GitHub release with checksums), and
the workflow handles tag creation, branch creation, building, and
downstream publishing.

`scripts/version.sh` fallback now uses `git describe` (nearest ancestor
tag) instead of global latest so dev builds on release branches show the
correct version series.
2026-06-04 14:38:48 -04:00

72 lines
1.5 KiB
Go

package main
import (
"fmt"
"regexp"
"strconv"
"strings"
"golang.org/x/xerrors"
)
// version represents a parsed semantic version with optional RC
// suffix. When rc < 0 the version is a final release. The original
// field preserves the string that was parsed (including the leading
// "v").
type version struct {
major int
minor int
patch int
rc int // -1 means not an RC
original string
}
// String returns the canonical version string (e.g. "v2.21.0" or
// "v2.21.0-rc.3").
func (v version) String() string {
if v.rc >= 0 {
return fmt.Sprintf("v%d.%d.%d-rc.%d", v.major, v.minor, v.patch, v.rc)
}
return fmt.Sprintf("v%d.%d.%d", v.major, v.minor, v.patch)
}
// IsRC returns true if this is a release candidate.
func (v version) IsRC() bool {
return v.rc >= 0
}
// semverRe matches vMAJOR.MINOR.PATCH with optional -rc.N suffix.
var semverRe = regexp.MustCompile(`^v?(\d+)\.(\d+)\.(\d+)(?:-rc\.(\d+))?$`)
// parseVersion parses a version string like "v2.21.0" or
// "v2.21.0-rc.3".
func parseVersion(s string) (version, error) {
m := semverRe.FindStringSubmatch(s)
if m == nil {
return version{}, xerrors.Errorf("invalid version %q", s)
}
major, _ := strconv.Atoi(m[1])
minor, _ := strconv.Atoi(m[2])
patch, _ := strconv.Atoi(m[3])
rc := -1
if m[4] != "" {
rc, _ = strconv.Atoi(m[4])
}
// Preserve the original string with leading "v".
orig := s
if !strings.HasPrefix(orig, "v") {
orig = "v" + orig
}
return version{
major: major,
minor: minor,
patch: patch,
rc: rc,
original: orig,
}, nil
}