diff --git a/.github/workflows/dependency-audit-reusable.yml b/.github/workflows/dependency-audit-reusable.yml index 0e547b62a..df56b9248 100644 --- a/.github/workflows/dependency-audit-reusable.yml +++ b/.github/workflows/dependency-audit-reusable.yml @@ -13,11 +13,16 @@ # reusable's own commit and source it. # # Pinned tool versions (update deliberately): -# govulncheck v1.1.4 | cargo-audit 0.22.1 | pip-audit 2.9.0 +# govulncheck v1.9.0 | cargo-audit 0.22.1 | pip-audit 2.9.0 # Python 3.13 for pip-audit (`python-version` input). Never a floating "3.x": # a new Python release can break the hash-locked tooling for every caller at # once (3.15 removed sre_constants, crashing pip-api 0.0.34's vendored # pyparsing). +# Go `stable` for govulncheck, on purpose: setup-go sets GOTOOLCHAIN=local, so +# the toolchain must be at least every audited go.mod's `go` line, and a fixed +# pin would break the job the day a caller bumps it. The cost is that a new Go +# release can outrun an old govulncheck's x/tools parser (v1.1.4 panicked with +# `unexpected expr: *ast.KeyValueExpr` on Go 1.27), so keep govulncheck current. name: Dependency audit (Reusable) on: @@ -149,7 +154,7 @@ jobs: go-version: "stable" - name: Install govulncheck - run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.4 # NOSONAR(githubactions:S8545) pinned @vX.Y.Z is reproducible (verified via Go checksum DB); no --locked equivalent + run: go install golang.org/x/vuln/cmd/govulncheck@v1.9.0 # NOSONAR(githubactions:S8545) pinned @vX.Y.Z is reproducible (verified via Go checksum DB); no --locked equivalent - name: Audit Go dependencies run: | diff --git a/test/workflows/dependency-audit/dependency-audit.bats b/test/workflows/dependency-audit/dependency-audit.bats index 384603a30..73a0501f7 100644 --- a/test/workflows/dependency-audit/dependency-audit.bats +++ b/test/workflows/dependency-audit/dependency-audit.bats @@ -257,6 +257,22 @@ TOML [ "$(yq -r '.jobs.detect.name' "$DA_WORKFLOW")" = 'Detect ecosystems' ] } +# govulncheck runs on Go `stable`; v1.1.4's x/tools parser panicked on Go 1.27 +# (`unexpected expr: *ast.KeyValueExpr`), failing every Go audit. The pin must +# not fall back below v1.9.0 and must match the header's pinned-versions line. +@test "workflow: govulncheck is pinned at v1.9.0 or later, matching the header" { + local install pin header + install="$(yq -r '.jobs["audit-go"].steps[] | select(.name == "Install govulncheck") | .run' "$DA_WORKFLOW")" + # The whole step, comment stripped, must be the one pinned install: a version + # in a trailing comment or a pre-release suffix must not satisfy the check. + pin="$(sed -E 's/[[:space:]]+#.*$//' <<<"$install" \ + | sed -nE 's|^go install golang\.org/x/vuln/cmd/govulncheck@(v[0-9]+\.[0-9]+\.[0-9]+)$|\1|p')" + header="$(grep -oE '^# govulncheck v[0-9]+\.[0-9]+\.[0-9]+' "$DA_WORKFLOW" | awk '{print $3}')" + [ -n "$pin" ] + [ "$pin" = "$header" ] + [ "$(printf '%s\n' v1.9.0 "$pin" | sort -V | head -1)" = 'v1.9.0' ] +} + @test "workflow: tooling is checked out from the reusable's own commit, outside the scanned tree" { local job for job in audit-cargo audit-pip audit-gate; do