chore(deps): bump actions/checkout from 4 to 5 #10
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI (uv) | |
| on: | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| branches: [ main ] | |
| jobs: | |
| test: | |
| name: Test / Lint / Typecheck (uv) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.11", "3.12", "3.13", "3.14"] | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| enable-cache: true | |
| - name: Set up Python ${{ matrix.python-version }} | |
| run: uv python install ${{ matrix.python-version }} | |
| - name: Sync dependencies with uv | |
| run: uv sync --all-extras | |
| - name: Lint (ruff) | |
| run: uv run ruff check python_project_deployment | |
| - name: Typecheck (mypy) | |
| run: uv run mypy python_project_deployment | |
| - name: Tests (pytest) | |
| run: uv run pytest --cov --cov-report=xml --cov-report=html | |
| - name: Security scan for dangerous APIs | |
| run: | | |
| set -euo pipefail | |
| if grep -R --line-number -E "\beval\(|\bexec\(|pickle\.loads|yaml\.load|subprocess\.(Popen|call)" python_project_deployment/ tests/ || true; then | |
| echo "⚠️ Potentially dangerous API usage detected. Please review before merging." >&2 | |
| exit 2 | |
| fi | |
| continue-on-error: true | |
| - name: Upload coverage.xml | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-${{ matrix.python-version }} | |
| path: coverage.xml | |
| - name: Upload coverage HTML | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-html-${{ matrix.python-version }} | |
| path: htmlcov | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| env: | |
| SECURITY_FAIL_LEVEL: MEDIUM | |
| steps: | |
| - uses: actions/checkout@v5 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v4 | |
| with: | |
| enable-cache: true | |
| - name: Set up Python 3.11 | |
| run: uv python install 3.11 | |
| - name: Sync deps and install security tools | |
| run: | | |
| uv sync --all-extras | |
| uv pip install bandit safety | |
| - name: Run Bandit and export SARIF | |
| run: | | |
| uv run bandit -r python_project_deployment/ -f json -o bandit-report.json | |
| uv run bandit -r python_project_deployment/ -f sarif -o bandit-report.sarif | |
| continue-on-error: true | |
| - name: Upload Bandit SARIF to GitHub Code Scanning | |
| uses: github/codeql-action/upload-sarif@v3 | |
| with: | |
| sarif_file: bandit-report.sarif | |
| continue-on-error: true | |
| - name: Run Safety (fail on any vulnerability) | |
| run: | | |
| uv run safety check --json > safety-report.json || true | |
| python - <<'PY' | |
| import json,sys,os | |
| try: | |
| data=json.load(open('safety-report.json')) | |
| if data.get('vulnerabilities'): | |
| print('Safety reported vulnerabilities') | |
| sys.exit(2) | |
| print('No safety vulnerabilities') | |
| except Exception as e: | |
| print(f'Error parsing safety output: {e}') | |
| sys.exit(0) | |
| PY | |
| continue-on-error: true | |
| - name: Apply Bandit threshold | |
| run: | | |
| python - <<'PY' | |
| import json,sys,os | |
| level=os.environ.get('SECURITY_FAIL_LEVEL','MEDIUM').upper() | |
| try: | |
| data=json.load(open('bandit-report.json')) | |
| sevs=[issue.get('issue_severity','') for issue in data.get('results',[])] | |
| if level=='NONE': | |
| print('SECURITY_FAIL_LEVEL=NONE: not failing on bandit issues') | |
| sys.exit(0) | |
| if level=='HIGH': | |
| if 'HIGH' in sevs: | |
| print('Failing on HIGH bandit issues') | |
| sys.exit(2) | |
| else: | |
| print('No HIGH bandit issues') | |
| sys.exit(0) | |
| if level=='MEDIUM': | |
| if any(s in ('HIGH','MEDIUM') for s in sevs): | |
| print('Failing on MEDIUM or HIGH bandit issues') | |
| sys.exit(2) | |
| else: | |
| print('No MEDIUM/HIGH bandit issues') | |
| sys.exit(0) | |
| print('Unknown SECURITY_FAIL_LEVEL:', level) | |
| sys.exit(1) | |
| except Exception as e: | |
| print(f'Error parsing bandit report: {e}') | |
| sys.exit(0) | |
| PY | |
| continue-on-error: true | |
| - name: Upload security reports | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: security-reports | |
| path: | | |
| bandit-report.json | |
| bandit-report.sarif | |
| safety-report.json | |
| if data.get('vulnerabilities'): |