Repository navigation
141 lines (135 loc) · 6.99 KB
/
Copy pathtest.yml
File metadata and controls
141 lines (135 loc) · 6.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
name: Test
# The suite on every push and pull request. Free: this repository is public, so standard runners --
# including Linux arm64, macOS and Windows -- carry no minute charge.
#
# `python-package.yml` publishes and runs only on `release: published`, which meant nothing checked a
# commit. The two files divide by question: that one asks whether the artifacts are right, this one
# whether the code is.
on:
push:
branches: [master]
pull_request:
workflow_dispatch:
# A second push to the same ref makes the first run's answer stale, so it is cancelled rather than
# finished.
concurrency:
group: test-${{ github.ref }}
cancel-in-progress: true
defaults:
run:
shell: bash # one quoting dialect; the runners all provide it
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
# Every row runs: the interesting failure is which rows differ, and the first one to fail would
# otherwise cancel exactly the comparison that identifies the cause.
fail-fast: false
matrix:
include:
# THE OLDEST AND NEWEST INTERPRETERS on the platform everything else is compared against.
- {os: ubuntu-24.04, python: "3.10"}
- {os: ubuntu-24.04, python: "3.14"}
# THE ARCH THAT IS NOT LIKE THE OTHERS. Plain `char` is unsigned here and signed everywhere
# else, and the flags that reconcile that (`chython/test/test_release_build.py`) are asserted
# from a declaration; this row is what runs the assertions on the arch itself.
- {os: ubuntu-24.04-arm, python: "3.12"}
# ONE ROW PER TOOLCHAIN: clang with an Apple SDK, and MSVC.
- {os: macos-latest, python: "3.12"}
- {os: windows-latest, python: "3.12"}
steps:
- uses: actions/checkout@v4
with:
submodules: true # INCHI, or every InChI test skips
- name: Set up CMake
uses: lukka/get-cmake@latest
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: pip
cache-dependency-path: pyproject.toml
- name: Install the build tools
# Named here rather than left to build isolation because the next step calls `setup.py` directly.
run: |
python -m pip install --upgrade pip
python -m pip install "cython>=3.1" "setuptools>=77" wheel
- name: Build in place
# `pytest chython/` imports the package out of the source tree, so the extension has to be there;
# an editable install alone leaves that to `editable_wheel`'s internals. This is also what stages
# libinchi beside the extension, which `core/__init__.py` loads relative to its own `__file__`.
run: python setup.py build_ext --inplace
- name: Install
# `--no-build-isolation` so this reuses the objects the step above compiled instead of compiling
# the translation unit a second time in an isolated environment. The extras are the ones the
# suite reads: `ml` is numpy, without which the fingerprint and matrix tests skip, and `rdkit` is
# the differential oracle in `formats/test/oracles.py`.
run: python -m pip install -e ".[ml,rdkit]" --group dev --no-build-isolation
- name: Confirm libinchi loaded
# A LOUD FAILURE FOR A SILENT ONE. Without the library about a hundred tests skip and the suite
# still passes, so a broken staging step or a missing submodule reads as green.
run: |
python -c "from chython import inchi_library_loaded; assert inchi_library_loaded(), 'libinchi did not load'"
- name: Test
# `test_performance.py` asserts RATIOS against RDKit, which is the right discipline for a
# developer's machine and still not one for a shared runner whose neighbour decides the numbers.
# It is a benchmark, run by hand; nothing else in the suite is timing-sensitive.
run: python -m pytest chython/ -q --deselect chython/test/test_performance.py
oracles:
# THE SAME SUITE WITH THE DIFFERENTIAL ORACLES, on one row and by itself: measured, they turn 584
# skips into tests and the run from 3m15s into 17m41s. Paying that on all five rows would make the
# answer to "did I break the build" arrive five times later, so the matrix above stays the fast
# signal and this job runs beside it.
#
# `extra-clean2d` and `extra-clean3d` by name rather than their members, so the CI cannot drift from
# what a user installing them gets. jpype comes with the first and its 63 tests still skip, needing
# a JChem jar that is licensed and not here; `CHYTHON_CDK_JAR` is unset, so 219 CDK comparisons skip
# too.
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Set up CMake
uses: lukka/get-cmake@latest
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install the build tools
run: |
python -m pip install --upgrade pip
python -m pip install "cython>=3.1" "setuptools>=77" wheel
- name: Build in place
run: python setup.py build_ext --inplace
- name: Install
run: |
python -m pip install -e ".[ml,rdkit,extra-clean2d,extra-clean3d]" --group dev --no-build-isolation
- name: Confirm libinchi loaded
run: |
python -c "from chython import inchi_library_loaded; assert inchi_library_loaded(), 'libinchi did not load'"
- name: Test, under coverage
# THE README BADGE'S NUMBER COMES FROM THIS JOB, because this is the run where nothing skips for a
# missing toolkit: on a fast-matrix row `interop/_indigo.py` would read as uncovered rather than as
# never imported. What it measures and what it omits are in `[tool.coverage]` in pyproject.toml,
# so the number is reproducible from a checkout. Measured cost of the wrapper on this suite: 245s
# against 186s, about a third, paid on the job that is already the slow one.
run: |
python -m coverage run -m pytest chython/ -q --deselect chython/test/test_performance.py
python -m coverage report
python -m coverage xml
- name: Upload coverage
# Only from this repository -- a fork has no project to upload to -- and never fatal: a badge that
# went stale is not the suite going red, and the step above already asserted the suite.
if: github.repository == 'chython/chython'
uses: codecov/codecov-action@v5
with:
files: coverage.xml
fail_ci_if_error: false
# REQUIRED for the badge. Codecov allows a tokenless upload from a pull request, including a
# fork's, but refuses one to the default branch -- `Token required because branch is protected`,
# which is its own rule and not GitHub's branch protection. Unset, the badge reads `unknown`
# while this step still reports success, so the number's absence is read here and not in CI.
token: ${{ secrets.CODECOV_TOKEN }}