| #!/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" |