From 794a37ccf3d331a163d5b621acacb60bf7c10113 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Fri, 25 Sep 2026 11:24:10 +0100 Subject: [PATCH 01/13] tests: split test suite into `tests/unit` and `tests/regression` --- tests/{ => regression}/conftest.py | 8 ++++++-- tests/{ => regression}/data/pbr322.toy.fa | 0 tests/{ => regression}/reference/v1.0.0/README.md | 0 .../reference/v1.0.0/competition.inherited.txt | 0 .../reference/v1.0.0/competition.rebuilt.txt | 0 tests/{ => regression}/reference/v1.0.0/cruciform.txt | 0 tests/{ => regression}/reference/v1.0.0/melting.txt | 0 tests/{ => regression}/reference/v1.0.0/z-dna.txt | 0 tests/{ => regression}/test_cli.py | 0 tests/{ => regression}/test_legacy_entrypoints.py | 4 ++-- tests/{ => regression}/test_regression.py | 8 +------- tests/{ => unit}/test_energetics.py | 0 tests/{ => unit}/test_ir_finder.py | 0 13 files changed, 9 insertions(+), 11 deletions(-) rename tests/{ => regression}/conftest.py (93%) rename tests/{ => regression}/data/pbr322.toy.fa (100%) rename tests/{ => regression}/reference/v1.0.0/README.md (100%) rename tests/{ => regression}/reference/v1.0.0/competition.inherited.txt (100%) rename tests/{ => regression}/reference/v1.0.0/competition.rebuilt.txt (100%) rename tests/{ => regression}/reference/v1.0.0/cruciform.txt (100%) rename tests/{ => regression}/reference/v1.0.0/melting.txt (100%) rename tests/{ => regression}/reference/v1.0.0/z-dna.txt (100%) rename tests/{ => regression}/test_cli.py (100%) rename tests/{ => regression}/test_legacy_entrypoints.py (95%) rename tests/{ => regression}/test_regression.py (98%) rename tests/{ => unit}/test_energetics.py (100%) rename tests/{ => unit}/test_ir_finder.py (100%) diff --git a/tests/conftest.py b/tests/regression/conftest.py similarity index 93% rename from tests/conftest.py rename to tests/regression/conftest.py index 09632e9..234dff2 100644 --- a/tests/conftest.py +++ b/tests/regression/conftest.py @@ -9,7 +9,7 @@ import pytest -REPOSITORY_ROOT = Path(__file__).resolve().parents[1] +REPOSITORY_ROOT = Path(__file__).resolve().parents[2] SIST_TRANSITIONS = ( pytest.param(("melting", "M"), id="melting"), @@ -136,6 +136,10 @@ def sist_command( During conda-build testing, use the installed console script. Otherwise run `python -m sist` against the maintained source tree, with its qsidd binaries resolved via env vars pointing at a freshly built copy. + + `built_sist_copy` is looked up lazily (rather than taken as a normal + fixture parameter) so conda-build testing never triggers it: that build + only has `tests/` and `pyproject.toml` available, not the C++ sources. """ if os.environ.get("CONDA_BUILD_STATE") == "TEST": @@ -172,7 +176,7 @@ def run_sist_calculation( runtime_directory = tmp_path_factory.mktemp(f"sist-{name}") - source_input = REPOSITORY_ROOT / "tests" / "data" / "pbr322.toy.fa" + source_input = Path(__file__).resolve().parent / "data" / "pbr322.toy.fa" runtime_input = runtime_directory / "pbr322.toy.fa" shutil.copy2(source_input, runtime_input) diff --git a/tests/data/pbr322.toy.fa b/tests/regression/data/pbr322.toy.fa similarity index 100% rename from tests/data/pbr322.toy.fa rename to tests/regression/data/pbr322.toy.fa diff --git a/tests/reference/v1.0.0/README.md b/tests/regression/reference/v1.0.0/README.md similarity index 100% rename from tests/reference/v1.0.0/README.md rename to tests/regression/reference/v1.0.0/README.md diff --git a/tests/reference/v1.0.0/competition.inherited.txt b/tests/regression/reference/v1.0.0/competition.inherited.txt similarity index 100% rename from tests/reference/v1.0.0/competition.inherited.txt rename to tests/regression/reference/v1.0.0/competition.inherited.txt diff --git a/tests/reference/v1.0.0/competition.rebuilt.txt b/tests/regression/reference/v1.0.0/competition.rebuilt.txt similarity index 100% rename from tests/reference/v1.0.0/competition.rebuilt.txt rename to tests/regression/reference/v1.0.0/competition.rebuilt.txt diff --git a/tests/reference/v1.0.0/cruciform.txt b/tests/regression/reference/v1.0.0/cruciform.txt similarity index 100% rename from tests/reference/v1.0.0/cruciform.txt rename to tests/regression/reference/v1.0.0/cruciform.txt diff --git a/tests/reference/v1.0.0/melting.txt b/tests/regression/reference/v1.0.0/melting.txt similarity index 100% rename from tests/reference/v1.0.0/melting.txt rename to tests/regression/reference/v1.0.0/melting.txt diff --git a/tests/reference/v1.0.0/z-dna.txt b/tests/regression/reference/v1.0.0/z-dna.txt similarity index 100% rename from tests/reference/v1.0.0/z-dna.txt rename to tests/regression/reference/v1.0.0/z-dna.txt diff --git a/tests/test_cli.py b/tests/regression/test_cli.py similarity index 100% rename from tests/test_cli.py rename to tests/regression/test_cli.py diff --git a/tests/test_legacy_entrypoints.py b/tests/regression/test_legacy_entrypoints.py similarity index 95% rename from tests/test_legacy_entrypoints.py rename to tests/regression/test_legacy_entrypoints.py index 4a9f141..9bbe9c6 100644 --- a/tests/test_legacy_entrypoints.py +++ b/tests/regression/test_legacy_entrypoints.py @@ -12,7 +12,6 @@ from pathlib import Path import pytest -from conftest import REPOSITORY_ROOT pytestmark = pytest.mark.regression @@ -41,7 +40,8 @@ def test_master_pl_alias_matches_sist_output( runtime_directory = tmp_path_factory.mktemp("master-pl-alias") input_path = runtime_directory / "pbr322.toy.fa" - shutil.copy2(REPOSITORY_ROOT / "tests" / "data" / "pbr322.toy.fa", input_path) + data_path = Path(__file__).resolve().parent / "data" / "pbr322.toy.fa" + shutil.copy2(data_path, input_path) result = subprocess.run( ["master.pl", "-f", input_path.name, "-a", "M", "-b", "-p", "-r"], diff --git a/tests/test_regression.py b/tests/regression/test_regression.py similarity index 98% rename from tests/test_regression.py rename to tests/regression/test_regression.py index 8ae18da..29d1e0a 100644 --- a/tests/test_regression.py +++ b/tests/regression/test_regression.py @@ -11,15 +11,9 @@ pytestmark = pytest.mark.regression -REPOSITORY_ROOT = Path(__file__).resolve().parents[1] REFERENCE_VERSION = "v1.0.0" -REFERENCE_DIRECTORY = ( - REPOSITORY_ROOT - / "tests" - / "reference" - / REFERENCE_VERSION -) +REFERENCE_DIRECTORY = Path(__file__).resolve().parent / "reference" / REFERENCE_VERSION COMPETITION_REFERENCE = ( REFERENCE_DIRECTORY diff --git a/tests/test_energetics.py b/tests/unit/test_energetics.py similarity index 100% rename from tests/test_energetics.py rename to tests/unit/test_energetics.py diff --git a/tests/test_ir_finder.py b/tests/unit/test_ir_finder.py similarity index 100% rename from tests/test_ir_finder.py rename to tests/unit/test_ir_finder.py From a2ef3414b56af8b059f93c9f98738057822ce661 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Fri, 25 Sep 2026 11:48:19 +0100 Subject: [PATCH 02/13] ci: add daily unit tests, weekly docs build, and coverage reporting --- .github/workflows/coveralls-main.yaml | 54 +++++++++++++++++++ .github/workflows/daily.yaml | 38 +++++++++++++ ...pdate-copyright-years-in-license-file.yaml | 17 ++++++ .github/workflows/weekly-docs.yaml | 47 ++++++++++++++++ .gitignore | 4 ++ pyproject.toml | 1 + 6 files changed, 161 insertions(+) create mode 100644 .github/workflows/coveralls-main.yaml create mode 100644 .github/workflows/daily.yaml create mode 100644 .github/workflows/update-copyright-years-in-license-file.yaml create mode 100644 .github/workflows/weekly-docs.yaml diff --git a/.github/workflows/coveralls-main.yaml b/.github/workflows/coveralls-main.yaml new file mode 100644 index 0000000..b9d9ac6 --- /dev/null +++ b/.github/workflows/coveralls-main.yaml @@ -0,0 +1,54 @@ +name: Coveralls Main + +on: + push: + branches: [main] + + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: coveralls-main-${{ github.ref }} + cancel-in-progress: true + +jobs: + coveralls: + name: Build main coverage baseline + runs-on: ubuntu-24.04 + timeout-minutes: 30 + + permissions: + contents: read + checks: write + statuses: write + + steps: + - name: Checkout + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + + - name: Set up Python 3.14 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + with: + python-version: "3.14" + + - name: Install testing dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -e .[testing] + + - name: Run coverage + run: | + python -m pytest tests/unit \ + --cov sist \ + --cov-report term-missing \ + --cov-report xml \ + -q + + - name: Upload coverage to Coveralls + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + file: coverage.xml + fail-on-error: false diff --git a/.github/workflows/daily.yaml b/.github/workflows/daily.yaml new file mode 100644 index 0000000..9e8458b --- /dev/null +++ b/.github/workflows/daily.yaml @@ -0,0 +1,38 @@ +name: Daily Unit Tests + +on: + schedule: + - cron: '0 8 * * 1-5' + workflow_dispatch: + +concurrency: + group: daily-${{ github.ref }} + cancel-in-progress: true + +jobs: + unit: + name: Unit (py${{ matrix.python-version }}) + runs-on: ubuntu-24.04 + timeout-minutes: 30 + + strategy: + fail-fast: false + matrix: + python-version: ["3.12", "3.13", "3.14"] + + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: ${{ matrix.python-version }} + + - name: Install testing dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -e .[testing] + + - name: Run unit tests + run: python -m pytest tests/unit diff --git a/.github/workflows/update-copyright-years-in-license-file.yaml b/.github/workflows/update-copyright-years-in-license-file.yaml new file mode 100644 index 0000000..a252dd5 --- /dev/null +++ b/.github/workflows/update-copyright-years-in-license-file.yaml @@ -0,0 +1,17 @@ +name: Update copyright year(s) in license file + +on: + schedule: + - cron: '0 3 1 1 *' # 03:00 AM on January 1 + workflow_dispatch: + +jobs: + update-license-year: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + with: + fetch-depth: 0 + - uses: FantasticFiasco/action-update-license-year@f180e962fa988db222d8f03ef4636750312d1b3d # v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/weekly-docs.yaml b/.github/workflows/weekly-docs.yaml new file mode 100644 index 0000000..30d0eda --- /dev/null +++ b/.github/workflows/weekly-docs.yaml @@ -0,0 +1,47 @@ +name: Weekly Docs Build + +on: + schedule: + - cron: '0 8 * * 1' + workflow_dispatch: + +concurrency: + group: weekly-docs-${{ github.ref }} + cancel-in-progress: true + +jobs: + docs: + name: Docs build (python ${{ matrix.python-version }}) + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + python-version: ["3.12", "3.13", "3.14"] + timeout-minutes: 30 + + steps: + - name: Checkout repo + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: ${{ matrix.python-version }} + + - name: Install python dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -r docs/requirements.txt + + - name: Build docs (warnings as errors) + run: | + make -C docs clean + make -C docs html SPHINXOPTS="-W --keep-going" + + - name: Upload docs artifacts on failure + if: failure() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 + with: + name: docs-py${{ matrix.python-version }}-failure + path: | + docs/build/** diff --git a/.gitignore b/.gitignore index b855c85..5ae4d20 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,10 @@ __pycache__/ .ruff_cache/ *.egg-info/ +# Coverage +.coverage +coverage.xml + # Regression test artefacts .testdata/ test-results/ \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f2fab85..579aa2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ sist = "sist.cli:main" [project.optional-dependencies] testing = [ "pytest>=9.0,<10.0", + "pytest-cov>=7.0,<8.0", "mypy>=1.14,<2.0", ] From 1432dc79773d9434ad4bc2956f60f790118eb30a Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Fri, 25 Sep 2026 12:22:07 +0100 Subject: [PATCH 03/13] ci: split pr.yaml into unit/regression jobs and add C++ coverage reporting --- .github/workflows/coveralls-main.yaml | 95 ++++++++++++++++++- .github/workflows/pr.yaml | 70 +++++++++++++- ...sion-tests.yaml => weekly-regression.yaml} | 5 +- .gitignore | 5 + README.md | 5 +- conda-recipe/run_test.sh | 2 +- src/trans_compete/Makefile | 3 + src/trans_three/Makefile | 3 + 8 files changed, 178 insertions(+), 10 deletions(-) rename .github/workflows/{regression-tests.yaml => weekly-regression.yaml} (95%) diff --git a/.github/workflows/coveralls-main.yaml b/.github/workflows/coveralls-main.yaml index b9d9ac6..e3bf3d2 100644 --- a/.github/workflows/coveralls-main.yaml +++ b/.github/workflows/coveralls-main.yaml @@ -14,8 +14,8 @@ concurrency: cancel-in-progress: true jobs: - coveralls: - name: Build main coverage baseline + python-coverage: + name: Build main coverage baseline (Python) runs-on: ubuntu-24.04 timeout-minutes: 30 @@ -51,4 +51,95 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} file: coverage.xml + flag-name: python + parallel: true fail-on-error: false + + cpp-coverage: + name: Build main coverage baseline (C++) + runs-on: ubuntu-24.04 + timeout-minutes: 30 + + permissions: + contents: read + checks: write + statuses: write + + steps: + - name: Checkout + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + + - name: Set up Python 3.14 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + with: + python-version: "3.14" + + - name: Setup Conda (for irf only) + uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4 + with: + miniforge-variant: Miniforge3 + auto-activate: true + activate-environment: base + conda-remove-defaults: true + channels: conda-forge,bioconda + channel-priority: strict + + - name: Install irf + shell: bash -l {0} + run: | + conda install -y \ + --override-channels \ + -c bioconda \ + -c conda-forge \ + "irf>=3.09,<3.10" + + - name: Install sist and coverage tooling + shell: bash -l {0} + run: | + python -m pip install --upgrade pip + python -m pip install -e .[testing] + python -m pip install gcovr + + - name: Build qsidd with coverage instrumentation + run: | + make -C src/trans_three clean + make -C src/trans_three coverage + make -C src/trans_compete clean + make -C src/trans_compete coverage + + - name: Run regression tests against instrumented binaries + shell: bash -l {0} + env: + CONDA_BUILD_STATE: TEST + SIST_TRANS_THREE_BIN: ${{ github.workspace }}/src/trans_three/qsidd + SIST_TRANS_COMPETE_BIN: ${{ github.workspace }}/src/trans_compete/qsidd + run: python -m pytest tests/regression -vv + + - name: Generate lcov report + run: | + gcovr --root . \ + --filter 'src/trans_three/.*' \ + --filter 'src/trans_compete/.*' \ + --gcov-ignore-parse-errors=suspicious_hits.warn \ + --lcov coverage.info + + - name: Upload coverage to Coveralls + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: coverage.info + flag-name: cpp + parallel: true + fail-on-error: false + + finish: + name: Close Coveralls build + needs: [python-coverage, cpp-coverage] + runs-on: ubuntu-24.04 + + steps: + - name: Close parallel build + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + parallel-finished: true diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 106b2f6..5680da4 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -11,6 +11,33 @@ concurrency: cancel-in-progress: true jobs: + unit: + name: Unit (py${{ matrix.python-version }}) + runs-on: ubuntu-24.04 + timeout-minutes: 15 + + strategy: + fail-fast: false + matrix: + python-version: ["3.12", "3.13", "3.14"] + + steps: + - name: Checkout + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + with: + python-version: ${{ matrix.python-version }} + + - name: Install testing dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -e .[testing] + + - name: Run unit tests + run: python -m pytest tests/unit + regression: name: Regression runs-on: ubuntu-24.04 @@ -78,4 +105,45 @@ jobs: name: docs-html path: docs/build/html/ if-no-files-found: error - retention-days: 7 \ No newline at end of file + retention-days: 7 + + coverage: + name: Coverage + needs: unit + runs-on: ubuntu-24.04 + timeout-minutes: 30 + + permissions: + contents: read + checks: write + statuses: write + pull-requests: write + + steps: + - name: Checkout + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + + - name: Set up Python 3.14 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 + with: + python-version: "3.14" + + - name: Install testing dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -e .[testing] + + - name: Run coverage + run: | + python -m pytest tests/unit \ + --cov sist \ + --cov-report term-missing \ + --cov-report xml \ + -q + + - name: Upload coverage to Coveralls + uses: coverallsapp/github-action@5cbfd81b66ca5d10c19b062c04de0199c215fb6e + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + file: coverage.xml + fail-on-error: false \ No newline at end of file diff --git a/.github/workflows/regression-tests.yaml b/.github/workflows/weekly-regression.yaml similarity index 95% rename from .github/workflows/regression-tests.yaml rename to .github/workflows/weekly-regression.yaml index d046ca2..9d07a6d 100644 --- a/.github/workflows/regression-tests.yaml +++ b/.github/workflows/weekly-regression.yaml @@ -1,9 +1,6 @@ -name: Regression Tests +name: Weekly Regression Tests on: - push: - branches: - - main schedule: - cron: "0 8 * * 1" workflow_dispatch: diff --git a/.gitignore b/.gitignore index 5ae4d20..4753c57 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,11 @@ src/trans_compete/depend # Debug information files *.dwo +# gcov/lcov coverage instrumentation and reports +*.gcno +*.gcda +coverage.info + # Build directories build/ dist/ diff --git a/README.md b/README.md index 651f0b0..217c1b8 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,9 @@ SIST: Stress-Induced Structural Transitions in superhelical DNA | Category | Badges | |----------------|--------| -| **Build** | [![PR Checks](https://github.com/CCPBioSim/SIST/actions/workflows/pr.yaml/badge.svg)](https://github.com/CCPBioSim/SIST/actions/workflows/pr.yaml) | -| **Documentation** | [![Docs - Status](https://app.readthedocs.org/projects/sist/badge/?version=latest)](https://sist.readthedocs.io/en/latest/?badge=latest) | +| **Build** | [![PR Checks](https://github.com/CCPBioSim/SIST/actions/workflows/pr.yaml/badge.svg)](https://github.com/CCPBioSim/SIST/actions/workflows/pr.yaml) [![Daily Tests](https://github.com/CCPBioSim/SIST/actions/workflows/daily.yaml/badge.svg)](https://github.com/CCPBioSim/SIST/actions/workflows/daily.yaml) | +| **Regression** | [![Weekly Regression](https://github.com/CCPBioSim/SIST/actions/workflows/weekly-regression.yaml/badge.svg)](https://github.com/CCPBioSim/SIST/actions/workflows/weekly-regression.yaml) | +| **Documentation** | [![Weekly Docs](https://github.com/CCPBioSim/SIST/actions/workflows/weekly-docs.yaml/badge.svg)](https://github.com/CCPBioSim/SIST/actions/workflows/weekly-docs.yaml) [![Docs - Status](https://app.readthedocs.org/projects/sist/badge/?version=latest)](https://sist.readthedocs.io/en/latest/?badge=latest) | | **Citation** | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.22753478.svg)](https://doi.org/10.5281/zenodo.22753478) | | **Anaconda** | [![Anaconda.org](https://anaconda.org/CCPBioSim/sist/badges/version.svg)](https://anaconda.org/CCPBioSim/sist/) [![Last Updated](https://anaconda.org/CCPBioSim/sist/badges/latest_release_date.svg)](https://anaconda.org/CCPBioSim/sist) [![Platforms](https://anaconda.org/CCPBioSim/sist/badges/platforms.svg)](https://anaconda.org/CCPBioSim/sist) [![License](https://anaconda.org/CCPBioSim/sist/badges/license.svg)](https://anaconda.org/CCPBioSim/sist) [![Downloads](https://anaconda.org/CCPBioSim/sist/badges/downloads.svg)](https://anaconda.org/CCPBioSim/sist)| | **Quality** | [![Coverage Status](https://coveralls.io/repos/github/CCPBioSim/SIST/badge.svg?branch=main)](https://coveralls.io/github/CCPBioSim/SIST?branch=main) | diff --git a/conda-recipe/run_test.sh b/conda-recipe/run_test.sh index 62d6569..8728dc5 100755 --- a/conda-recipe/run_test.sh +++ b/conda-recipe/run_test.sh @@ -6,4 +6,4 @@ command -v irf command -v python command -v pytest -python -m pytest tests -vv +python -m pytest tests/regression -vv diff --git a/src/trans_compete/Makefile b/src/trans_compete/Makefile index 703b15c..93b2108 100644 --- a/src/trans_compete/Makefile +++ b/src/trans_compete/Makefile @@ -54,6 +54,9 @@ tar: gcc: make $(APP) CC="$(CXX)" CPPFLAGS="-O2 -Wall" +coverage: + make $(APP) CC="$(CXX)" CPPFLAGS="-O0 -Wall --coverage -fprofile-abs-path" LDFLAGS="--coverage" + ################### # Inference Rules # diff --git a/src/trans_three/Makefile b/src/trans_three/Makefile index 06b0afe..1908f1d 100644 --- a/src/trans_three/Makefile +++ b/src/trans_three/Makefile @@ -54,6 +54,9 @@ tar: gcc: make $(APP) CC="$(CXX)" CPPFLAGS="-O2 -Wall " +coverage: + make $(APP) CC="$(CXX)" CPPFLAGS="-O0 -Wall --coverage -fprofile-abs-path" LDFLAGS="--coverage" + ################### # Inference Rules # From d2c6e381bf98fb6e6ca4282f901f78bb5acce02d Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Fri, 25 Sep 2026 13:52:16 +0100 Subject: [PATCH 04/13] tests: update comments within `regression/conftest.py` --- tests/regression/conftest.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/regression/conftest.py b/tests/regression/conftest.py index 234dff2..d5854a7 100644 --- a/tests/regression/conftest.py +++ b/tests/regression/conftest.py @@ -136,10 +136,6 @@ def sist_command( During conda-build testing, use the installed console script. Otherwise run `python -m sist` against the maintained source tree, with its qsidd binaries resolved via env vars pointing at a freshly built copy. - - `built_sist_copy` is looked up lazily (rather than taken as a normal - fixture parameter) so conda-build testing never triggers it: that build - only has `tests/` and `pyproject.toml` available, not the C++ sources. """ if os.environ.get("CONDA_BUILD_STATE") == "TEST": From 825233eb35246f1638fcac60d4b9912a4b93e462 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 09:23:26 +0100 Subject: [PATCH 05/13] chore(workflows): update all workflows to use new `ubuntu-26.04` images --- .github/workflows/coveralls-main.yaml | 6 +++--- .github/workflows/daily.yaml | 2 +- .github/workflows/pr.yaml | 4 ++-- .github/workflows/weekly-docs.yaml | 2 +- .readthedocs.yaml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coveralls-main.yaml b/.github/workflows/coveralls-main.yaml index e3bf3d2..3186354 100644 --- a/.github/workflows/coveralls-main.yaml +++ b/.github/workflows/coveralls-main.yaml @@ -16,7 +16,7 @@ concurrency: jobs: python-coverage: name: Build main coverage baseline (Python) - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 timeout-minutes: 30 permissions: @@ -57,7 +57,7 @@ jobs: cpp-coverage: name: Build main coverage baseline (C++) - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 timeout-minutes: 30 permissions: @@ -135,7 +135,7 @@ jobs: finish: name: Close Coveralls build needs: [python-coverage, cpp-coverage] - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 steps: - name: Close parallel build diff --git a/.github/workflows/daily.yaml b/.github/workflows/daily.yaml index 9e8458b..01a5343 100644 --- a/.github/workflows/daily.yaml +++ b/.github/workflows/daily.yaml @@ -12,7 +12,7 @@ concurrency: jobs: unit: name: Unit (py${{ matrix.python-version }}) - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 timeout-minutes: 30 strategy: diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index f0b6054..dbd8407 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -13,7 +13,7 @@ concurrency: jobs: unit: name: Unit (py${{ matrix.python-version }}) - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 timeout-minutes: 15 strategy: @@ -115,7 +115,7 @@ jobs: coverage: name: Coverage needs: unit - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 timeout-minutes: 30 permissions: diff --git a/.github/workflows/weekly-docs.yaml b/.github/workflows/weekly-docs.yaml index 30d0eda..9a913b7 100644 --- a/.github/workflows/weekly-docs.yaml +++ b/.github/workflows/weekly-docs.yaml @@ -12,7 +12,7 @@ concurrency: jobs: docs: name: Docs build (python ${{ matrix.python-version }}) - runs-on: ubuntu-24.04 + runs-on: ubuntu-26.04 strategy: fail-fast: false matrix: diff --git a/.readthedocs.yaml b/.readthedocs.yaml index db69c29..87e396c 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -6,7 +6,7 @@ version: 2 # Set the OS, Python version, and other tools you might need build: - os: ubuntu-24.04 + os: ubuntu-26.04 tools: python: "3.13" From 5184f25c9d071ae09dae4a75ec0981434c2e4267 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 09:37:57 +0100 Subject: [PATCH 06/13] chore(workflows): matrix regression tests across all supported python versions --- .github/workflows/daily.yaml | 5 +++-- .github/workflows/pr.yaml | 9 ++++++--- .github/workflows/weekly-regression.yaml | 4 +++- conda-recipe/meta.yaml | 2 +- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/daily.yaml b/.github/workflows/daily.yaml index 01a5343..c1e2da3 100644 --- a/.github/workflows/daily.yaml +++ b/.github/workflows/daily.yaml @@ -11,13 +11,14 @@ concurrency: jobs: unit: - name: Unit (py${{ matrix.python-version }}) - runs-on: ubuntu-26.04 + name: Unit (${{ matrix.os }}, py${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} timeout-minutes: 30 strategy: fail-fast: false matrix: + os: [ubuntu-26.04, macos-26-intel, macos-26] python-version: ["3.12", "3.13", "3.14"] steps: diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index dbd8407..e859677 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -12,13 +12,14 @@ concurrency: jobs: unit: - name: Unit (py${{ matrix.python-version }}) - runs-on: ubuntu-26.04 + name: Unit (${{ matrix.os }}, py${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} timeout-minutes: 15 strategy: fail-fast: false matrix: + os: [ubuntu-26.04, macos-26-intel, macos-26] python-version: ["3.12", "3.13", "3.14"] steps: @@ -39,13 +40,14 @@ jobs: run: python -m pytest tests/unit regression: - name: Regression (${{ matrix.os }}) + name: Regression (${{ matrix.os }}, py${{ matrix.python-version }}) runs-on: ${{ matrix.os }} timeout-minutes: 60 strategy: fail-fast: false matrix: os: [ubuntu-26.04, macos-26-intel, macos-26] + python-version: ["3.12", "3.13", "3.14"] steps: - name: Checkout @@ -77,6 +79,7 @@ jobs: --override-channels \ -c conda-forge \ -c bioconda \ + --python ${{ matrix.python-version }} \ --no-anaconda-upload docs: diff --git a/.github/workflows/weekly-regression.yaml b/.github/workflows/weekly-regression.yaml index bcfa4da..a5900cc 100644 --- a/.github/workflows/weekly-regression.yaml +++ b/.github/workflows/weekly-regression.yaml @@ -14,13 +14,14 @@ concurrency: jobs: regression: - name: SIST Regression (${{ matrix.os }}) + name: SIST Regression (${{ matrix.os }}, py${{ matrix.python-version }}) runs-on: ${{ matrix.os }} timeout-minutes: 30 strategy: fail-fast: false matrix: os: [ubuntu-26.04, macos-26-intel, macos-26] + python-version: ["3.12", "3.13", "3.14"] steps: - name: Checkout @@ -51,4 +52,5 @@ jobs: --override-channels \ -c conda-forge \ -c bioconda \ + --python ${{ matrix.python-version }} \ --no-anaconda-upload \ No newline at end of file diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index c2b1143..6e4fa95 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -29,7 +29,7 @@ requirements: test: requires: - - python >=3.14 + - python >=3.12 - pytest >=9,<10 source_files: From d811b37a980960c7b8b70567c65a68bec09cde0a Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 09:47:27 +0100 Subject: [PATCH 07/13] ci(sist): gate docs job behind unit tests --- .github/workflows/pr.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index e859677..23bdb24 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -84,6 +84,7 @@ jobs: docs: name: Docs + needs: unit runs-on: ubuntu-26.04 timeout-minutes: 20 From 569fb13ff6eb98be66f5ba367dd393afa7b9ada5 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 09:51:54 +0100 Subject: [PATCH 08/13] ci(sist): limit pr regression to a single python version, keep full matrix weekly --- .github/workflows/pr.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 23bdb24..41fbb03 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -40,14 +40,13 @@ jobs: run: python -m pytest tests/unit regression: - name: Regression (${{ matrix.os }}, py${{ matrix.python-version }}) + name: Regression (${{ matrix.os }}) runs-on: ${{ matrix.os }} timeout-minutes: 60 strategy: fail-fast: false matrix: os: [ubuntu-26.04, macos-26-intel, macos-26] - python-version: ["3.12", "3.13", "3.14"] steps: - name: Checkout @@ -79,7 +78,7 @@ jobs: --override-channels \ -c conda-forge \ -c bioconda \ - --python ${{ matrix.python-version }} \ + --python 3.14 \ --no-anaconda-upload docs: From ef164cf9044b4ca755834e1a560370896008c2f2 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 09:57:54 +0100 Subject: [PATCH 09/13] chore(workflows): update workflow names for consistency --- .github/workflows/pr.yaml | 4 ++-- .github/workflows/weekly-regression.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 41fbb03..815ffeb 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -12,7 +12,7 @@ concurrency: jobs: unit: - name: Unit (${{ matrix.os }}, py${{ matrix.python-version }}) + name: Pytest unit • ${{ matrix.os }}, ${{ matrix.python-version }} runs-on: ${{ matrix.os }} timeout-minutes: 15 @@ -40,7 +40,7 @@ jobs: run: python -m pytest tests/unit regression: - name: Regression (${{ matrix.os }}) + name: Regression • ${{ matrix.os }}) runs-on: ${{ matrix.os }} timeout-minutes: 60 strategy: diff --git a/.github/workflows/weekly-regression.yaml b/.github/workflows/weekly-regression.yaml index a5900cc..8d29eda 100644 --- a/.github/workflows/weekly-regression.yaml +++ b/.github/workflows/weekly-regression.yaml @@ -14,7 +14,7 @@ concurrency: jobs: regression: - name: SIST Regression (${{ matrix.os }}, py${{ matrix.python-version }}) + name: SIST Regression (${{ matrix.os }}, ${{ matrix.python-version }}) runs-on: ${{ matrix.os }} timeout-minutes: 30 strategy: From 9ede062ecf6dbac8e9a53dc3184c05a032153f54 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 10:02:37 +0100 Subject: [PATCH 10/13] chore: remove debug from IRF calculation --- src/sist/ir_finder.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sist/ir_finder.py b/src/sist/ir_finder.py index 8509d66..236add7 100644 --- a/src/sist/ir_finder.py +++ b/src/sist/ir_finder.py @@ -325,7 +325,6 @@ def _score_reports( str(self.IRF_MAX_LENGTH), str(self.IRF_MAX_LOOP), ], - stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, From f6c8692f64092cd0294bd759638d9a75bf263546 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 10:05:04 +0100 Subject: [PATCH 11/13] chore(workflows): fix typo within `.github/workflows/pr.yaml` --- .github/workflows/pr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 815ffeb..18c1957 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -40,7 +40,7 @@ jobs: run: python -m pytest tests/unit regression: - name: Regression • ${{ matrix.os }}) + name: Regression (${{ matrix.os }}) runs-on: ${{ matrix.os }} timeout-minutes: 60 strategy: From a3bcfd5d186a34ca61942cbe607ad8c7c417f88a Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 10:06:32 +0100 Subject: [PATCH 12/13] chore(workflows): update titles within `.github/workflows` for clarity --- .github/workflows/pr.yaml | 2 +- .github/workflows/weekly-regression.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 18c1957..8467d20 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -12,7 +12,7 @@ concurrency: jobs: unit: - name: Pytest unit • ${{ matrix.os }}, ${{ matrix.python-version }} + name: Pytest unit • ${{ matrix.os }}, Python ${{ matrix.python-version }} runs-on: ${{ matrix.os }} timeout-minutes: 15 diff --git a/.github/workflows/weekly-regression.yaml b/.github/workflows/weekly-regression.yaml index 8d29eda..167870a 100644 --- a/.github/workflows/weekly-regression.yaml +++ b/.github/workflows/weekly-regression.yaml @@ -14,7 +14,7 @@ concurrency: jobs: regression: - name: SIST Regression (${{ matrix.os }}, ${{ matrix.python-version }}) + name: SIST Regression (${{ matrix.os }}, Python ${{ matrix.python-version }}) runs-on: ${{ matrix.os }} timeout-minutes: 30 strategy: From ecde1ece84e267257a81b90b8c6e6887c57f8139 Mon Sep 17 00:00:00 2001 From: harryswift01 Date: Mon, 28 Sep 2026 10:24:09 +0100 Subject: [PATCH 13/13] fix(docs): floor `nbsphinx` at `v0.9.8` to avoid sphinx version conflict --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index f6ba0b1..71fd2b5 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ sphinx>=9.1,<9.2 -nbsphinx>=0.9,<1.0 +nbsphinx>=0.9.8,<1.0 furo>=2025.0,<2026.0 sphinx_copybutton>=0.5,<1.0 sphinxcontrib-contentui>=0.2,<1.0