From 2acdfc022fddda3a4547a70cd95eff2a1cf2be89 Mon Sep 17 00:00:00 2001 From: hallelx2 Date: Sun, 18 Oct 2026 17:09:26 +0100 Subject: [PATCH 1/2] ci: keep Go's module and build caches between Lorx jobs Every Go job started from a bare golang:1.25 container: it downloaded every module and compiled every package from nothing (vet 96.8 s and build 98.7 s on 2026-10-17). Long jobs hold the Lorx server longer, and that server, an e2-small, peaked at 282% CPU and cancelled running jobs. vet, build, lint and test now point GOMODCACHE and GOCACHE (and, for lint, GOLANGCI_LINT_CACHE) at directories under .cache/ in the checkout. They name those directories in cache:, which Lorx keeps between jobs as volumes per repository, directory and image. ./... skips dot-directories, and .cache/ is git-ignored. fmt stays uncached, because gofmt -l . would walk the module cache. bit ci check: valid, 5 jobs in 3 levels. --- .lorx/actions/ci.yml | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/.lorx/actions/ci.yml b/.lorx/actions/ci.yml index dbe6ed2..f74c88f 100644 --- a/.lorx/actions/ci.yml +++ b/.lorx/actions/ci.yml @@ -3,6 +3,13 @@ # Jobs run in container images so a runner needs only docker or podman, not a Go toolchain. # GOFLAGS=-buildvcs=false: the checkout is owned by the runner's user, not the container's, # so git refuses it and Go's VCS stamping fails the build. +# +# Caches (HAL-3505): a job's `cache:` directories are kept between jobs, mounted at +# /work/ from a volume per repository, directory and image. Go is pointed at them, so a +# job reuses the modules and compiled packages the last one left instead of downloading and +# compiling everything again (vet and build each took ~97 s from nothing, 2026-10-17). They +# live under .cache/, which `./...` skips as a dot-directory. fmt stays uncached: `gofmt -l .` +# would walk the module cache, and it takes a second anyway. fmt: image: golang:1.25 @@ -11,27 +18,35 @@ fmt: vet: image: golang:1.25 - env: { GOFLAGS: -buildvcs=false } + env: { GOFLAGS: -buildvcs=false, GOMODCACHE: /work/.cache/gomod, GOCACHE: /work/.cache/gobuild } + cache: [.cache/gomod, .cache/gobuild] run: go vet ./... timeout: 20m build: needs: [fmt] image: golang:1.25 - env: { GOFLAGS: -buildvcs=false } + env: { GOFLAGS: -buildvcs=false, GOMODCACHE: /work/.cache/gomod, GOCACHE: /work/.cache/gobuild } + cache: [.cache/gomod, .cache/gobuild] run: go build ./... timeout: 20m lint: needs: [build] image: golangci/golangci-lint:v2.14.0 - env: { GOFLAGS: -buildvcs=false } + env: + GOFLAGS: -buildvcs=false + GOMODCACHE: /work/.cache/gomod + GOCACHE: /work/.cache/gobuild + GOLANGCI_LINT_CACHE: /work/.cache/golangci + cache: [.cache/gomod, .cache/gobuild, .cache/golangci] run: golangci-lint run ./... timeout: 20m test: needs: [vet, build] image: golang:1.25 - env: { GOFLAGS: -buildvcs=false } + env: { GOFLAGS: -buildvcs=false, GOMODCACHE: /work/.cache/gomod, GOCACHE: /work/.cache/gobuild } + cache: [.cache/gomod, .cache/gobuild] run: go test ./... timeout: 30m From c19d8b2918a5ee8706645678a3aafeb25e446e49 Mon Sep 17 00:00:00 2001 From: hallelx2 Date: Sun, 18 Oct 2026 17:48:42 +0100 Subject: [PATCH 2/2] ci: run the Go jobs only when something Go reads changes Lorx's step cache keys every step on the whole checkout, so a docs-only push re-ran all five Go jobs. Each job now names the paths it depends on: Go files, go.mod and go.sum, pkg/, internal/, cmd/ and testdata/ (the embedded migrations and test fixtures live there), the lint config and the CI file. docs/, charts/, selfhost/ and the READMEs run none of them. bit ci check: valid, 5 jobs, 5 path-filtered. --- .lorx/actions/ci.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.lorx/actions/ci.yml b/.lorx/actions/ci.yml index f74c88f..9564ee4 100644 --- a/.lorx/actions/ci.yml +++ b/.lorx/actions/ci.yml @@ -10,13 +10,21 @@ # compiling everything again (vet and build each took ~97 s from nothing, 2026-10-17). They # live under .cache/, which `./...` skips as a dot-directory. fmt stays uncached: `gofmt -l .` # would walk the module cache, and it takes a second anyway. +# +# Paths (HAL-3505): Lorx's step cache keys each step on the whole checkout, so any change, a +# README included, re-runs every step; `paths` decides whether a job runs at all. The Go jobs +# run when Go code, a module file, or anything Go reads changes: the embedded migrations under +# pkg/, the testdata, the lint config and this file. A change to docs/, charts/, selfhost/ or +# the READMEs runs none of them. fmt: + paths: ["**/*.go", go.mod, go.sum, pkg/**, internal/**, cmd/**, testdata/**, .golangci.yml, .lorx/**] image: golang:1.25 env: { GOFLAGS: -buildvcs=false } run: 'test -z "$(gofmt -l . | grep -v ^vendor/)"' vet: + paths: ["**/*.go", go.mod, go.sum, pkg/**, internal/**, cmd/**, testdata/**, .golangci.yml, .lorx/**] image: golang:1.25 env: { GOFLAGS: -buildvcs=false, GOMODCACHE: /work/.cache/gomod, GOCACHE: /work/.cache/gobuild } cache: [.cache/gomod, .cache/gobuild] @@ -24,6 +32,7 @@ vet: timeout: 20m build: + paths: ["**/*.go", go.mod, go.sum, pkg/**, internal/**, cmd/**, testdata/**, .golangci.yml, .lorx/**] needs: [fmt] image: golang:1.25 env: { GOFLAGS: -buildvcs=false, GOMODCACHE: /work/.cache/gomod, GOCACHE: /work/.cache/gobuild } @@ -32,6 +41,7 @@ build: timeout: 20m lint: + paths: ["**/*.go", go.mod, go.sum, pkg/**, internal/**, cmd/**, testdata/**, .golangci.yml, .lorx/**] needs: [build] image: golangci/golangci-lint:v2.14.0 env: @@ -44,6 +54,7 @@ lint: timeout: 20m test: + paths: ["**/*.go", go.mod, go.sum, pkg/**, internal/**, cmd/**, testdata/**, .golangci.yml, .lorx/**] needs: [vet, build] image: golang:1.25 env: { GOFLAGS: -buildvcs=false, GOMODCACHE: /work/.cache/gomod, GOCACHE: /work/.cache/gobuild }