Skip to content

Merge pull request #90 from Gavin-Borges/dependabot/github_actions/gi… #239

Merge pull request #90 from Gavin-Borges/dependabot/github_actions/gi…

Merge pull request #90 from Gavin-Borges/dependabot/github_actions/gi… #239

Workflow file for this run

name: SESTRAV CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions: read-all
jobs:
lint:
# Coding-standards gate (OpenSSF Silver: coding_standards_enforced).
# PEP 8 enforced automatically via Ruff; config lives in pyproject.toml.
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
- name: Install Ruff
# Hash-pinned (OpenSSF Scorecard Pinned-Dependencies). Regenerate with:
# pip-compile --generate-hashes environments/requirements-ci-ruff.in \
# --output-file environments/requirements-ci-ruff.txt --no-emit-index-url
run: pip install --require-hashes -r environments/requirements-ci-ruff.txt
- name: Ruff lint (coding standards)
run: ruff check .
compat:
# Lightweight Python-version compatibility check (OpenSSF Silver: works_as_advertised).
# Verifies non-torch imports on 3.11/3.12; torch+GNN coverage is the 3.13 test job.
# PyTorch wheels are not installed here: torch imports in src/ are inside functions,
# so the compat smoke-test exercises the module boundary without a 200 MB wheel download.
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install --no-deps --require-hashes -r requirements.txt
pip install --no-deps --require-hashes -r environments/requirements-ci.txt
- name: Smoke-test import
run: python -c "import src.features; import src.model; print('import OK')"
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.13"]
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ matrix.python-version }}
- name: Install CPU PyTorch
run: |
pip install --no-deps --require-hashes -r environments/requirements-ci-torch-cpu.txt \
--index-url https://download.pytorch.org/whl/cpu
- name: Install dependencies
run: |
pip install --no-deps --require-hashes -r requirements.txt
pip install --no-deps --require-hashes -r environments/requirements-ci.txt
- name: Verify MHCflurry model version pin
# Binding features change across MHCflurry releases; silent drift invalidates training checksums.
# config.yaml mhcflurry_model_version must match the installed version.
run: |
PINNED=$(python -c "import yaml; c=yaml.safe_load(open('config.yaml')); print(c['mhcflurry_model_version'])")
INSTALLED=$(python -c "import mhcflurry; print(mhcflurry.__version__)")
echo "Pinned: $PINNED | Installed: $INSTALLED"
if [ "$PINNED" != "$INSTALLED" ]; then
echo "ERROR: MHCflurry version mismatch - update mhcflurry_model_version in config.yaml"
exit 1
fi
- name: Install coverage tooling
# pytest-cov is a test-only tool, layered on top of the hash-pinned
# runtime deps installed above (OpenSSF Silver test_statement_coverage80).
# Hash-pinned (OpenSSF Scorecard Pinned-Dependencies). Regenerate with:
# pip-compile --generate-hashes environments/requirements-ci-pytest-cov.in \
# --output-file environments/requirements-ci-pytest-cov.txt --no-emit-index-url
run: pip install --require-hashes -r environments/requirements-ci-pytest-cov.txt
- name: Verify library-coverage scope is in sync
# The OpenSSF Silver coverage scope omits executable scripts objectively
# (presence of a __main__ guard). Fail fast if .coveragerc.library has
# drifted from the source tree.
run: python tools/check_library_coverage.py --check
- name: Run tests with coverage (OpenSSF Silver test_statement_coverage80)
# Statement + branch coverage on the importable LIBRARY surface, gated at
# fail_under=95 via .coveragerc.library (executable research/pipeline
# scripts are validated by the integration/data gates below, not unit
# coverage). The whole-repo regression floor lives in pyproject.toml for
# local `pytest --cov` runs. PYTHONPATH + COVERAGE_PROCESS_START activate
# the tools/coverage_subprocess hook so child-process modules are counted.
env:
PYTHONPATH: ${{ github.workspace }}/tools/coverage_subprocess
COVERAGE_PROCESS_START: ${{ github.workspace }}/.coveragerc.library
run: >-
python -m pytest tests/ -v
--cov=src --cov=functions
--cov-config=.coveragerc.library
--cov-report=term-missing --cov-report=xml
- name: Run Dataset Curation QC Gate
run: python scripts/data_qc_gate.py --dataset data/immunogenicity_dataset_v3.csv --config config.yaml
- name: Run Contamination and Benchmark Evaluation Gate
run: python scripts/benchmark_runner.py --tier A --run-id ci_dryrun --skip-freeze-check
- name: Validate Snakemake pipeline wiring
run: snakemake --snakefile pipeline.smk --dry-run --cores 1
- name: Set up Quarto
uses: quarto-dev/quarto-actions/setup@8a96df13519ee81fd526f2dfca5962811136661b # v2.2.0
- name: Install Quarto rendering dependencies
# Jupyter execution stack needed to run the report's {python} cells.
# Hash-locked separately from the runtime lockfiles (render-only deps).
run: pip install --require-hashes -r environments/requirements-ci-render.txt
- name: Render Quarto Report
# --execute-dir . keeps the Python kernel's working directory at the
# repo root so that `from src.xxx import ...` resolves correctly.
run: quarto render docs/results_report.qmd --execute-dir .