diff --git a/.github/workflows/dependency-audit-reusable.yml b/.github/workflows/dependency-audit-reusable.yml index 7a1f3f28a..3c9726805 100644 --- a/.github/workflows/dependency-audit-reusable.yml +++ b/.github/workflows/dependency-audit-reusable.yml @@ -133,7 +133,7 @@ jobs: go-version: "stable" - name: Install govulncheck - run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.4 + 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 - name: Audit Go dependencies run: | diff --git a/.github/workflows/dependency-audit.yml b/.github/workflows/dependency-audit.yml index da41b7abb..dcc064774 100644 --- a/.github/workflows/dependency-audit.yml +++ b/.github/workflows/dependency-audit.yml @@ -137,7 +137,7 @@ jobs: go-version: "stable" - name: Install govulncheck - run: go install golang.org/x/vuln/cmd/govulncheck@v1.1.4 + 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 - name: Audit Go dependencies run: | diff --git a/test/workflows/dependency-hardening.bats b/test/workflows/dependency-hardening.bats index 175cba34f..2dd02c680 100644 --- a/test/workflows/dependency-hardening.bats +++ b/test/workflows/dependency-hardening.bats @@ -57,6 +57,34 @@ workflow_command_lines() { [ "$fail" -eq 0 ] } +@test "every 'go install' in a workflow is version-pinned and S8545-exempted" { + # S8545 flags `go install` as non-lockfile-enforcing. Go has no --locked / + # --require-hashes equivalent: a pinned `@vX.Y.Z` is the reproducible install + # (verified via the Go checksum DB, sum.golang.org), so the finding is a confirmed + # false positive suppressed with an inline `# NOSONAR(githubactions:S8545)` + # marker. This guard fails loud if a new `go install` is added unpinned + # (@latest/@main) or without the marker. + local fail=0 file cmd + while IFS=$'\t' read -r file cmd || [ -n "$file" ]; do + case "$cmd" in + *"go install"*) + case "$cmd" in + *[a-zA-Z0-9_-]go\ install*) : ;; + *) + case "$cmd" in *"@v"[0-9]*) : ;; *) + echo "UNPINNED go install (needs @vX.Y.Z): ${file##*/}: $cmd"; fail=1 ;; + esac + case "$cmd" in *"NOSONAR(githubactions:S8545)"*) : ;; *) + echo "MISSING # NOSONAR(githubactions:S8545): ${file##*/}: $cmd"; fail=1 ;; + esac + ;; + esac + ;; + esac + done < <(workflow_command_lines) + [ "$fail" -eq 0 ] +} + @test "each hash-locked requirements file referenced by a workflow exists" { local fail=0 file cmd path while IFS=$'\t' read -r file cmd || [ -n "$file" ]; do