diff --git a/.github/workflows/go-ci.yml b/.github/workflows/go-ci.yml index 08229c8..21549e9 100644 --- a/.github/workflows/go-ci.yml +++ b/.github/workflows/go-ci.yml @@ -22,6 +22,10 @@ on: golangci-lint-version: type: string default: 'v2.12.2' + golangci-lint-timeout: + description: 'Timeout passed to golangci-lint. Raise it for a large module or one with a cold build cache - setup-go only caches the module cache, not the build cache, so a big repo can typecheck every package and dependency from scratch within this window.' + type: string + default: '5m' gosec-version: type: string default: 'v2.28.0' @@ -326,12 +330,28 @@ jobs: check-latest: true cache-dependency-path: ${{ inputs.working-directory }}/go.mod + # golangci-lint's package loader gets export data for every dependency + # by reading GOCACHE, same as a plain build. setup-go's cache only + # covers the module download cache, so on a fresh runner GOCACHE starts + # empty and lint ends up compiling everything itself, uncached, inside + # the timeout above. Building here fills GOCACHE for lint to reuse a + # moment later on the same runner, and fails fast with a plain compiler + # error if the module does not build at all, instead of a confusing + # lint timeout. Costs a few seconds on a small module; saves much more + # on a large one. + - name: Warm build cache + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + set -euo pipefail + go build ./... + - name: Run golangci-lint uses: golangci/golangci-lint-action@v9 with: version: ${{ inputs.golangci-lint-version }} working-directory: ${{ inputs.working-directory }} - args: --timeout=5m + args: --timeout=${{ inputs.golangci-lint-timeout }} verify: name: Verify