Use pre-built binaries in 05-custom.sh

Replaces go install for 11 tools with direct binary/tarball downloads
from GitHub releases. Build time drops from 2+ hours to ~10 minutes
and arm64 QEMU segfaults are eliminated (no Go compilation for goreleaser).
- rootfs/root/docker/setup/05-custom.sh: add _gh_latest/_install_tar/_install_bin
helpers; download goreleaser, golangci-lint, staticcheck, gofumpt,
gotestsum, ko, air, buf, goose, gopls, govulncheck from release artifacts;
keep go install only for goimports, stringer, dlv, gops, benchstat,
wire, mockgen, protoc-gen-go, protoc-gen-go-grpc; remove -p=1 arm64
workaround (no longer needed)

rootfs/root/docker/setup/05-custom.sh
This commit is contained in:
2026-06-01 00:12:38 -04:00
parent d3fb3ebc31
commit 08d96b6d5b
+137 -53
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# shellcheck shell=bash
# - - - - - - - - - - - - - - - - - - - - - - - - -
##@Version : 202605292220-git
##@Version : 202606010000-git
# @@Author : CasjaysDev
# @@Contact : CasjaysDev <docker-admin@casjaysdev.pro>
# @@License : MIT
@@ -9,7 +9,7 @@
# @@Created : Fri May 29 10:20:10 PM EDT 2026
# @@File : 05-custom.sh
# @@Description : Install Go latest and Go tooling
# @@Changelog : Add Go install and toolchain setup
# @@Changelog : Use pre-built binaries where available; go install for the rest
# @@TODO : N/A
# @@Other : N/A
# @@Resource : https://go.dev/dl/
@@ -36,12 +36,48 @@ GOBIN_DIR="/usr/local/bin"
GOCACHE_BUILD="/tmp/go-build-cache"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Predefined actions
# Helpers
# Return the latest tag from a GitHub release API
_gh_latest() {
local repo="$1"
local filter="${2:-.tag_name}"
curl -fsSL "https://api.github.com/repos/${repo}/releases/latest" | jq -r "${filter}"
}
# Download a tar.gz release asset, extract a single binary, install to GOBIN_DIR
# Usage: _install_tar <url> <binary-name-in-archive> [<subdir-prefix>]
_install_tar() {
local url="$1"
local bin="$2"
local prefix="${3:-}"
local tmp
tmp="$(mktemp -d)"
curl -fsSL "$url" | tar -C "$tmp" -xz
if [ -n "$prefix" ]; then
install -m 0755 "${tmp}/${prefix}/${bin}" "${GOBIN_DIR}/${bin}"
else
# Binary may be in a subdirectory; find it
local found
found="$(find "$tmp" -name "$bin" -type f | head -1)"
install -m 0755 "$found" "${GOBIN_DIR}/${bin}"
fi
rm -rf "$tmp"
}
# Download a single binary release asset directly to GOBIN_DIR
# Usage: _install_bin <url> <installed-name>
_install_bin() {
local url="$1"
local name="$2"
curl -fsSL "$url" -o "${GOBIN_DIR}/${name}"
chmod 0755 "${GOBIN_DIR}/${name}"
}
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Main script
# Architecture detection
# Map uname -m to the Go download architecture suffix
# Go convention (used by gopls, govulncheck tarballs)
case "$(uname -m)" in
x86_64) _GOARCH="amd64" ;;
aarch64) _GOARCH="arm64" ;;
@@ -53,19 +89,28 @@ case "$(uname -m)" in
;;
esac
# Fetch the latest stable Go version string from the official download API
# uname -m verbatim (used by buf, goreleaser aarch64 vs arm64 assets)
_UNAME_M="$(uname -m)"
# goreleaser / ko / gotestsum / goose use x86_64 / arm64 (not aarch64)
if [ "$_UNAME_M" = "aarch64" ]; then
_ARCH_GLIBC="arm64"
else
_ARCH_GLIBC="$_UNAME_M"
fi
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Install Go distribution
_GO_VERSION="$(curl -fsSL 'https://go.dev/dl/?mode=json' | jq -r '.[0].version')"
echo "Installing ${_GO_VERSION} (linux/${_GOARCH})"
# Remove any prior installation and extract the new tarball
rm -rf "${GOINSTALL_DIR}"
curl -fsSL "https://dl.google.com/go/${_GO_VERSION}.linux-${_GOARCH}.tar.gz" | tar -C /usr/local -xz
# Symlink the core binaries so they are found without /usr/local/go/bin in PATH
ln -sf "${GOINSTALL_DIR}/bin/go" "${GOBIN_DIR}/go"
ln -sf "${GOINSTALL_DIR}/bin/gofmt" "${GOBIN_DIR}/gofmt"
# Wire up the environment for the tool installation that follows
export GOPATH="${GOPATH_DIR}"
export GOBIN="${GOBIN_DIR}"
export PATH="${GOINSTALL_DIR}/bin:${PATH}"
@@ -73,79 +118,118 @@ export GOCACHE="${GOCACHE_BUILD}"
export CGO_ENABLED="0"
export GOTOOLCHAIN="auto"
# Under QEMU arm64 emulation the Go compiler can segfault when many packages
# compile in parallel due to memory pressure. Serialise compilation on arm64.
[ "$(uname -m)" = "aarch64" ] && export GOFLAGS="${GOFLAGS:+$GOFLAGS }-p=1"
# Ensure the GOPATH directory tree exists
mkdir -p "${GOPATH_DIR}/pkg/mod" "${GOPATH_DIR}/cache" "${GOPATH_DIR}/bin"
echo "Installing Go tooling (GOBIN=${GOBIN_DIR})"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# Pre-built binary installs (fast — no compilation)
# Language server - editor integration (VSCode, Neovim, etc.)
go install golang.org/x/tools/gopls@latest
echo "Installing pre-built tools"
# Import organiser - superset of gofmt that also manages import groups
# goreleaser — release automation
_GR_VER="$(_gh_latest goreleaser/goreleaser)"
_GR_TAG="${_GR_VER#v}"
_install_tar \
"https://github.com/goreleaser/goreleaser/releases/download/${_GR_VER}/goreleaser_Linux_${_ARCH_GLIBC}.tar.gz" \
"goreleaser"
# golangci-lint — meta-linter (official installer writes to /usr/local/bin)
curl -fsSL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh \
| sh -s -- -b "${GOBIN_DIR}" latest
# staticcheck — standalone advanced static analyser
_SC_VER="$(_gh_latest dominikh/go-tools .tag_name)"
_install_tar \
"https://github.com/dominikh/go-tools/releases/download/${_SC_VER}/staticcheck_linux_${_GOARCH}.tar.gz" \
"staticcheck"
# gofumpt — stricter formatter
_GF_VER="$(_gh_latest mvdan/gofumpt)"
_install_bin \
"https://github.com/mvdan/gofumpt/releases/download/${_GF_VER}/gofumpt_linux_${_GOARCH}" \
"gofumpt"
# gotestsum — structured test runner
_GTS_VER="$(_gh_latest gotestyourself/gotestsum)"
_GTS_TAG="${_GTS_VER#v}"
_install_tar \
"https://github.com/gotestyourself/gotestsum/releases/download/${_GTS_VER}/gotestsum_${_GTS_TAG}_linux_${_ARCH_GLIBC}.tar.gz" \
"gotestsum"
# ko — build Go container images without a Dockerfile
_KO_VER="$(_gh_latest google/ko)"
_KO_TAG="${_KO_VER#v}"
_install_tar \
"https://github.com/google/ko/releases/download/${_KO_VER}/ko_${_KO_TAG}_Linux_${_ARCH_GLIBC}.tar.gz" \
"ko"
# air — live-reload dev server
_AIR_VER="$(_gh_latest air-verse/air)"
_install_bin \
"https://github.com/air-verse/air/releases/download/${_AIR_VER}/air_linux_${_GOARCH}" \
"air"
# buf — modern protobuf toolchain
# buf uses x86_64 / aarch64 (uname -m style)
_BUF_VER="$(_gh_latest bufbuild/buf)"
_install_bin \
"https://github.com/bufbuild/buf/releases/download/${_BUF_VER}/buf-Linux-${_UNAME_M}" \
"buf"
# goose — DB migration runner
_GOOSE_VER="$(_gh_latest pressly/goose)"
_GOOSE_TAG="${_GOOSE_VER#v}"
_install_bin \
"https://github.com/pressly/goose/releases/download/${_GOOSE_VER}/goose_linux_${_ARCH_GLIBC}" \
"goose"
# gopls — Go language server
_GOPLS_VER="$(curl -fsSL 'https://api.github.com/repos/golang/tools/tags?per_page=50' \
| jq -r '[.[] | select(.name | startswith("gopls/v"))] | .[0].name | ltrimstr("gopls/")')"
_install_tar \
"https://github.com/golang/tools/releases/download/gopls%2F${_GOPLS_VER}/gopls_${_GOPLS_VER}_linux_${_GOARCH}.tar.gz" \
"gopls"
# govulncheck — vulnerability scanner
_VULN_VER="$(curl -fsSL 'https://api.github.com/repos/golang/vuln/releases/latest' | jq -r '.tag_name')"
_install_tar \
"https://github.com/golang/vuln/releases/download/${_VULN_VER}/govulncheck_${_VULN_VER}_linux_${_GOARCH}.tar.gz" \
"govulncheck"
# - - - - - - - - - - - - - - - - - - - - - - - - -
# go install for tools without standalone release binaries
echo "Installing Go tooling via go install"
# Import organiser — superset of gofmt that also manages import groups
go install golang.org/x/tools/cmd/goimports@latest
# Stricter formatter used by many golangci-lint configs
go install mvdan.cc/gofumpt@latest
# Generate String() methods for iota-based types
go install golang.org/x/tools/cmd/stringer@latest
# Meta-linter: runs golint, errcheck, ineffassign, gocyclo, and many more
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Standalone advanced static analyser
go install honnef.co/go/tools/cmd/staticcheck@latest
# Vulnerability scanner against the Go vulnerability database
go install golang.org/x/vuln/cmd/govulncheck@latest
# Structured test runner with better output and JUnit/JSON export
go install gotest.tools/gotestsum@latest
# Source-level debugger
go install github.com/go-delve/delve/cmd/dlv@latest
# Live process diagnostics: list Go processes, dump stacks, force GC, etc.
# Live process diagnostics: list Go processes, dump stacks, force GC
go install github.com/google/gops@latest
# Benchmark comparison (statistically sound diff of pprof benchmark runs)
# Benchmark comparison statistically sound diff of pprof benchmark runs
go install golang.org/x/perf/cmd/benchstat@latest
# Live-reload dev server for iterative development
go install github.com/air-verse/air@latest
# Release automation: cross-compile, sign, publish, container images
go install github.com/goreleaser/goreleaser/v2@latest
# Compile-time dependency injection code generator
go install github.com/google/wire/cmd/wire@latest
# Mock generator for interfaces (uber fork of golang/mock)
# Mock generator for interfaces (Uber fork of golang/mock)
go install go.uber.org/mock/mockgen@latest
# Build Go container images without a Dockerfile
go install github.com/google/ko@latest
# protobuf Go code generator
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
# gRPC Go code generator
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
# Modern protobuf toolchain: lint, format, breaking-change detection, managed deps
go install github.com/bufbuild/buf/cmd/buf@latest
# DB schema migration runner (Go-native, supports Go and SQL migrations)
go install github.com/pressly/goose/v3/cmd/goose@latest
echo "Go tooling installed"
# Strip the module download cache and ephemeral build cache from this layer.
# The installed binaries in GOBIN_DIR are preserved in the image.
# Strip the module download cache and ephemeral build cache from this layer
go clean -modcache
go clean -cache
rm -rf "${GOCACHE_BUILD}"