blob: b9a2829f9138c735ae746995fc070863967645ab [file]
#!/usr/bin/env bash
# Copyright 2025 The etcd Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This script verifies that the value of the toolchain directive in the
# go.mod files always match that of the .go-version file to ensure that
# we accidentally don't test and release with differing versions of Go.
set -euo pipefail
source ./scripts/test_lib.sh
target_go_version="${target_go_version:-"$(cat "${ETCD_ROOT_DIR}/.go-version")"}"
log_info "expected go toolchain directive: go${target_go_version}"
log_info
toolchain_out_of_sync="false"
go_line_violation="false"
# verify_go_versions takes a go.mod filepath as an argument
# and checks if:
# (1) go directive <= version in .go-version
# (2) toolchain directive == version in .go-version
function verify_go_versions() {
# shellcheck disable=SC2086
toolchain_version="$(go mod edit -json $1 | jq -r .Toolchain)"
# shellcheck disable=SC2086
go_line_version="$(go mod edit -json $1 | jq -r .Go)"
if [[ "go${target_go_version}" != "${toolchain_version}" ]]; then
log_error "go toolchain directive out of sync for $1, got: ${toolchain_version}"
toolchain_out_of_sync="true"
fi
if ! printf '%s\n' "${go_line_version}" "${target_go_version}" | sort --check=silent --version-sort; then
log_error "go directive in $1 is greater than maximum allowed: go${target_go_version}"
go_line_violation="true"
fi
}
# Workaround to get go.work's toolchain, as go work edit -json doesn't return
# the toolchain as of Go 1.24. When this is fixed, we can replace these two
# checks with verify_go_versions go.work
toolchain_version="$(grep toolchain go.work | cut -d' ' -f2)"
if [[ "go${target_go_version}" != "${toolchain_version}" ]]; then
log_error "go toolchain directive out of sync for go.work, got: ${toolchain_version}"
toolchain_out_of_sync="true"
fi
go_line_version="$(go work edit -json | jq -r .Go)"
if ! printf '%s\n' "${go_line_version}" "${target_go_version}" | sort --check=silent --version-sort; then
log_error "go directive in go.work is greater than maximum allowed: go${target_go_version}"
go_line_violation="true"
fi
while read -r mod; do
verify_go_versions "${mod}";
done < <(find . -name 'go.mod')
if [[ "${toolchain_out_of_sync}" == "true" ]]; then
log_error
log_error "Please run make sync-toolchain-directive or update .go-version to rectify this error"
fi
if [[ "${go_line_violation}" == "true" ]]; then
log_error
log_error "Please update .go-version to rectify this error, any go directive should be <= .go-version"
fi
if [[ "${go_line_violation}" == "true" ]] || [[ "${toolchain_out_of_sync}" == "true" ]]; then
exit 1
fi
log_success "SUCCESS: Go toolchain directive in sync"