mise.md

  1# Go mise
  2
  3Read [../mise.md](../mise.md) and [baseline.md](baseline.md) before applying
  4this file. Use `mise.toml` as the project task runner and tool installer.
  5Translate older Taskfile/justfile commands into mise instead of preserving the
  6old runner by default.
  7
  8## Baseline Go `mise.toml`
  9
 10Adapt names and paths, but keep the shape recognisable:
 11
 12```toml
 13min_version = "2026.2.4"
 14
 15[env]
 16GOAMD64 = "v3"
 17
 18[vars]
 19test_args = "-v -race -count=5 -p=3 -timeout=5m ./..."
 20
 21[tools]
 22go = "latest"
 23"go:golang.org/x/vuln/cmd/govulncheck" = "latest"
 24golangci-lint = "latest"
 25
 26[tasks.fmt]
 27description = "Format Go code"
 28run = "golangci-lint fmt"
 29
 30[tasks.tidy]
 31description = "Tidy go.mod and go.sum"
 32run = "go mod tidy"
 33
 34[tasks.modernize]
 35description = "Apply Go modernization fixes"
 36run = "golangci-lint run --enable-only modernize --fix ./..."
 37
 38[tasks.lint]
 39description = "Lint Go code and apply safe fixes"
 40run = "golangci-lint run --fix"
 41
 42[tasks.fix]
 43description = "Format, modernize, and apply lint fixes"
 44run = [
 45  "mise run fmt",
 46  "mise run modernize",
 47  "mise run lint",
 48]
 49
 50[tasks.vet]
 51description = "Run go vet"
 52run = "go vet ./..."
 53
 54[tasks.vuln]
 55description = "Run govulncheck"
 56run = "govulncheck ./..."
 57
 58[tasks.build]
 59description = "Build all Go packages"
 60run = "go build ./..."
 61
 62[tasks.test]
 63description = "Run Go tests repeatedly with the race detector"
 64env = { CGO_ENABLED = "1" }
 65run = "go test {{vars.test_args}}"
 66
 67[tasks."test:quiet"]
 68description = "Run Go tests with quiet success output"
 69env = { CGO_ENABLED = "1" }
 70run = '''
 71if output=$(go test {{vars.test_args}} 2>&1); then
 72  echo "✓"
 73else
 74  echo "$output"
 75  exit 1
 76fi
 77'''
 78
 79[tasks.check]
 80description = "Format, tidy, lint, scan, build, and test"
 81run = [
 82  "mise run fix",
 83  "mise run tidy",
 84  "mise run vet",
 85  "mise run vuln",
 86  "mise run build",
 87  "mise run test:quiet",
 88]
 89```
 90
 91`GOAMD64=v3` is Amolith's personal/performance baseline. Lower or remove it for
 92public binaries that need broad x86-64 compatibility.
 93
 94Do not add a non-mutating tidy check unless the user asks for it. `tidy` is the
 95task.
 96
 97## Binary projects
 98
 99For a user-facing binary, make build/install tasks target the actual command:
100
101```toml
102[vars]
103binary = "example"
104main = "./cmd/example"
105static_tags = "netgo,osusergo,static_build"
106static_ldflags = "-d -s -w -buildid= -extldflags=-static"
107
108[tasks.build]
109description = "Build a static pure-Go binary"
110env = { CGO_ENABLED = "0" }
111run = '''
112go build \
113  -trimpath \
114  -tags '{{vars.static_tags}}' \
115  -ldflags '{{vars.static_ldflags}}' \
116  -o {{vars.binary}} \
117  {{vars.main}}
118'''
119
120[tasks.install]
121description = "Install a static pure-Go binary"
122env = { CGO_ENABLED = "0" }
123run = '''
124go install \
125  -trimpath \
126  -tags '{{vars.static_tags}}' \
127  -ldflags '{{vars.static_ldflags}}' \
128  {{vars.main}}
129'''
130```
131
132Do not settle version policy by copying the static template. The template leaves
133`-buildvcs` unspecified, so Go uses its `auto` behavior. For version reporting,
134those fields matter only if project code or Fang reads them; they can still
135matter for reproducibility or privacy, so choose `-buildvcs` explicitly when that
136matters. Choose the policy with the user:
137
138- **Best-effort local/dev metadata**: leave `-buildvcs` unset and read
139  `runtime/debug.BuildInfo` or Fang's fallback when `unknown` is acceptable.
140- **Release/package/user-visible version**: derive an exact semver or commit in
141  the task and inject it with `-ldflags -X ...`.
142- **jj-derived versions or multiple version surfaces**: keep a project-owned
143  resolver and pass the values to Fang, server metadata, package metadata, and
144  tests.
145- **Reproducible or privacy-sensitive builds**: consider `-buildvcs=false`, but
146  document the tradeoff. If a release task relies on Go VCS metadata, consider
147  `-buildvcs=true` so missing metadata fails loudly.
148
149The static template is for pure-Go binaries. It will not work for Wails, race
150tests, or projects that require CGO, native keychains, WebKitGTK, or C-backed
151database drivers.
152
153`netgo` forces the pure-Go DNS resolver. `osusergo` forces pure-Go user/group
154lookup. `static_build` is only a project convention unless files or dependencies
155use that build tag. `-extldflags=-static` asks the external linker for static C
156libraries when external linking is involved; it is not a magic fix for CGO.
157
158## Optional pprof tasks
159
160Add these only when the project intentionally exposes `net/http/pprof`, usually
161on localhost and behind an explicit debug flag:
162
163```toml
164[tasks."profile:cpu"]
165run = "go tool pprof -http :6061 'http://127.0.0.1:6060/debug/pprof/profile?seconds=15'"
166
167[tasks."profile:heap"]
168run = "go tool pprof -http :6061 'http://127.0.0.1:6060/debug/pprof/heap'"
169
170[tasks."profile:allocs"]
171run = "go tool pprof -http :6061 'http://127.0.0.1:6060/debug/pprof/allocs'"
172```
173
174## Frontend or Wails projects
175
176Add only the tools the project needs. For Wails, see [wails.md](wails.md); for
177light web apps, see [web.md](web.md). Keep frontend package manager choice
178project-specific: use the existing lockfile, or ask before introducing npm, Bun,
179pnpm, or yarn.