Files
coder/scripts/check_go_versions.sh
T
Thomas Kosiewski 5f9b3220b5 chore: install dogfood image tooling via mise.toml (#25282)
This PR replaces the hand-rolled `curl | tar | go install | cargo
install` chains in the dogfood Ubuntu 22.04 and 26.04 Dockerfiles with a
single `mise install` driven by a new repo-root `mise.toml`.

The previous Dockerfiles installed ~25 CLIs across three multi-stage
builds with versions hardcoded inline. Version bumps were scattered
across the Dockerfiles, the root `mise.toml` (added in #24618 but
otherwise unused at runtime), and CI's setup actions; build-time network
failures came from a dozen distinct endpoints; and `mise` itself sat in
the image with no manifest to install from.

The new flow:

- The repo's `mise.toml` is the single source of truth for image tool
versions. The Dockerfiles `COPY` it to `/etc/mise/config.toml` and run a
single `mise install` as the `coder` user.
- Tools are installed into `/opt/mise/data` rather than the default
`/home/coder/.local/share/mise`, so they live in the image (not on the
persistent home volume) and reach every workspace on recreate.
- Build context moves to the repo root so the Dockerfile can `COPY
mise.toml`; an allowlist `.dockerignore` keeps the transferred context
to ~24 kB.
- Optional `--secret id=github_token` plumbing through the Makefile and
`.github/workflows/dogfood.yaml` lifts aqua's GitHub API quota from
60/hr unauthenticated to 1000/hr with `secrets.GITHUB_TOKEN`.
- `MISE_TRUSTED_CONFIG_PATHS=/home/coder:/etc/mise` is set as an ENV so
users who clone the coder repo into their workspace home aren't prompted
to `mise trust`.

Net diff for the two Ubuntu Dockerfiles: -399 / +244 lines (~200 lines
shorter each). The `FROM rust-utils`, `FROM go`, and `FROM proto`
multi-stage builds are gone; so are the NVM/Node block, the bulk
binary-install block (golangci-lint, helm, kubectx, syft, cosign, bun),
the gh `.deb`/lazygit/doctl tarball installs, the gofmt
`update-alternatives` line, and the `yq`→`yq4` rename
(`scripts/lib.sh:267-275` already auto-detects either name).

Both images were built and smoke-tested with Apple's `container` CLI on
macOS — every migrated tool resolves to the expected pinned version
including outside the cloned coder repo (e.g. `gh` from `/home/coder`,
matching the workspace startup script in `dogfood/coder/main.tf`),
`sqlc` runs (proving `CGO_ENABLED=1` was honoured at install), `yq
--version` reports v4 for `scripts/lib.sh`'s detection, and `gofmt`
resolves via the mise shim.

Follow-ups (out of scope here):

- Commit a multi-platform `mise.lock` so `gh = "latest"` and the other
floating versions resolve deterministically across rebuilds and dev
machines.
- Migrate CI's `setup-go` / `setup-node` actions to consume `mise.toml`
so image and CI versions stop being able to drift.

---------

Signed-off-by: Thomas Kosiewski <tk@coder.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 11:36:22 +02:00

51 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# This script ensures that the same version of Go is referenced in all of the
# following files:
# - go.mod
# - mise.toml (the dogfood image installs from this manifest)
# - flake.nix
# - .github/actions/setup-go/action.yml
# The version of Go in go.mod is considered the source of truth.
set -euo pipefail
# shellcheck source=scripts/lib.sh
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
cdroot
# At the time of writing, Nix only has go 1.22.x.
# We don't want to fail the build for this reason.
IGNORE_NIX=${IGNORE_NIX:-false}
GO_VERSION_GO_MOD=$(grep -Eo 'go [0-9]+\.[0-9]+\.[0-9]+' ./go.mod | cut -d' ' -f2)
GO_VERSION_MISE_TOML=$(grep -Eo '^go = "[0-9]+\.[0-9]+\.[0-9]+"' ./mise.toml | sed -E 's/.*"([^"]+)"/\1/')
GO_VERSION_SETUP_GO=$(yq '.inputs.version.default' .github/actions/setup-go/action.yaml)
GO_VERSION_FLAKE_NIX=$(grep -Eo '\bgo_[0-9]+_[0-9]+\b' ./flake.nix)
# Convert to major.minor format.
GO_VERSION_FLAKE_NIX_MAJOR_MINOR=$(echo "$GO_VERSION_FLAKE_NIX" | cut -d '_' -f 2-3 | tr '_' '.')
log "INFO : go.mod : $GO_VERSION_GO_MOD"
log "INFO : mise.toml : $GO_VERSION_MISE_TOML"
log "INFO : setup-go/action.yaml : $GO_VERSION_SETUP_GO"
log "INFO : flake.nix : $GO_VERSION_FLAKE_NIX_MAJOR_MINOR"
if [ "$GO_VERSION_GO_MOD" != "$GO_VERSION_MISE_TOML" ]; then
error "Go version mismatch between go.mod and mise.toml"
fi
if [ "$GO_VERSION_GO_MOD" != "$GO_VERSION_SETUP_GO" ]; then
error "Go version mismatch between go.mod and .github/actions/setup-go/action.yaml"
fi
# At the time of writing, Nix only constrains the major.minor version.
# We need to check that specifically.
if [ "$IGNORE_NIX" = "false" ]; then
GO_VERSION_GO_MOD_MAJOR_MINOR=$(echo "$GO_VERSION_GO_MOD" | cut -d '.' -f 1-2)
if [ "$GO_VERSION_FLAKE_NIX_MAJOR_MINOR" != "$GO_VERSION_GO_MOD_MAJOR_MINOR" ]; then
error "Go version mismatch between go.mod and flake.nix"
fi
else
log "INFO : Ignoring flake.nix, as IGNORE_NIX=${IGNORE_NIX}"
fi
log "Go version check passed, all versions are $GO_VERSION_GO_MOD"