Improve version comparison to handle both X.Y.0 and X.Y.Z formats

- Compare major.minor versions instead of exact string match
- Preserve go directive if already at latest major.minor
- Handle cases where go.mod has full patch version (e.g., 1.25.6)
- Update PR body to use actual go directive from modified go.mod
- Add detailed comments explaining version handling logic

Co-authored-by: williammartin <1611510+williammartin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-01-29 19:13:09 +00:00 committed by William Martin
parent f5610036b9
commit 653ffc23ca

View file

@ -40,17 +40,19 @@ echo "Fetching latest stable Go version…"
LATEST_JSON=$(curl -fsSL https://go.dev/dl/?mode=json | jq -c '[.[] | select(.stable==true)][0]')
FULL_VERSION=$(jq -r '.version' <<< "$LATEST_JSON") # e.g. go1.23.4
TOOLCHAIN_VERSION="${FULL_VERSION#go}" # e.g. 1.23.4
# `go mod tidy` will always add `.0` if there is no minor version
# so let's just ensure .0 is suffixed to the go directive.
GO_DIRECTIVE_VERSION="$(cut -d. -f1-2 <<< "$TOOLCHAIN_VERSION").0"
echo " → go : $GO_DIRECTIVE_VERSION"
echo " → toolchain : $TOOLCHAIN_VERSION"
# The go directive can be either X.Y.0 (minor version) or X.Y.Z (patch version)
# We accept both forms as "latest" if they match the toolchain's major.minor
LATEST_MAJOR_MINOR="$(cut -d. -f1-2 <<< "$TOOLCHAIN_VERSION")"
echo " → latest toolchain : $TOOLCHAIN_VERSION"
# ---- Prepare Git branch ---------------------------------------------------
CURRENT_GO_DIRECTIVE=$(grep -E '^go ' "$GO_MOD" | cut -d ' ' -f2)
CURRENT_TOOLCHAIN_DIRECTIVE=$(grep -E '^toolchain ' "$GO_MOD" | cut -d ' ' -f2 || true)
CURRENT_MAJOR_MINOR="$(cut -d. -f1-2 <<< "$CURRENT_GO_DIRECTIVE")"
BRANCH="bump-go-$TOOLCHAIN_VERSION"
BRANCH_CREATED=0
@ -64,19 +66,21 @@ cleanup() {
trap cleanup EXIT
# Check if we're already up to date
# Note: toolchain directive may be missing when go directive == latest toolchain.
# Note: toolchain directive may be missing when go directive >= latest toolchain.
# This is expected behavior - `go mod tidy` removes the toolchain line when
# the minimum Go version matches the latest toolchain, as it's redundant.
if [[ "$CURRENT_GO_DIRECTIVE" = "$GO_DIRECTIVE_VERSION" ]]; then
# the minimum Go version matches or exceeds the latest toolchain, as it's redundant.
if [[ "$CURRENT_MAJOR_MINOR" = "$LATEST_MAJOR_MINOR" ]]; then
# Current go directive is at the same major.minor as latest
if [[ -z "$CURRENT_TOOLCHAIN_DIRECTIVE" ]]; then
# No toolchain directive present - this is expected when go version == latest
echo "Already on latest Go version: $CURRENT_GO_DIRECTIVE"
# No toolchain directive present - this is expected when go version >= latest
echo "Already on latest Go version: $CURRENT_GO_DIRECTIVE (latest toolchain: $TOOLCHAIN_VERSION)"
echo " → Note: No toolchain directive (expected when go version matches latest toolchain)"
exit 0
elif [[ "$CURRENT_TOOLCHAIN_DIRECTIVE" = "go$TOOLCHAIN_VERSION" ]]; then
echo "Already on latest Go version: $CURRENT_GO_DIRECTIVE (toolchain: $CURRENT_TOOLCHAIN_DIRECTIVE)"
exit 0
fi
# Current go directive is latest but toolchain is outdated - continue to update toolchain
fi
echo "Creating branch $BRANCH"
@ -84,16 +88,22 @@ git switch -c "$BRANCH" >/dev/null 2>&1
BRANCH_CREATED=1
# ---- Patch go.mod -----------------------------------------------------------
if [[ "$CURRENT_GO_DIRECTIVE" != "$GO_DIRECTIVE_VERSION" ]]; then
sed -Ei.bak "s/^go [0-9]+\.[0-9]+.*$/go $GO_DIRECTIVE_VERSION/" "$GO_MOD"
echo " • go directive $CURRENT_GO_DIRECTIVE$GO_DIRECTIVE_VERSION"
# Only update go directive if we're not already at the latest major.minor version
if [[ "$CURRENT_MAJOR_MINOR" != "$LATEST_MAJOR_MINOR" ]]; then
# Bump to the latest major.minor.0 (preserves the convention of X.Y.0 for go directive)
NEW_GO_DIRECTIVE="$LATEST_MAJOR_MINOR.0"
sed -Ei.bak "s/^go [0-9]+\.[0-9]+.*$/go $NEW_GO_DIRECTIVE/" "$GO_MOD"
echo " • go directive $CURRENT_GO_DIRECTIVE$NEW_GO_DIRECTIVE"
# After updating, the current go directive is now the new one for toolchain logic
CURRENT_GO_DIRECTIVE="$NEW_GO_DIRECTIVE"
fi
# Handle toolchain directive - may need to add, update, or skip
if [[ -z "$CURRENT_TOOLCHAIN_DIRECTIVE" ]]; then
# No toolchain directive exists
if [[ "$GO_DIRECTIVE_VERSION" = "$(cut -d. -f1-2 <<< "$TOOLCHAIN_VERSION").0" ]]; then
# go directive matches latest toolchain - toolchain line is redundant
CURRENT_MAJOR_MINOR="$(cut -d. -f1-2 <<< "$CURRENT_GO_DIRECTIVE")"
if [[ "$CURRENT_MAJOR_MINOR" = "$LATEST_MAJOR_MINOR" ]]; then
# go directive is at latest major.minor - toolchain line is redundant
echo " • toolchain directive not needed (go version matches latest toolchain)"
else
# go directive is older than latest toolchain - add toolchain directive after go line
@ -139,10 +149,13 @@ if [[ $APPLY -eq 0 ]]; then
fi
# ---- Push & PR --------------------------------------------------------------
# Get the actual go directive from the updated go.mod
FINAL_GO_DIRECTIVE=$(grep -E '^go ' "$GO_MOD" | cut -d ' ' -f2)
PR_BODY=$(cat <<EOF
This PR updates Go to the latest stable release.
* **go directive:** \`$GO_DIRECTIVE_VERSION\`
* **go directive:** \`$FINAL_GO_DIRECTIVE\`
* **toolchain:** \`$TOOLCHAIN_VERSION\`
EOF
)