From f627c2a1f92af4f90a50cdf65f0c3d1a8c55d88f Mon Sep 17 00:00:00 2001 From: Blair Hamilton Date: Thu, 30 Jul 2026 11:52:58 -0400 Subject: [PATCH] feat(pre-commit-advisory): restore/seed Go caches for the golang hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The golang hooks are diff-*triggered* but whole-module in execution: golangci-lint typechecks the entire module and go-mod-tidy-repo re-resolves the full module graph, and the workflow cached neither the Go module/build caches nor golangci-lint's analysis cache — every PR run paid ~4 minutes cold (measured on chaos-lab: 42s tidy + 3m27s lint). PR runs now restore ~/go/pkg/mod, ~/.cache/go-build and ~/.cache/golangci-lint (restore-only, to avoid churning the 10GB cache budget with per-push saves), and the push-to-default-branch seed run executes the Go hooks and saves the caches per-sha, so PRs restore a warm cache at most one merge behind and only re-analyze what they touched. All three steps are gated on a go.sum existing — a no-op for non-Go callers. --- .github/workflows/pre-commit-advisory.yml | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/.github/workflows/pre-commit-advisory.yml b/.github/workflows/pre-commit-advisory.yml index c58507c..645af8e 100644 --- a/.github/workflows/pre-commit-advisory.yml +++ b/.github/workflows/pre-commit-advisory.yml @@ -164,6 +164,30 @@ jobs: ;; esac + # Go caches for the `language: golang` hooks (go-mod-tidy-repo, + # golangci-lint). pre-commit diff-scopes the *trigger* (the hooks are + # skipped when no .go file changed), but the hooks themselves are + # pass_filenames:false — golangci-lint typechecks the whole module and + # go mod tidy re-resolves the full module graph. Cold, that costs + # ~4 minutes per run (measured on chaos-lab: 42s tidy + 3m27s lint); + # warm, the same hooks re-analyze only what changed. ~/go/pkg/mod also + # holds the GOTOOLCHAIN auto-provisioned toolchain from the pin step + # above. Restore-only here: PR runs never save (a per-sha, ~0.5-1GB + # cache per push would churn the repo's 10GB cache budget); the + # push-to-default-branch seed run saves below, so PRs restore a cache + # at most one merge behind. + - name: Restore Go hook caches + if: hashFiles('**/go.sum') != '' + uses: actions/cache/restore@v6 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + ~/.cache/golangci-lint + key: go-hook-caches-${{ runner.os }}-${{ github.sha }} + restore-keys: | + go-hook-caches-${{ runner.os }}- + # Optional: install .NET SDK + restore local tools (csharpier, etc). # setup-dotnet@v5 caches the SDK by version across runs. - name: Set up .NET @@ -218,6 +242,29 @@ jobs: if: github.event_name == 'push' run: pre-commit install-hooks + # install-hooks builds hook envs but never *executes* the Go hooks, so + # the default-branch scope would otherwise never hold a warm Go + # module/build/lint cache and every PR would pay the cold whole-module + # lint. Execute the Go hooks here to populate those caches. `|| true` + # on each: this is a cache seed, not a gate — whole-repo runs replay + # org-wide debt on purpose here, and repos without one of these hook + # ids just skip it. + - name: Warm Go hook caches (cache seed) + if: github.event_name == 'push' && hashFiles('**/go.sum') != '' + run: | + pre-commit run go-mod-tidy-repo --all-files || true + pre-commit run golangci-lint --all-files || true + + - name: Save Go hook caches (cache seed) + if: github.event_name == 'push' && hashFiles('**/go.sum') != '' + uses: actions/cache/save@v6 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + ~/.cache/golangci-lint + key: go-hook-caches-${{ runner.os }}-${{ github.sha }} + - name: Run pre-commit on PR diff if: github.event_name == 'pull_request' id: precommit