Skip to content

Commit bfdc361

Browse files
committed
v1.0.0 — EU AI Act compliance scanner GitHub Action
0 parents  commit bfdc361

4 files changed

Lines changed: 952 additions & 0 deletions

File tree

.github/workflows/test.yml

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
name: Test Compliance Action
2+
3+
on:
4+
push:
5+
branches: [main, develop]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test-basic:
11+
name: Test Basic Scan
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Run compliance scan
17+
id: scan
18+
uses: ./
19+
with:
20+
path: '.'
21+
strict: false
22+
badge: true
23+
format: 'summary'
24+
25+
- name: Check outputs
26+
run: |
27+
echo "Score: ${{ steps.scan.outputs.score }}"
28+
echo "Status: ${{ steps.scan.outputs.status }}"
29+
echo "Badge URL: ${{ steps.scan.outputs.badge_url }}"
30+
echo "Total checks: ${{ steps.scan.outputs.total_checks }}"
31+
echo "Passed: ${{ steps.scan.outputs.passed }}"
32+
echo "Warned: ${{ steps.scan.outputs.warned }}"
33+
echo "Failed: ${{ steps.scan.outputs.failed }}"
34+
35+
- name: Verify outputs exist
36+
run: |
37+
if [ -z "${{ steps.scan.outputs.score }}" ]; then
38+
echo "Error: score output is empty"
39+
exit 1
40+
fi
41+
if [ -z "${{ steps.scan.outputs.status }}" ]; then
42+
echo "Error: status output is empty"
43+
exit 1
44+
fi
45+
if [ -z "${{ steps.scan.outputs.badge_url }}" ]; then
46+
echo "Error: badge_url output is empty"
47+
exit 1
48+
fi
49+
echo "All outputs present and valid"
50+
51+
test-strict-mode:
52+
name: Test Strict Mode
53+
runs-on: ubuntu-latest
54+
steps:
55+
- uses: actions/checkout@v4
56+
57+
- name: Run scan in strict mode
58+
id: scan
59+
uses: ./
60+
with:
61+
path: '.'
62+
strict: true
63+
format: 'summary'
64+
continue-on-error: true
65+
66+
- name: Report strict mode result
67+
run: |
68+
if [ "${{ steps.scan.outcome }}" = "failure" ]; then
69+
echo "Strict mode correctly failed due to compliance issues"
70+
else
71+
echo "Scan passed in strict mode"
72+
fi
73+
74+
test-verbose-mode:
75+
name: Test Verbose Output
76+
runs-on: ubuntu-latest
77+
steps:
78+
- uses: actions/checkout@v4
79+
80+
- name: Run scan in verbose mode
81+
uses: ./
82+
with:
83+
path: '.'
84+
format: 'verbose'
85+
86+
test-json-output:
87+
name: Test JSON Format
88+
runs-on: ubuntu-latest
89+
steps:
90+
- uses: actions/checkout@v4
91+
92+
- name: Run scan with JSON output
93+
id: scan
94+
uses: ./
95+
with:
96+
path: '.'
97+
format: 'json'
98+
99+
- name: Verify JSON structure
100+
run: |
101+
# The action outputs the same fields regardless of format
102+
# JSON format is handled by the air-compliance tool itself
103+
if [ -z "${{ steps.scan.outputs.score }}" ]; then
104+
echo "Error: JSON format did not produce outputs"
105+
exit 1
106+
fi
107+
echo "JSON format outputs verified"
108+
109+
test-custom-path:
110+
name: Test Custom Path
111+
runs-on: ubuntu-latest
112+
steps:
113+
- uses: actions/checkout@v4
114+
115+
- name: Create test subdirectory with Python
116+
run: |
117+
mkdir -p test_project
118+
cat > test_project/sample.py << 'EOF'
119+
"""Sample AI agent for testing."""
120+
121+
from typing import Optional
122+
123+
class AIAgent:
124+
"""A simple AI agent."""
125+
126+
def __init__(self):
127+
"""Initialize the agent."""
128+
pass
129+
130+
def run(self, input_text: str) -> str:
131+
"""Run the agent.
132+
133+
Args:
134+
input_text: The input to process
135+
136+
Returns:
137+
The processed output
138+
"""
139+
# Add error handling
140+
try:
141+
result = self._process(input_text)
142+
return result
143+
except Exception as e:
144+
# Log the error
145+
print(f"Error: {e}")
146+
return "Error occurred"
147+
148+
def _process(self, text: str) -> str:
149+
"""Process the input.
150+
151+
Args:
152+
text: The text to process
153+
154+
Returns:
155+
The processed text
156+
"""
157+
return text.upper()
158+
EOF
159+
160+
- name: Scan custom path
161+
id: custom
162+
uses: ./
163+
with:
164+
path: 'test_project'
165+
strict: false
166+
167+
- name: Verify custom path scan
168+
run: |
169+
echo "Custom path scan completed"
170+
echo "Score: ${{ steps.custom.outputs.score }}"
171+
echo "Status: ${{ steps.custom.outputs.status }}"
172+
173+
test-badge-generation:
174+
name: Test Badge Generation
175+
runs-on: ubuntu-latest
176+
steps:
177+
- uses: actions/checkout@v4
178+
179+
- name: Run scan and get badge
180+
id: scan
181+
uses: ./
182+
with:
183+
path: '.'
184+
badge: true
185+
186+
- name: Verify badge URL
187+
run: |
188+
BADGE_URL="${{ steps.scan.outputs.badge_url }}"
189+
if [[ $BADGE_URL == "https://img.shields.io/badge/"* ]]; then
190+
echo "Badge URL is valid: $BADGE_URL"
191+
else
192+
echo "Error: Invalid badge URL format"
193+
exit 1
194+
fi
195+
196+
test-integration:
197+
name: Integration Test - Full Workflow
198+
runs-on: ubuntu-latest
199+
steps:
200+
- uses: actions/checkout@v4
201+
202+
- name: Run full compliance workflow
203+
id: compliance
204+
uses: ./
205+
with:
206+
path: '.'
207+
strict: false
208+
badge: true
209+
format: 'summary'
210+
211+
- name: Display compliance report
212+
if: always()
213+
run: |
214+
echo "====== Compliance Scan Results ======"
215+
echo "Score: ${{ steps.compliance.outputs.score }}%"
216+
echo "Status: ${{ steps.compliance.outputs.status }}"
217+
echo "Total Checks: ${{ steps.compliance.outputs.total_checks }}"
218+
echo "Passed: ${{ steps.compliance.outputs.passed }}"
219+
echo "Warned: ${{ steps.compliance.outputs.warned }}"
220+
echo "Failed: ${{ steps.compliance.outputs.failed }}"
221+
echo "Badge: ${{ steps.compliance.outputs.badge_url }}"
222+
echo "======================================"
223+
224+
- name: Comment on PR with results
225+
if: github.event_name == 'pull_request'
226+
uses: actions/github-script@v7
227+
with:
228+
script: |
229+
const score = "${{ steps.compliance.outputs.score }}";
230+
const status = "${{ steps.compliance.outputs.status }}";
231+
const passed = "${{ steps.compliance.outputs.passed }}";
232+
const failed = "${{ steps.compliance.outputs.failed }}";
233+
234+
github.rest.issues.createComment({
235+
issue_number: context.issue.number,
236+
owner: context.repo.owner,
237+
repo: context.repo.repo,
238+
body: `
239+
## EU AI Act Compliance Report
240+
241+
**Score:** ${score}%
242+
**Status:** ${status.toUpperCase()}
243+
244+
**Results:**
245+
- Passed: ${passed}
246+
- Failed: ${failed}
247+
248+
See the full report in the [Actions summary](${context.payload.pull_request.html_url}/checks) above.
249+
`
250+
});

0 commit comments

Comments
 (0)