.github/scripts/run-semgrep.sh14 of 14 statements covered (100.00%).
coveredmissednever traced by Bash (not counted)A line ending in … continues the statement above it and shares its fate.
| 1 | #!/bin/sh | |
| 2 | # ============================================================================= | |
| 3 | # run-semgrep.sh — run semgrep with repo-wide rule suppressions from a file | |
| 4 | # ============================================================================= | |
| 5 | # | |
| 6 | # The list of suppressed rule IDs (each with a justification) lives in | |
| 7 | # .github/config/semgrep-excluded-rules.txt | |
| 8 | # This script expands every non-comment, non-blank line into a repeated | |
| 9 | # `--exclude-rule <id>` argument and then runs `semgrep scan`. Keeping the IDs | |
| 10 | # in a version-controlled data file (the same posture as .trivyignore and | |
| 11 | # .pip-audit-ignore) means a suppression is reviewed as a data change rather | |
| 12 | # than hardwired into pipeline YAML, and every caller invokes this one script | |
| 13 | # instead of duplicating the flag list. | |
| 14 | # | |
| 15 | # Any arguments passed to this script are forwarded to `semgrep scan` ahead of | |
| 16 | # the scan target (the repository root). | |
| 17 | # | |
| 18 | # Usage: | |
| 19 | # sh .github/scripts/run-semgrep.sh | |
| 20 | # SEMGREP_EXCLUDE_RULES_FILE=/path/to/list sh .github/scripts/run-semgrep.sh | |
| 21 | # | |
| 22 | # POSIX sh on purpose: the semgrep container image is not guaranteed to ship | |
| 23 | # bash. | |
| 24 | # ============================================================================= | |
| 25 | 9 | set -eu |
| 26 | ||
| 27 | # Make path resolution independent of any inherited CDPATH (which would make | |
| 28 | # `cd` echo the resolved directory into the command substitution). | |
| 29 | 9 | unset CDPATH |
| 30 | ||
| 31 | # Resolve the repository root from this script's own location (.github/scripts). | |
| 32 | 36 | script_dir=$(cd -- "$(dirname -- "$0")" && pwd) |
| 33 | 27 | repo_root=$(cd -- "$script_dir/../.." && pwd) |
| 34 | 9 | exclude_file="${SEMGREP_EXCLUDE_RULES_FILE:-$repo_root/.github/config/semgrep-excluded-rules.txt}" |
| 35 | ||
| 36 | # Positional parameters ($@) accumulate any caller-supplied args first, then the | |
| 37 | # --exclude-rule flags read from the static config file. Each rule sits alone on | |
| 38 | # its line; `read` strips surrounding whitespace and the throwaway second field | |
| 39 | # absorbs any trailing inline comment, while the case skips blank/comment lines. | |
| 40 | 9 | if [ -f "$exclude_file" ]; then |
| 41 | 60 | while read -r rule _ || [ -n "$rule" ]; do |
| 42 | 45 | case "$rule" in |
| 43 | 38 | '' | '#'*) continue ;; |
| 44 | esac | |
| 45 | 7 | set -- "$@" --exclude-rule "$rule" |
| 46 | done < "$exclude_file" | |
| 47 | 7 | echo "run-semgrep: applied rule suppressions from $exclude_file" |
| 48 | else | |
| 49 | 2 | echo "run-semgrep: no suppression file at $exclude_file (no rule excludes)" |
| 50 | fi | |
| 51 | ||
| 52 | 9 | set -x |
| 53 | 9 | exec semgrep scan --config auto --error "$@" --json -o semgrep-report.json . |