Skip to content

feat(setup-go): key Go caches per calling job, not per go.sum - #58

Merged
blairham merged 1 commit into
mainfrom
feat/setup-go-per-job-cache
Aug 15, 2026
Merged

feat(setup-go): key Go caches per calling job, not per go.sum#58
blairham merged 1 commit into
mainfrom
feat/setup-go-per-job-cache

Conversation

@blairham

@blairham blairham commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replaces actions/setup-go's built-in cache with an actions/cache step over ~/go/pkg/mod + ~/.cache/go-build, keyed setup-go-job-<os>-<arch>-<github.job>-<hash(go.mod, **/go.sum)>.

  • The built-in cache keys once per go.sum for the whole repo: the first job to save wins the key, and sibling jobs restore wrong-flag artifacts, recompile from scratch, and never save their own. Measured in k5s run 31884046285: the Test job spent 204 s of 242 s recompiling the dependency graph with -race -coverprofile on every run, against ~31 s of actual test time; its post-step logs Cache hit occurred on the primary key …, not saving cache.

  • restore-keys fall back to the same scope with an older go.sum (near-warm after a dep bump), then to any scope (a cold job still inherits a sibling's module downloads).

  • New cache-name input: fixed name shares one cache across jobs that compile identically; "false" disables caching.

  • Propagates to every @main caller on merge. Per-job keys are new, so each repo's first run per job compiles cold once and is warm from then on; the old setup-go-* caches age out on their own.

  • Supersedes feat(setup-go): release-cache — a release-scoped Go cache for goreleaser jobs #56 (goreleaser release-cache input): a goreleaser job's id gives it its own scope automatically, so the same benefit lands with zero caller opt-in. Second data point: k4a's last release spent 457 s of ~9 min inside Run GoReleaser on a cold cross-compile matrix — warm from the second release on under per-job scopes.

Test plan

  • Validation PR in k5s (k5s#99, closed after validating) on run 31885048037: cold run saved setup-go-job-Linux-X64-test-… / …-build-…; warm re-run restored them exactly — Test 284s→36s, Build 45s→37s
  • actionlint green

🤖 Generated with Claude Code

actions/setup-go's built-in cache keys once per go.sum for the whole
repo: the first job to finish saves the key, and every sibling job
restores artifacts compiled with the wrong flags, recompiles from
scratch, and never saves its own ('Cache hit occurred on the primary
key …, not saving cache'). In k5s the Test job spent ~204 s of its
242 s recompiling the dependency graph with -race -coverprofile on
EVERY run, against ~30 s of actual test time — permanently, because
the shared key already held the build job's plain artifacts.

Replace the built-in cache with an actions/cache step over
~/go/pkg/mod + ~/.cache/go-build keyed on
setup-go-job-<os>-<arch>-<github.job>-<hash(go.mod, **/go.sum)>, with
restore-keys falling back to the same scope on a dep bump and then to
any scope (a cold job still inherits a sibling's module cache). New
cache-name input overrides the scope; 'false' disables.

Propagates to every @main caller on merge — the per-job keys are new,
so each repo's first run per job recompiles once and is warm after.
@blairham
blairham merged commit 80222ff into main Aug 15, 2026
2 checks passed
@blairham
blairham deleted the feat/setup-go-per-job-cache branch August 15, 2026 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant