Skip to content

Commit 3e03c75

Browse files
authored
Merge pull request #24 from prog-time/issues-9
[FEATURE] Add Semgrep CI snippet
2 parents 3376ade + e448652 commit 3e03c75

5 files changed

Lines changed: 130 additions & 0 deletions

File tree

CI/security/semgrep.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
semgrep:
2+
runs-on: ubuntu-latest
3+
steps:
4+
- uses: actions/checkout@v4
5+
6+
- uses: actions/setup-python@v5
7+
with:
8+
python-version: "3.12"
9+
10+
- name: Cache Semgrep
11+
uses: actions/cache@v4
12+
with:
13+
path: ~/.cache/semgrep
14+
key: semgrep-${{ runner.os }}-${{ hashFiles('**/.semgrepignore') }}
15+
16+
- name: Install Semgrep
17+
run: pip install semgrep==1.72.0
18+
19+
- name: Run Semgrep
20+
run: |
21+
set -euo pipefail
22+
23+
if ! command -v semgrep &> /dev/null; then
24+
echo "::error::semgrep not found. Install it before running this script."
25+
exit 1
26+
fi
27+
28+
echo "ℹ️ Running Semgrep static analysis..."
29+
30+
if semgrep --config p/default --error .; then
31+
echo "✅ Semgrep passed"
32+
exit 0
33+
else
34+
echo "❌ Semgrep found issues"
35+
exit 1
36+
fi

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ that projects compose into their own workflows.
1111
|------|----------|------|
1212
| gitleaks | security | [CI/security/gitleaks.yml](https://github.com/prog-time/workflows/blob/main/CI/security/gitleaks.yml) |
1313
| trivy | security | [CI/security/trivy.yml](https://github.com/prog-time/workflows/blob/main/CI/security/trivy.yml) |
14+
| semgrep | security | [CI/security/semgrep.yml](https://github.com/prog-time/workflows/blob/main/CI/security/semgrep.yml) |
1415
| ESLint | linters | [CI/linters/eslint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/eslint.yml) |
1516
| golangci-lint | linters | [CI/linters/golangci-lint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/golangci-lint.yml) |
1617
| Hadolint | linters | [CI/linters/hadolint.yml](https://github.com/prog-time/workflows/blob/main/CI/linters/hadolint.yml) |
@@ -82,6 +83,7 @@ Workflows/
8283
│ │ │ └── yamllint.yml
8384
│ │ ├── security/
8485
│ │ │ ├── gitleaks.yml
86+
│ │ │ ├── semgrep.yml
8587
│ │ │ └── trivy.yml
8688
│ │ ├── static_analysis/
8789
│ │ │ ├── mypy.yml
@@ -110,6 +112,7 @@ Workflows/
110112
│ │ └── yamllint.sh
111113
│ └── security/
112114
│ ├── gitleaks.sh
115+
│ ├── semgrep.sh
113116
│ └── trivy.sh
114117
115118
├── CI/ # assembled output (ready to use)
@@ -129,6 +132,7 @@ Workflows/
129132
│ │ └── yamllint.bats
130133
│ ├── security/
131134
│ │ ├── gitleaks.bats
135+
│ │ ├── semgrep.bats
132136
│ │ └── trivy.bats
133137
│ └── helpers/
134138
│ └── common.bash # shared test utilities (mocks, temp dirs)
@@ -204,6 +208,7 @@ shellcheck:
204208
|---------|------|----------------|
205209
| `CI/security/gitleaks.yml` | [gitleaks](https://github.com/gitleaks/gitleaks) | Hardcoded secrets, tokens, and API keys |
206210
| `CI/security/trivy.yml` | [trivy](https://github.com/aquasecurity/trivy) | CVEs in OS packages, container images, and dependency manifests |
211+
| `CI/security/semgrep.yml` | [semgrep](https://semgrep.dev) | OWASP Top 10 patterns and insecure coding patterns across Python, JS/TS, Go, Java, Ruby, and more |
207212

208213
### Linters
209214

scripts/CI/security/semgrep.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
semgrep:
2+
runs-on: ubuntu-latest
3+
steps:
4+
- uses: actions/checkout@v4
5+
6+
- uses: actions/setup-python@v5
7+
with:
8+
python-version: "3.12"
9+
10+
- name: Cache Semgrep
11+
uses: actions/cache@v4
12+
with:
13+
path: ~/.cache/semgrep
14+
key: semgrep-${{ runner.os }}-${{ hashFiles('**/.semgrepignore') }}
15+
16+
- name: Install Semgrep
17+
run: pip install semgrep==1.72.0
18+
19+
- name: Run Semgrep
20+
run: bash scripts/shell/security/semgrep.sh

scripts/shell/security/semgrep.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
if ! command -v semgrep &> /dev/null; then
5+
echo "::error::semgrep not found. Install it before running this script."
6+
exit 1
7+
fi
8+
9+
echo "ℹ️ Running Semgrep static analysis..."
10+
11+
if semgrep --config p/default --error .; then
12+
echo "✅ Semgrep passed"
13+
exit 0
14+
else
15+
echo "❌ Semgrep found issues"
16+
exit 1
17+
fi

tests/security/semgrep.bats

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env bats
2+
3+
load "../helpers/common"
4+
5+
SCRIPT="$BATS_TEST_DIRNAME/../../scripts/shell/security/semgrep.sh"
6+
7+
setup() {
8+
setup_test_dir
9+
mkdir -p "$TEST_DIR/bin"
10+
export PATH="$TEST_DIR/bin:$PATH"
11+
}
12+
13+
teardown() {
14+
teardown_test_dir
15+
}
16+
17+
make_semgrep_stub() {
18+
local exit_code="$1"
19+
cat > "$TEST_DIR/bin/semgrep" <<EOF
20+
#!/usr/bin/env bash
21+
exit $exit_code
22+
EOF
23+
chmod +x "$TEST_DIR/bin/semgrep"
24+
}
25+
26+
@test "semgrep not installed: exits 1 with error annotation" {
27+
# Do not create a semgrep stub — it should be absent from PATH
28+
run bash "$SCRIPT"
29+
[ "$status" -eq 1 ]
30+
[[ "$output" == *"::error::semgrep not found"* ]]
31+
}
32+
33+
@test "semgrep finds no issues: exits 0 with success message" {
34+
make_semgrep_stub 0
35+
run bash "$SCRIPT"
36+
[ "$status" -eq 0 ]
37+
[[ "$output" == *"✅ Semgrep passed"* ]]
38+
}
39+
40+
@test "semgrep finds issues: exits 1 with failure message" {
41+
make_semgrep_stub 1
42+
run bash "$SCRIPT"
43+
[ "$status" -eq 1 ]
44+
[[ "$output" == *"❌ Semgrep found issues"* ]]
45+
}
46+
47+
@test "scan message is printed before running semgrep" {
48+
make_semgrep_stub 0
49+
run bash "$SCRIPT"
50+
[ "$status" -eq 0 ]
51+
[[ "$output" == *"ℹ️ Running Semgrep static analysis"* ]]
52+
}

0 commit comments

Comments
 (0)