diff --git a/.github/workflows/scripts/govulncheck-run.sh b/.github/workflows/scripts/govulncheck-run.sh new file mode 100755 index 0000000000..07234f4dca --- /dev/null +++ b/.github/workflows/scripts/govulncheck-run.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -euo pipefail + +mkdir -p ./govulncheck 2>/dev/null + +# Get all package directories +ALL_PKG_DIRS=$(go list ./...) + +# Initialize failure flag +FAILED=0 + +# Repository prefix to remove from package names +REPO_PREFIX=$(go list -m) + +# Run govulncheck for each package +for pkg in $ALL_PKG_DIRS; do + # Remove the repository prefix from the package name to keep the category names short + # and replace slashes with underscores to make clear that the categories are not nested. + OUTPUT_FILE="./govulncheck/$(echo "$pkg" | sed "s|^$REPO_PREFIX/||" | tr '/' '_').sarif" + echo -e "\nRunning govulncheck for package $pkg" + if ! govulncheck ${GOVULN_OPTS:-} "$pkg" > "$OUTPUT_FILE"; then + echo "govulncheck failed for package $pkg, output saved to $OUTPUT_FILE" + FAILED=1 + else + echo "govulncheck succeeded for package $pkg, output saved to $OUTPUT_FILE" + fi +done + +if [ $FAILED -ne 0 ]; then + echo -e "\ngovulncheck failed for one or more packages" + exit 1 +fi + +echo -e "\ngovulncheck completed successfully for all packages" diff --git a/.github/workflows/vuln-scans.yml b/.github/workflows/vuln-scans.yml index 52e758bdec..ef9766fb3f 100644 --- a/.github/workflows/vuln-scans.yml +++ b/.github/workflows/vuln-scans.yml @@ -267,7 +267,7 @@ jobs: with: sarif_file: snyk.sarif - govulncheck: + govulncheck-run: runs-on: ubuntu-24.04 timeout-minutes: 30 steps: @@ -278,11 +278,63 @@ jobs: with: go-version: ${{ env.GO_VERSION }} cache-dependency-path: '**/go.sum' + - name: Install Tools run: make install-tools - - name: Run `govulncheck` - run: govulncheck -format sarif ./... > govulncheck.sarif + + - run: govulncheck --version + + - name: Run `govulncheck` script + env: + GOVULN_OPTS: --format sarif --scan package + run: ./.github/workflows/scripts/govulncheck-run.sh + + - name: Save govulncheck results as artifact + uses: actions/upload-artifact@v4 + with: + name: govulncheck-results + path: ./govulncheck/ + + govulncheck-categories: + runs-on: ubuntu-24.04 + outputs: + matrix: ${{ steps.capture-packages.outputs.matrix }} + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: ${{ env.GO_VERSION }} + cache-dependency-path: '**/go.sum' + - name: Capture Go Packages + id: capture-packages + run: | + repoPrefix=$(go list -m) + packages=$(go list ./... | sed "s|^$repoPrefix/||" | tr '/' '_') + category=$(for p in $(echo -e "$packages"); do echo "\"$p\","; done) + matrix=$(echo "{\"category\": [${category%,}]}" | tr -d '\n') + echo "$matrix" | jq + echo "matrix=${matrix}" >> $GITHUB_OUTPUT + + govulncheck-upload: + runs-on: ubuntu-24.04 + needs: [govulncheck-run, govulncheck-categories] + strategy: + matrix: ${{ fromJSON(needs.govulncheck-categories.outputs.matrix) }} + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Download govulncheck results artifact + uses: actions/download-artifact@v4 + with: + name: govulncheck-results + path: ./govulncheck/ + - name: Upload result to GitHub Code Scanning + if: always() uses: github/codeql-action/upload-sarif@v3 with: - sarif_file: govulncheck.sarif + sarif_file: ./govulncheck/${{ matrix.category }}.sarif + category: ${{ matrix.category }} diff --git a/.gitignore b/.gitignore index 1aa3972214..4fde6742bd 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,6 @@ deployments/heroku/test/node_modules # temp file created during testing tests/installation/testdata/systemd/splunk-otel-collector.conf + +# For convenience excluding sarif files generated by ./.github/workflows/scripts/govulncheck-run.sh +/govulncheck/ diff --git a/Makefile.Common b/Makefile.Common index d51cb3d24b..68ce3d3336 100644 --- a/Makefile.Common +++ b/Makefile.Common @@ -136,5 +136,13 @@ moddownload: $(GOCMD) mod download .PHONY: govulncheck -govulncheck: install-tools - govulncheck ./... \ No newline at end of file +govulncheck: + @FAILED=0; \ + @for pkg in $(shell $(GOCMD) list $(ALL_PKG_DIRS)); do \ + echo "\nRunning govulncheck for package $$pkg\n"; \ + govulncheck $${GOVULN_OPTS} $$pkg || FAILED=1; \ + done; \ + @if [ $$FAILED -ne 0 ]; then \ + echo "\ngovulncheck failed for one or more packages"; \ + exit 1; \ + fi