Skip to content

feat: critical security hardening for THUNES workflows (#1) #9

feat: critical security hardening for THUNES workflows (#1)

feat: critical security hardening for THUNES workflows (#1) #9

Workflow file for this run

name: CI
# ENFORCEMENT POLICY (Phase 13 Sprint 1.13):
# All quality gates MUST pass before merge. Failures block merges to protect main branch.
# - Ruff linting (code style)
# - Black formatting (consistent formatting)
# - Mypy type checking (type safety)
# - Pytest (205+/228 tests passing)
# This prevents the documentation drift that allowed broken tests to reach main.
permissions:
contents: read # Default read-only (elevated permissions granted per-job)
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint-and-test:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read # Checkout code
pull-requests: write # Codecov PR comments
actions: write # Enable pip cache save/restore
strategy:
matrix:
python-version: ["3.12"]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a20 # v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies (with retry)
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3
with:
timeout_minutes: 5
max_attempts: 3
retry_wait_seconds: 30
command: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
# Note: Using requirements-dev.txt (core + testing/linting only)
# This reduces CI build time from ~10 min to ~2-3 min by excluding
# heavy research dependencies (vectorbt, optuna, matplotlib, jupyter)
- name: Run ruff (linting)
run: |
ruff check src tests
if [ $? -ne 0 ]; then
echo "::error::Ruff linting failed - fix issues before merge"
exit 1
fi
- name: Run black (formatting check)
run: |
black --check src tests
if [ $? -ne 0 ]; then
echo "::error::Black formatting check failed - run 'make format' to fix"
exit 1
fi
- name: Run mypy (type checking)
run: |
mypy src
if [ $? -ne 0 ]; then
echo "::error::Type checking failed - fix type hints before merge"
exit 1
fi
- name: Run tests with coverage
run: |
set -e # Exit immediately on test failure
pytest -v --cov=src --cov-report=xml --cov-report=term-missing
# Explicit exit code check (pytest returns non-zero on failures)
if [ $? -ne 0 ]; then
echo "::error::Tests failed - blocking merge to protect main branch"
exit 1
fi
- name: Verify test passage (deployment gate)
if: always()
run: |
if [ ! -f coverage.xml ]; then
echo "::error::No coverage report generated - tests may have crashed"
exit 1
fi
echo "✅ Tests passed - deployment gate satisfied"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@edd20798ab377991aad21abfb1f2d5e093b681e8 # v4.0.0
with:
file: ./coverage.xml
fail_ci_if_error: false