Files
tailscale/version_test.go
Brad Fitzpatrick c3736ae41a Dockerfile: use our own Go toolchain, not the golang Docker image
The golang:N-alpine Docker image lags behind Go minor releases by a
day or two. When we bump go.mod to a new minor version before the
image catches up, the required "Build Docker image" CI check fails
with "go.mod requires go >= 1.27.1 (running go 1.27.0;
GOTOOLCHAIN=local)" and blocks the toolchain bump from merging.

Instead, base the build stage on plain alpine and download the
Tailscale Go toolchain release for the revision in go.toolchain.rev,
matching how everything else in this repo is built.

Fixes #21072

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I1ccb77fa3c7a49532ea87dbdbf9e3340880ec94e
2026-09-01 15:47:33 -07:00

64 lines
1.5 KiB
Go

// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package tailscaleroot
import (
"os"
"os/exec"
"runtime"
"strings"
"testing"
"golang.org/x/mod/modfile"
)
// TestGoVersion tests that the Go version specified in go.mod matches ./tool/go version.
func TestGoVersion(t *testing.T) {
// We could special-case ./tool/go path for Windows, but really there is no
// need to run it there.
if runtime.GOOS == "windows" {
t.Skip("Skipping test on Windows")
}
goModVersion := mustGetGoModVersion(t)
goToolCmd := exec.Command("./tool/go", "version")
goToolOutput, err := goToolCmd.Output()
if err != nil {
t.Fatalf("Failed to get ./tool/go version: %v", err)
}
// Version info will approximately look like 'go version go1.24.4 linux/amd64'.
parts := strings.Fields(string(goToolOutput))
if len(parts) < 4 {
t.Fatalf("Unexpected ./tool/go version output format: %s", goToolOutput)
}
goToolVersion := strings.TrimPrefix(parts[2], "go")
if goModVersion != goToolVersion {
t.Errorf("Go version in go.mod (%q) does not match the version of ./tool/go (%q).\nEnsure that the go.mod refers to the same Go version as ./go.toolchain.rev.",
goModVersion, goToolVersion)
}
}
func mustGetGoModVersion(t *testing.T) string {
t.Helper()
goModBytes, err := os.ReadFile("go.mod")
if err != nil {
t.Fatal(err)
}
modFile, err := modfile.Parse("go.mod", goModBytes, nil)
if err != nil {
t.Fatal(err)
}
if modFile.Go == nil {
t.Fatal("no Go version found in go.mod")
}
return modFile.Go.Version
}