check / check (push) Successful in 12m47s
Linting and testing become the lint and test phases of the Dockerfile, and the build stage depends on both. Dockerfile.lint, CHECK_EPOCH and the tests that checked them are removed. Every docker build in script/ passes --no-cache, and script/cibuild runs script/bootstrap first. A host without Go gets the go.mod version from script/install-go in .tool/go, which bootstrap, the Makefile, fmt, fmt-check, precommit and release add to PATH; fmt-check skips .tool. The image takes its version from the VERSION build arg or git describe, dev without .git. This repo's own entries follow the canonical content in .gitignore and .editorconfig. The golangci-lint v2.14.0 findings are fixed. The rules in CLAUDE.md move into AGENTS.md. IsDevVersion counts "unknown". Model: opus-5-5
167 lines
5.7 KiB
Bash
Executable File
167 lines
5.7 KiB
Bash
Executable File
#!/bin/sh
|
|
# script/install-go: install the Go toolchain pinned by go.mod into the
|
|
# repo-local tool directory, verified against a committed sha256. Our
|
|
# own extension to scripts-to-rule-them-all. Idempotent: exits at once
|
|
# when the pinned toolchain is already installed.
|
|
#
|
|
# .gitea/workflows/release.yml calls this, and so does script/bootstrap
|
|
# when the host has no Go, as on the check runner. goreleaser is not a
|
|
# compiler: it shells out to `go` for the `before:` hook and for every
|
|
# one of the four cross-compiles, so the release runner needs a Go
|
|
# toolchain on PATH. The check runner compiles nothing on the host; it
|
|
# uses this Go only for bootstrap's `go mod download` and for gofmt in
|
|
# script/fmt-check. Per REPO_POLICIES.md a host Go is pinned by hash.
|
|
# actions/setup-go exposes no checksum input, so Go is installed the way
|
|
# script/install-goreleaser installs goreleaser: download the exact
|
|
# archive from go.dev and refuse it unless its sha256 matches the value
|
|
# committed below.
|
|
#
|
|
# The version is go.mod's `go` directive, the single source of truth for
|
|
# the toolchain. GO_VERSION below MUST equal it, and this script fails
|
|
# when they disagree -- so bumping Go is one reviewed change touching
|
|
# go.mod, the checksums here, and the Dockerfile's two golang digests
|
|
# together.
|
|
#
|
|
# Linux and macOS, each on amd64 and arm64: the four archives whose
|
|
# checksums are committed below.
|
|
set -eu
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
|
|
|
# Go 1.26.1, 2026-09-21. Checksums are the sha256 values go.dev publishes
|
|
# for each archive at https://go.dev/dl/ (also in its ?mode=json
|
|
# manifest).
|
|
GO_VERSION="1.26.1"
|
|
SHA256_LINUX_AMD64="031f088e5d955bab8657ede27ad4e3bc5b7c1ba281f05f245bcc304f327c987a"
|
|
SHA256_LINUX_ARM64="a290581cfe4fe28ddd737dde3095f3dbeb7f2e4065cab4eae44dfc53b760c2f7"
|
|
SHA256_DARWIN_AMD64="65773dab2f8cc4cd23d93ba6d0a805de150ca0b78378879292be0b903b8cdd08"
|
|
SHA256_DARWIN_ARM64="353df43a7811ce284c8938b5f3c7df40b7bfb6f56cb165b150bc40b5e2dd541f"
|
|
|
|
GOROOT_DIR="$ROOT/.tool/go"
|
|
GOCMD="$GOROOT_DIR/bin/go"
|
|
|
|
# The `go` directive in go.mod, e.g. "1.26.1" from `go 1.26.1`.
|
|
gomod_go_version() {
|
|
sed -n 's/^go \([0-9][0-9.]*\).*/\1/p' "$ROOT/go.mod" | head -n 1
|
|
}
|
|
|
|
# Print the version of the go at $1 as "1.26.1", or nothing if it is not
|
|
# usable. `go version` prints "go version go1.26.1 linux/amd64".
|
|
go_version() {
|
|
[ -x "$1" ] || return 0
|
|
"$1" version 2>/dev/null |
|
|
sed -n 's/^go version go\([0-9][0-9.]*\) .*/\1/p' |
|
|
head -n 1
|
|
}
|
|
|
|
verify_sha256() {
|
|
file="$1"
|
|
want="$2"
|
|
if command -v sha256sum >/dev/null 2>&1; then
|
|
got="$(sha256sum "$file" | cut -d' ' -f1)"
|
|
elif command -v shasum >/dev/null 2>&1; then
|
|
got="$(shasum -a 256 "$file" | cut -d' ' -f1)"
|
|
else
|
|
echo "install-go: no sha256sum or shasum available" >&2
|
|
return 1
|
|
fi
|
|
if [ "$got" != "$want" ]; then
|
|
echo "install-go: checksum mismatch for $file" >&2
|
|
echo " expected: $want" >&2
|
|
echo " actual: $got" >&2
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# On a Gitea/GitHub Actions runner, put the toolchain on PATH for the
|
|
# steps that follow by appending to the file named by $GITHUB_PATH. A
|
|
# no-op off CI, where the caller manages its own PATH.
|
|
export_ci_path() {
|
|
[ -n "${GITHUB_PATH:-}" ] || return 0
|
|
echo "$GOROOT_DIR/bin" >>"$GITHUB_PATH"
|
|
}
|
|
|
|
main() {
|
|
cd "$ROOT"
|
|
|
|
want="$(gomod_go_version)"
|
|
if [ "$want" != "$GO_VERSION" ]; then
|
|
echo "install-go: go.mod says go $want but this script pins" \
|
|
"$GO_VERSION." >&2
|
|
echo " Update GO_VERSION and the checksums in this script to" \
|
|
"match go.mod." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Already installed from a previous run? Then just fix PATH and stop.
|
|
if [ "$(go_version "$GOCMD")" = "$GO_VERSION" ]; then
|
|
echo "go $GO_VERSION already installed in .tool/go"
|
|
export_ci_path
|
|
return 0
|
|
fi
|
|
|
|
os="$(uname -s)"
|
|
arch="$(uname -m)"
|
|
case "$os" in
|
|
Linux) os="linux" ;;
|
|
Darwin) os="darwin" ;;
|
|
*)
|
|
echo "install-go: unsupported OS $os" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
case "$arch" in
|
|
x86_64 | amd64) arch="amd64" ;;
|
|
arm64 | aarch64) arch="arm64" ;;
|
|
*)
|
|
echo "install-go: unsupported architecture $arch" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
case "${os}-${arch}" in
|
|
linux-amd64) sum="$SHA256_LINUX_AMD64" ;;
|
|
linux-arm64) sum="$SHA256_LINUX_ARM64" ;;
|
|
darwin-amd64) sum="$SHA256_DARWIN_AMD64" ;;
|
|
darwin-arm64) sum="$SHA256_DARWIN_ARM64" ;;
|
|
esac
|
|
|
|
archive="go${GO_VERSION}.${os}-${arch}.tar.gz"
|
|
url="https://go.dev/dl/${archive}"
|
|
|
|
if ! command -v curl >/dev/null 2>&1; then
|
|
echo "install-go: curl is required" >&2
|
|
exit 1
|
|
fi
|
|
|
|
dl="$(mktemp -d)"
|
|
mkdir -p "$ROOT/.tool"
|
|
stage="$(mktemp -d "$ROOT/.tool/.go-install.XXXXXX")"
|
|
# shellcheck disable=SC2064 # expand the paths now, not at trap time
|
|
trap "rm -rf '$dl' '$stage'" EXIT INT TERM
|
|
|
|
echo "installing go $GO_VERSION for ${os}-${arch}"
|
|
curl -fsSL --retry 3 -o "$dl/$archive" "$url"
|
|
verify_sha256 "$dl/$archive" "$sum"
|
|
|
|
# The archive unpacks to a top-level `go/` directory. Extract it into
|
|
# a staging directory on the same filesystem as the destination, then
|
|
# rename it into place so a concurrent run never observes a
|
|
# half-written toolchain.
|
|
tar -xzf "$dl/$archive" -C "$stage"
|
|
rm -rf "$GOROOT_DIR"
|
|
mv "$stage/go" "$GOROOT_DIR"
|
|
|
|
installed="$(go_version "$GOCMD")"
|
|
if [ "$installed" != "$GO_VERSION" ]; then
|
|
echo "install-go: installed toolchain reports '$installed'," \
|
|
"expected '$GO_VERSION'" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "go $GO_VERSION installed to .tool/go"
|
|
export_ci_path
|
|
}
|
|
|
|
main "$@"
|