Skip to content

Commit 6e5007a

Browse files
authored
Merge pull request #53 from trustyai-explainability/main
[pull] main from trustyai-explainability:main
2 parents ecdd3ea + 2622279 commit 6e5007a

24 files changed

+785
-164
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
name: 'Test Setup'
2+
description: 'Common setup for detector test workflows'
3+
4+
inputs:
5+
component_name:
6+
description: 'Name of the component being tested (for caching)'
7+
required: true
8+
requirements_files:
9+
description: 'Space-separated list of requirements files to install'
10+
required: true
11+
precommit_paths:
12+
description: 'Space-separated list of paths to check with pre-commit'
13+
required: false
14+
default: ''
15+
python_version:
16+
description: 'Python version to use'
17+
required: false
18+
default: '3.11'
19+
needs_system_deps:
20+
description: 'Whether to install system dependencies (build-essential, wget)'
21+
required: false
22+
default: 'false'
23+
24+
runs:
25+
using: 'composite'
26+
steps:
27+
- name: Set up Python ${{ inputs.python_version }}
28+
uses: actions/setup-python@v5
29+
with:
30+
python-version: ${{ inputs.python_version }}
31+
32+
- name: Generate cache key
33+
id: cache-key
34+
shell: bash
35+
run: |
36+
# Create a hash of all requirements files for cache key
37+
CACHE_KEY="${{ runner.os }}-pip-${{ inputs.component_name }}-"
38+
for file in ${{ inputs.requirements_files }}; do
39+
if [ -f "$file" ]; then
40+
CACHE_KEY="${CACHE_KEY}$(sha256sum $file | cut -d' ' -f1)-"
41+
fi
42+
done
43+
echo "cache_key=${CACHE_KEY%%-}" >> $GITHUB_OUTPUT
44+
echo "cache_restore_keys=${{ runner.os }}-pip-${{ inputs.component_name }}-" >> $GITHUB_OUTPUT
45+
46+
- name: Cache pip dependencies
47+
uses: actions/cache@v4
48+
with:
49+
path: ~/.cache/pip
50+
key: ${{ steps.cache-key.outputs.cache_key }}
51+
restore-keys: |
52+
${{ steps.cache-key.outputs.cache_restore_keys }}
53+
${{ runner.os }}-pip-
54+
55+
- name: Install system dependencies
56+
if: inputs.needs_system_deps == 'true'
57+
shell: bash
58+
run: |
59+
sudo apt-get update
60+
sudo apt-get install -y --no-install-recommends \
61+
build-essential \
62+
wget
63+
64+
- name: Install dependencies
65+
shell: bash
66+
run: |
67+
python -m pip install --upgrade pip
68+
# Install test dependencies
69+
pip install pytest-cov
70+
# Install component-specific requirements
71+
for file in ${{ inputs.requirements_files }}; do
72+
if [ -f "$file" ]; then
73+
echo "Installing requirements from $file"
74+
pip install -r "$file"
75+
else
76+
echo "Warning: Requirements file $file not found"
77+
fi
78+
done
79+
80+
- name: Set Python path
81+
shell: bash
82+
run: |
83+
echo "PYTHONPATH=$GITHUB_WORKSPACE/detectors/huggingface:$GITHUB_WORKSPACE/detectors/llm_judge:$GITHUB_WORKSPACE/detectors:$GITHUB_WORKSPACE" >> $GITHUB_ENV
84+
85+
- name: Lint with pre-commit (if available)
86+
if: inputs.precommit_paths != ''
87+
shell: bash
88+
run: |
89+
if [ -f .pre-commit-config.yaml ]; then
90+
# Run pre-commit on specified paths
91+
find ${{ inputs.precommit_paths }} -name '*.py' 2>/dev/null | xargs -r pre-commit run --files
92+
else
93+
echo "No pre-commit config found, skipping linting"
94+
fi
95+
continue-on-error: true

.github/workflows/build-and-push.yaml

