From 31833052506ada78756ae015cbb395139518b149 Mon Sep 17 00:00:00 2001 From: Isaiah Grigsby Date: Tue, 14 Apr 2026 13:54:06 -0500 Subject: [PATCH] perf(trufflehog): scan all PR changed files in one process Run a single trufflehog filesystem invocation with the filtered path list instead of one process per file, avoiding repeated startup cost that dominated wall time on large diffs. Made-with: Cursor --- .github/workflows/reusable-trufflehog.yml | 24 +++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/.github/workflows/reusable-trufflehog.yml b/.github/workflows/reusable-trufflehog.yml index eb38baa..c8525fd 100644 --- a/.github/workflows/reusable-trufflehog.yml +++ b/.github/workflows/reusable-trufflehog.yml @@ -147,17 +147,33 @@ jobs: fi if [[ -s changed-files.txt ]]; then + # One TruffleHog process for all changed paths (same flags as non-PR scan). The + # previous per-file loop paid full startup cost for every path, which dominated + # runtime on large PRs. Paths are still filtered for excludes and missing files + # (e.g. deletions in the diff). + paths=() while IFS= read -r file; do if [[ -s /tmp/exclude-regexes.txt ]] && echo "$file" | grep -qEf /tmp/exclude-regexes.txt 2>/dev/null; then echo "Skipping: ${file} (matches exclude pattern)" continue fi - if [[ -f "${file}" ]]; then - echo "Scanning: ${file}" - trufflehog filesystem "${file}" --exclude-paths /tmp/trufflehog-exclude.txt --concurrency 16 --json --no-update --results=verified,unverified >> results.ndjson || true + paths+=("${file}") fi done < changed-files.txt + + if ((${#paths[@]} > 0)); then + echo "Running TruffleHog on ${#paths[@]} changed file(s) in a single invocation..." + trufflehog filesystem \ + --exclude-paths /tmp/trufflehog-exclude.txt \ + --concurrency 16 \ + --json \ + --no-update \ + --results=verified,unverified \ + "${paths[@]}" > results.ndjson || true + else + echo "No files to scan after excludes (only deletions or excluded paths)" + fi else echo "No files changed" fi @@ -379,7 +395,7 @@ jobs: id-token: write steps: - name: Get Prometheus secrets from Vault - uses: grafana/shared-workflows/actions/get-vault-secrets@f1614b210386ac420af6807a997ac7f6d96e477a # get-vault-secrets/v1.3.1 + uses: grafana/shared-workflows/actions/get-vault-secrets@078c4a8af09e06d646077550f9e0f68171d5881e # get-vault-secrets/v1.3.1 with: common_secrets: | PROMETHEUS_URL=grafana-bench:prometheus_url