Skip to content

Commit ee83189

Browse files
committed
TUN-11024: Build with the exact Go version from go.mod
The macOS binaries in the latest VULN-181166 patch release were built with an older Go than the other platforms. install-go.sh ran `brew install go@X.Y.Z`, which is not a Homebrew formula, and the script had no `set -e`, so the install failed silently and the build used whatever Go the runner already had. GOTOOLCHAIN=auto, the default, only upgrades an older local Go to the go.mod version and never downgrades a newer one. The Makefile now exports GOTOOLCHAIN=go<version> from the go directive in go.mod, so every build that goes through make (Linux, macOS, Windows, packaging and Docker images) uses exactly that version, downloading it when the installed Go differs. A go directive without a patch version fails the build, because go1.X is not a valid toolchain name. Remove install-go.sh and MAC_GO_VERSION, since the macOS runner now only needs some Go installed. Key the macOS cache on go.mod instead of GO_VERSION, and drop the job's silent exit when the build script is not executable. Document the full major.minor.patch requirement and the Go upgrade checklist in README and AGENTS.md. Closes TUN-11024
1 parent fa04bbf commit ee83189

6 files changed

Lines changed: 38 additions & 22 deletions

File tree

‎.ci/mac.gitlab-ci.yml‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ include:
1010
GOPROXY: "https://proxy.golang.org,direct"
1111
cache:
1212
key:
13-
prefix: "$CI_COMMIT_REF_PROTECTED-$GO_VERSION-$TARGET_ARCH"
13+
prefix: "$CI_COMMIT_REF_PROTECTED-$TARGET_ARCH"
1414
files:
15+
- go.mod
1516
- go.sum
1617
paths:
1718
- .cache/go/
@@ -34,14 +35,10 @@ macos-build-cloudflared: &mac-build
3435
paths:
3536
- artifacts/*
3637
script:
38+
- set -euo pipefail
3739
- ARCH=$(uname -m)
3840
- echo ARCH=$ARCH - TARGET_ARCH=$TARGET_ARCH
39-
- ./.ci/scripts/mac/install-go.sh "$MAC_GO_VERSION"
40-
- BUILD_SCRIPT=.ci/scripts/mac/build.sh
41-
- if [[ ! -x ${BUILD_SCRIPT} ]] ; then exit ; fi
42-
- set -euo pipefail
43-
- echo "Executing ${BUILD_SCRIPT}"
44-
- exec ${BUILD_SCRIPT}
41+
- ./.ci/scripts/mac/build.sh
4542

4643
###############################################
4744
### Build and Sign Cloudflared Mac Binaries ###

‎.ci/scripts/mac/install-go.sh‎

Lines changed: 0 additions & 14 deletions
This file was deleted.

‎.gitlab-ci.yml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
variables:
22
GO_VERSION: "1.27.3"
3-
MAC_GO_VERSION: "go@$GO_VERSION"
43
WIN_GO_VERSION: "go$GO_VERSION"
54
GIT_DEPTH: "0"
65
# Athens caches public modules for faster CI downloads; direct preserves public fallback.

‎AGENTS.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,13 @@ notice, do not proceed without explicit confirmation.
289289
## Dependencies Management
290290

291291
- Use Go modules (`go.mod`) exclusively
292+
- The `go` directive in `go.mod` must include the patch version (`major.minor.patch`).
293+
It is the exact Go version for builds and tests: the Makefile exports
294+
`GOTOOLCHAIN=go<version>` from it unless Go is configured with `GOTOOLCHAIN=local`.
295+
Cloudflare's internal Go package sets that so its patches are never replaced by an
296+
upstream toolchain (RFC-028); never override it. Do not add a `toolchain` directive.
297+
When bumping Go, align all CI, Docker image, and documentation version references,
298+
including the Linux CI builder image and digest; see README's "Updating Go" section.
292299
- Resolve dependencies from the locked module graph with `go mod download`; do not vendor dependencies.
293300
- Builds, tests, vet, and lint use `-mod=readonly`; `go.mod` and `go.sum` must not drift in CI.
294301
- Linux CI uses Athens before public and direct module sources; macOS and Windows use the public proxy directly.

‎Makefile‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ ifdef CONTAINER_BUILD
4040
VERSION_FLAGS := $(VERSION_FLAGS) -X "github.com/cloudflare/cloudflared/metrics.Runtime=virtual"
4141
endif
4242

43+
# Build and test with exactly the Go version in go.mod. The default GOTOOLCHAIN=auto
44+
# only upgrades an older local Go and never downgrades a newer one.
45+
# Leave GOTOOLCHAIN=local alone if an environment sets it in go.env.
46+
ifneq ($(shell go env GOTOOLCHAIN),local)
47+
GO_MOD_VERSION := $(shell go list -m -f "{{.GoVersion}}")
48+
ifneq ($(GO_MOD_VERSION),)
49+
export GOTOOLCHAIN := go$(GO_MOD_VERSION)
50+
endif
51+
endif
52+
4353
LINK_FLAGS :=
4454
ifeq ($(FIPS), true)
4555
export GOFIPS140 := latest

‎README.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,23 @@ For example, as of January 2023 Cloudflare will support cloudflared version 2023
7575
- [golangci-lint](https://github.com/golangci/golangci-lint)
7676
- [gomocks](https://pkg.go.dev/go.uber.org/mock)
7777

78+
### Updating Go
79+
80+
The `go` directive in `go.mod` must specify the full `major.minor.patch` version
81+
(for example, `go 1.27.3`). Do not omit the patch version, including `.0` releases.
82+
This is the exact Go version used to build and test cloudflared: the Makefile exports
83+
`GOTOOLCHAIN=go<version>` from it, so `make` downloads that toolchain whenever the
84+
installed Go is older or newer. Tools that `make` runs with `go run pkg@version` also
85+
use this toolchain. A `toolchain` directive in `go.mod` is ignored; do not add one.
86+
To use the installed Go instead, run `make <target> GOTOOLCHAIN=local`.
87+
88+
When upgrading Go, update the `go` directive and all corresponding version references
89+
in `.gitlab-ci.yml`, `.ci/image/Dockerfile`, `.github/workflows/check.yaml`, and the
90+
Dockerfiles. Update the Linux CI builder image and digest in `.ci/linux.gitlab-ci.yml`
91+
to match; its `golangVersion` selects the major/minor image family. On macOS and
92+
Windows a mismatch only costs a toolchain download. Builds that use `GOTOOLCHAIN=local`
93+
fail if their Go is older than `go.mod` and use their own Go if it is newer.
94+
7895
### Build
7996
To build cloudflared locally run `make cloudflared`
8097

0 commit comments

Comments
 (0)