Skip to content

🛡️ Sentinel: [MEDIUM] Fix SQL template injection risk #289

🛡️ Sentinel: [MEDIUM] Fix SQL template injection risk

🛡️ Sentinel: [MEDIUM] Fix SQL template injection risk #289

Workflow file for this run

name: Minimal CI
on:
push:
branches: [main]
pull_request:
branches: [main]
# Cancel in-progress runs for same PR
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Tests
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest-cov
pip install -e ".[dev]"
- name: Run tests
run: |
pytest -n0 tests/ -xvs --tb=short --cov=src --cov-report=xml
env:
PYTHONPATH: src
- name: Upload coverage
uses: codecov/codecov-action@v4
if: matrix.python-version == '3.11'
with:
files: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
security:
name: Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install security tools
run: |
python -m pip install bandit safety pip-audit
- name: Run Bandit (SAST)
id: bandit
run: |
bandit -r src/ -f json -o bandit-report.json || true
continue-on-error: true
- name: Run Safety (Dependency Check)
id: safety
run: |
safety check --json > safety-report.json || true
continue-on-error: true
- name: Run Pip-audit
id: pip-audit
run: |
pip-audit --desc --format json > pip-audit-report.json || true
continue-on-error: true
- name: Parse security reports
run: |
python << 'EOF'
import json
import sys
# Bandit
try:
with open('bandit-report.json') as f:
bandit = json.load(f)
print(f"Bandit: {bandit.get('metrics', {}).get('SEVERITY.HIGH', 0)} HIGH issues")
except:
pass
# Safety
try:
with open('safety-report.json') as f:
safety = json.load(f)
vulns = safety.get('vulnerabilities', [])
print(f"Safety: {len(vulns)} known vulnerabilities")
except:
pass
# Pip-audit
try:
with open('pip-audit-report.json') as f:
pip_audit = json.load(f)
deps = pip_audit.get('dependencies', [])
vuln_deps = [d for d in deps if d.get('vulnerabilities')]
print(f"Pip-audit: {len(vuln_deps)} vulnerable packages")
except:
pass
EOF
- name: Upload security reports
uses: actions/upload-artifact@v4
if: always()
with:
name: security-reports
path: |
bandit-report.json
safety-report.json
pip-audit-report.json
- name: Comment PR with security results
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const issue_number = context.issue.number;
const fs = require('fs');
const parseJsonSafe = (filepath) => {
try {
if (fs.existsSync(filepath)) {
const content = fs.readFileSync(filepath, 'utf8');
if (!content.trim()) return {};
const start = content.indexOf('{');
const end = content.lastIndexOf('}');
if (start !== -1 && end !== -1) {
return JSON.parse(content.substring(start, end + 1));
}
}
} catch (e) { console.error(`Error parsing ${filepath}:`, e); }
return {};
};
let body = '## đź”’ Security Scan Results\\n\\n';
body += '### Bandit (SAST)\\n';
body += `- ${(parseJsonSafe('bandit-report.json').metrics || {})['SEVERITY.HIGH'] || 0} HIGH severity issues\\n\\n`;
body += '### Safety (Dependencies)\\n';
body += `- ${(parseJsonSafe('safety-report.json').vulnerabilities || []).length || 0} known vulnerabilities\\n\\n`;
body += '### Pip-audit (Dependencies)\\n';
body += `- ${(parseJsonSafe('pip-audit-report.json').dependencies || []).filter(d => d.vulnerabilities?.length)?.length || 0} vulnerable packages\\n`;
core.summary.addHeading('đź”’ Security Scan Results');
core.summary.addRaw(body);
core.summary.write();
github-token: ${{ secrets.GITHUB_TOKEN }}
lint:
name: Code Quality
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install linting tools
run: |
python -m pip install ruff black mypy
- name: Run Ruff (Fast Python Linter)
run: |
ruff check src/ tests/ --output-format=github
continue-on-error: true
- name: Check formatting (Black)
run: |
black --check src/ tests/ --diff
continue-on-error: true
- name: Type checking (MyPy)
run: |
mypy src/ --ignore-missing-imports || true
continue-on-error: true
build:
name: Build Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[gguf]"
- name: Verify import
run: |
python -c "import ledgermind; print('âś“ Imports work')"
- name: Create distribution
run: |
pip install build
python -m build