Lines changed: 28 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,46 @@
11
name: Build and Push - Detectors
22
on:
3+
# Trigger on successful test completion
4+
workflow_run:
5+
workflows:
6+
- "Tier 1 - Built-in detectors unit tests"
7+
- "Tier 1 - Hugging Face Runtime unit tests"
8+
- "Tier 1 - LLM Judge unit tests"
9+
types:
10+
- completed
11+
12+
# Direct triggers (tests will run in parallel)
313
push:
414
branches:
515
- main
16+
- incubation
17+
- stable
618
tags:
719
- v*
820
paths:
921
- 'detectors/*'
1022
- '.github/workflows/*'
11-
pull_request_target:
23+
pull_request:
1224
paths:
1325
- 'detectors/*'
1426
types: [labeled, opened, synchronize, reopened]
1527
jobs:
1628
# Ensure that tests pass before publishing a new image.
1729
build-and-push-ci:
30+
# Only run if:
31+
# 1. Running in the trustyai-explainability/guardrails-detectors repository, AND
32+
# 2. Tests completed successfully on target branches (from workflow_run trigger), OR
33+
# 3. Direct push/PR trigger (tests will run in parallel)
34+
if: |
35+
github.repository == 'trustyai-explainability/guardrails-detectors' &&
36+
((github.event_name == 'workflow_run' &&
37+
github.event.workflow_run.conclusion == 'success' &&
38+
contains(fromJSON('["main", "incubation", "stable"]'), github.event.workflow_run.head_branch)) ||
39+
(github.event_name != 'workflow_run'))
1840
runs-on: ubuntu-latest
1941
permissions:
2042
contents: read
2143
pull-requests: write
22-
security-events: write
2344
env:
2445
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
2546
GITHUB_REF_NAME: ${{ github.ref_name }}
@@ -44,12 +65,15 @@ jobs:
4465
mode: minimum
4566
count: 1
4667
labels: "ok-to-test, lgtm, approved"
47-
- uses: actions/checkout@v3
68+
- uses: actions/checkout@v4
4869
if: env.BUILD_CONTEXT == 'ci'
4970
with:
5071
ref: ${{ github.event.pull_request.head.sha }}
51-
- uses: actions/checkout@v3
72+
persist-credentials: false
73+
- uses: actions/checkout@v4
5274
if: env.BUILD_CONTEXT == 'main' || env.BUILD_CONTEXT == 'tag'
75+
with:
76+
persist-credentials: false
5377
#
5478
# Print variables for debugging
5579
- name: Log reference variables
@@ -129,51 +153,3 @@ jobs:
129153
📦 [Huggingface PR image](https://quay.io/repository/trustyai/guardrails-detector-huggingface-runtime-ci?tab=tags): `quay.io/trustyai/guardrails-detector-huggingface-runtime-ci:$PR_HEAD_SHA`
130154
📦 [Built-in PR image](https://quay.io/trustyai/guardrails-detector-built-in-ci?tab=tags): `quay.io/trustyai/guardrails-detector-built-in-ci:$PR_HEAD_SHA`
131155
📦 [LLM Judge PR image](https://quay.io/trustyai/guardrails-detector-llm-judge-ci?tab=tags): `quay.io/trustyai/guardrails-detector-llm-judge-ci:$PR_HEAD_SHA`
132-
- name: Trivy scan
133-
uses: aquasecurity/trivy-action@0.28.0
134-
with:
135-
scan-type: 'image'
136-
image-ref: "${{ env.IMAGE_NAME }}:${{ env.TAG }}"
137-
format: 'sarif'
138-
output: 'trivy-results.sarif'
139-
severity: 'MEDIUM,HIGH,CRITICAL'
140-
exit-code: '0'
141-
ignore-unfixed: false
142-
vuln-type: 'os,library'
143-
- name: Trivy scan, built-in image
144-
uses: aquasecurity/trivy-action@0.28.0
145-
with:
146-
scan-type: 'image'
147-
image-ref: "${{ env.BUILTIN_IMAGE_NAME }}:${{ env.TAG }}"
148-
format: 'sarif'
149-
output: 'trivy-results-built-in.sarif'
150-
severity: 'MEDIUM,HIGH,CRITICAL'
151-
exit-code: '0'
152-
ignore-unfixed: false
153-
vuln-type: 'os,library'
154-
- name: Trivy scan, LLM Judge image
155-
uses: aquasecurity/trivy-action@0.28.0
156-
with:
157-
scan-type: 'image'
158-
image-ref: "${{ env.LLM_JUDGE_IMAGE_NAME }}:${{ env.TAG }}"
159-
format: 'sarif'
160-
output: 'trivy-results-llm-judge.sarif'
161-
severity: 'MEDIUM,HIGH,CRITICAL'
162-
exit-code: '0'
163-
ignore-unfixed: false
164-
vuln-type: 'os,library'
165-
- name: Update Security tab - Huggingface
166-
uses: github/codeql-action/upload-sarif@v3
167-
with:
168-
sarif_file: 'trivy-results.sarif'
169-
category: huggingface
170-
- name: Update Security tab - Built-in
171-
uses: github/codeql-action/upload-sarif@v3
172-
with:
173-
sarif_file: 'trivy-results-built-in.sarif'
174-
category: built-in
175-
- name: Update Security tab - LLM Judge
176-
uses: github/codeql-action/upload-sarif@v3
177-
with:
178-
sarif_file: 'trivy-results-llm-judge.sarif'
179-
category: llm-judge
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: Tier 1 - Security scan
2+
3+
on:
4+
push:
5+
branches: [ main, incubation, stable ]
6+
paths:
7+
- 'detectors/**'
8+
- 'requirements*.txt'
9+
- '*.py'
10+
- '.github/workflows/security-scan.yaml'
11+
12+
pull_request:
13+
branches: [ main, incubation, stable ]
14+
paths:
15+
- 'detectors/**'
16+
- 'requirements*.txt'
17+
- '*.py'
18+
- '.github/workflows/security-scan.yaml'
19+
20+
# Manual trigger for security scans
21+
workflow_dispatch:
22+
23+
# Scheduled security scans
24+
schedule:
25+
- cron: '0 2 * * 1' # Weekly on Mondays at 2 AM UTC
26+
27+
jobs:
28+
filesystem-security-scan:
29+
runs-on: ubuntu-latest
30+
31+
permissions:
32+
contents: read
33+
security-events: write
34+
35+
strategy:
36+
matrix:
37+
component:
38+
- name: "builtin-detectors"
39+
path: "detectors/built_in"
40+
- name: "huggingface-runtime"
41+
path: "detectors/huggingface"
42+
- name: "llm-judge"
43+
path: "detectors/llm_judge"
44+
- name: "common"
45+
path: "detectors/common"
46+
47+
steps:
48+
- name: Checkout code
49+
uses: actions/checkout@v4
50+
51+
- name: Log scan parameters
52+
run: |
53+
echo "Scanning filesystem path: ${{ matrix.component.path }}"
54+
echo "Component: ${{ matrix.component.name }}"
55+
56+
- name: Run Trivy vulnerability scanner (filesystem)
57+
uses: aquasecurity/trivy-action@0.28.0
58+
with:
59+
scan-type: 'fs'
60+
scan-ref: '${{ matrix.component.path }}'
61+
format: 'sarif'
62+
output: 'trivy-results-${{ matrix.component.name }}.sarif'
63+
severity: 'MEDIUM,HIGH,CRITICAL'
64+
exit-code: '0'
65+
scanners: 'vuln,secret'
66+
67+
- name: Run Trivy configuration scanner
68+
uses: aquasecurity/trivy-action@0.28.0
69+
with:
70+
scan-type: 'config'
71+
scan-ref: '${{ matrix.component.path }}'
72+
hide-progress: false
73+
format: 'sarif'
74+
output: 'trivy-config-${{ matrix.component.name }}.sarif'
75+
exit-code: '0'
76+
continue-on-error: true
77+
78+
- name: Upload vulnerability scan results to GitHub Security tab
79+
uses: github/codeql-action/upload-sarif@v3
80+
with:
81+
sarif_file: 'trivy-results-${{ matrix.component.name }}.sarif'
82+
category: '${{ matrix.component.name }}-vulnerabilities'
83+
84+
- name: Upload configuration scan results to GitHub Security tab
85+
uses: github/codeql-action/upload-sarif@v3
86+
if: hashFiles(format('trivy-config-{0}.sarif', matrix.component.name)) != ''
87+
with:
88+
sarif_file: 'trivy-config-${{ matrix.component.name }}.sarif'
89+
category: '${{ matrix.component.name }}-config'
90+
91+
- name: Generate human-readable vulnerability report
92+
uses: aquasecurity/trivy-action@0.28.0
93+
with:
94+
scan-type: 'fs'
95+
scan-ref: '${{ matrix.component.path }}'
96+
format: 'table'
97+
output: 'trivy-report-${{ matrix.component.name }}.txt'
98+
severity: 'HIGH,CRITICAL'
99+
exit-code: '0'
100+
scanners: 'vuln,secret'
101+
102+
- name: Upload scan artifacts
103+
uses: actions/upload-artifact@v4
104+
with:
105+
name: security-scan-${{ matrix.component.name }}
106+
path: |
107+
trivy-results-${{ matrix.component.name }}.sarif
108+
trivy-config-${{ matrix.component.name }}.sarif
109+
trivy-report-${{ matrix.component.name }}.txt
110+
retention-days: 30
111+
112+
# Scan the entire repository root for additional security issues
113+
repository-security-scan:
114+
runs-on: ubuntu-latest
115+
116+
permissions:
117+
contents: read
118+
security-events: write
119+
120+
steps:
121+
- name: Checkout code
122+
uses: actions/checkout@v4
123+
124+
- name: Run Trivy repository scan
125+
uses: aquasecurity/trivy-action@0.28.0
126+
with:
127+
scan-type: 'fs'
128+
scan-ref: '.'
129+
format: 'sarif'
130+
output: 'trivy-repository-results.sarif'
131+
severity: 'HIGH,CRITICAL'
132+
exit-code: '0'
133+
scanners: 'vuln,secret'
134+
135+
- name: Upload repository scan results to GitHub Security tab
136+
uses: github/codeql-action/upload-sarif@v3
137+
with:
138+
sarif_file: 'trivy-repository-results.sarif'
139+
category: 'repository-wide-security'
140+
141+
- name: Generate repository security report
142+
uses: aquasecurity/trivy-action@0.28.0
143+
with:
144+
scan-type: 'fs'
145+
scan-ref: '.'
146+
format: 'table'
147+
output: 'trivy-repository-report.txt'
148+
severity: 'HIGH,CRITICAL'
149+
exit-code: '0'
150+
scanners: 'vuln,secret'
151+
152+
- name: Upload repository scan artifacts
153+
uses: actions/upload-artifact@v4
154+
with:
155+
name: security-scan-repository
156+
path: |
157+
trivy-repository-results.sarif
158+
trivy-repository-report.txt
159+
retention-days: 30

0 commit comments

Comments
 (0)