pymstm 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pymstm-1.0.0/.github/workflows/publish.yml +335 -0
- pymstm-1.0.0/.github/workflows/test.yml +49 -0
- pymstm-1.0.0/.gitignore +304 -0
- pymstm-1.0.0/.gitmodules +3 -0
- pymstm-1.0.0/CHANGELOG.md +39 -0
- pymstm-1.0.0/LICENSE +65 -0
- pymstm-1.0.0/Makefile +99 -0
- pymstm-1.0.0/PKG-INFO +102 -0
- pymstm-1.0.0/README.md +69 -0
- pymstm-1.0.0/devenv.nix +50 -0
- pymstm-1.0.0/devenv.yaml +20 -0
- pymstm-1.0.0/examples/single_sphere.py +29 -0
- pymstm-1.0.0/external/mstm/LICENSE +21 -0
- pymstm-1.0.0/external/mstm/code/make-parallel.bat +4 -0
- pymstm-1.0.0/external/mstm/code/make-serial.bat +4 -0
- pymstm-1.0.0/external/mstm/code/mpidefs-parallel.f90 +409 -0
- pymstm-1.0.0/external/mstm/code/mpidefs-serial.f90 +147 -0
- pymstm-1.0.0/external/mstm/code/mstm-intrinsics.f90 +69 -0
- pymstm-1.0.0/external/mstm/code/mstm-v4.0.f90 +18213 -0
- pymstm-1.0.0/external/mstm/code/readme +2 -0
- pymstm-1.0.0/external/mstm/december2023/fft_translation-5.f90 +3202 -0
- pymstm-1.0.0/external/mstm/december2023/lmfit.f90 +1577 -0
- pymstm-1.0.0/external/mstm/december2023/mpidefs-parallel-2.f90 +449 -0
- pymstm-1.0.0/external/mstm/december2023/mpidefs-serial.f90 +147 -0
- pymstm-1.0.0/external/mstm/december2023/mstm-input-37.f90 +4002 -0
- pymstm-1.0.0/external/mstm/december2023/mstm-intrinsics.f90 +69 -0
- pymstm-1.0.0/external/mstm/december2023/mstm-main-3.f90 +185 -0
- pymstm-1.0.0/external/mstm/december2023/mstm-modules-33.f90 +6822 -0
- pymstm-1.0.0/external/mstm/december2023/mstm-scatprops-26.f90 +3501 -0
- pymstm-1.0.0/external/mstm/december2023/mstm-solver-8.f90 +1054 -0
- pymstm-1.0.0/external/mstm/december2023/random_configuration-10.f90 +1403 -0
- pymstm-1.0.0/external/mstm/december2023/readme +13 -0
- pymstm-1.0.0/external/mstm/doc/mackowski-mstm-2021.pdf +0 -0
- pymstm-1.0.0/external/mstm/doc/mackowski-mstm-2022b.pdf +0 -0
- pymstm-1.0.0/external/mstm/doc/mstm-manual-2021.pdf +0 -0
- pymstm-1.0.0/external/mstm/doc/readme +5 -0
- pymstm-1.0.0/external/mstm/examples/frac_agg.pos +100 -0
- pymstm-1.0.0/external/mstm/examples/mstm-2022b-fig1.inp +34 -0
- pymstm-1.0.0/external/mstm/examples/mstm-2022b-fig2.inp +30 -0
- pymstm-1.0.0/external/mstm/examples/mstm-2022b-fig3.inp +49 -0
- pymstm-1.0.0/external/mstm/examples/mstm-2022b-fig4.inp +38 -0
- pymstm-1.0.0/external/mstm/examples/mstm-2022b-fig5.inp +28 -0
- pymstm-1.0.0/external/mstm/examples/plots mstm-2022b.nb +346449 -0
- pymstm-1.0.0/external/mstm/examples/random_in_cylinder_1000.pos +1000 -0
- pymstm-1.0.0/external/mstm/examples/readme +1 -0
- pymstm-1.0.0/external/mstm/readme +3 -0
- pymstm-1.0.0/flake.lock +43 -0
- pymstm-1.0.0/flake.nix +133 -0
- pymstm-1.0.0/meson.build +132 -0
- pymstm-1.0.0/pyproject.toml +103 -0
- pymstm-1.0.0/scripts/streamlit_app.py +992 -0
- pymstm-1.0.0/src/pymstm/__init__.py +6 -0
- pymstm-1.0.0/src/pymstm/_build.py +50 -0
- pymstm-1.0.0/src/pymstm/_config.py +327 -0
- pymstm-1.0.0/src/pymstm/_fortran/mstm_f2py.f90 +863 -0
- pymstm-1.0.0/src/pymstm/_fortran/patches/mstm-modules-33-f2py-data-fix.patch +76 -0
- pymstm-1.0.0/src/pymstm/_fortran/patches/random_configuration-10-f2py-derivedtype-fix.patch +43 -0
- pymstm-1.0.0/src/pymstm/_fortran/patches/random_configuration-10-license-fix.patch +218 -0
- pymstm-1.0.0/src/pymstm/_inp.py +153 -0
- pymstm-1.0.0/src/pymstm/_inp_parser.py +456 -0
- pymstm-1.0.0/src/pymstm/_mstm.py +499 -0
- pymstm-1.0.0/src/pymstm/_parser.py +265 -0
- pymstm-1.0.0/tests/conftest.py +4 -0
- pymstm-1.0.0/tests/data/fractal_N128_Df2.0.dat +149 -0
- pymstm-1.0.0/tests/data/fractal_sweep.toml +28 -0
- pymstm-1.0.0/tests/test_advanced.py +98 -0
- pymstm-1.0.0/tests/test_compatibility.py +564 -0
- pymstm-1.0.0/tests/test_f2py_smoke.py +405 -0
- pymstm-1.0.0/tests/test_solve.py +96 -0
- pymstm-1.0.0/tests/test_tmatrix.py +64 -0
- pymstm-1.0.0/tools/apply_patch.py +25 -0
- pymstm-1.0.0/tools/build_f2py_ext.py +83 -0
- pymstm-1.0.0/uv.lock +1867 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
name: Continuous Delivery
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
testing:
|
|
11
|
+
uses: ./.github/workflows/test.yml
|
|
12
|
+
|
|
13
|
+
determine-version:
|
|
14
|
+
name: Determine next version (no side effects yet)
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
needs:
|
|
17
|
+
- testing
|
|
18
|
+
outputs:
|
|
19
|
+
released: ${{ steps.compute.outputs.released }}
|
|
20
|
+
version: ${{ steps.compute.outputs.version }}
|
|
21
|
+
steps:
|
|
22
|
+
- name: Setup | Checkout Repository
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
with:
|
|
25
|
+
fetch-depth: 0
|
|
26
|
+
|
|
27
|
+
- name: Setup | Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@v4
|
|
29
|
+
|
|
30
|
+
- name: Setup | Install python-semantic-release only
|
|
31
|
+
# --no-install-project: this job only ever calls `semantic-release
|
|
32
|
+
# version --print`, a pure dry run that never touches
|
|
33
|
+
# build_command -- unlike the real `release` job below, it never
|
|
34
|
+
# needs pymstm itself built, so it can skip gfortran entirely
|
|
35
|
+
# (confirmed locally: --print works fine against just the `build`
|
|
36
|
+
# extra's own deps).
|
|
37
|
+
run: uv sync --extra build --no-install-project
|
|
38
|
+
|
|
39
|
+
- name: Evaluate | Compute next version without tagging
|
|
40
|
+
id: compute
|
|
41
|
+
# `uv run <cmd>` implicitly re-syncs the venv first by default,
|
|
42
|
+
# regardless of an earlier separate `uv sync --no-install-project`
|
|
43
|
+
# -- that implicit sync doesn't inherit --no-install-project, so
|
|
44
|
+
# it tries to build/install pymstm itself again, which needs
|
|
45
|
+
# gfortran (deliberately not installed in this job, see the
|
|
46
|
+
# step above). That failure was hidden by this step's own
|
|
47
|
+
# `2>/dev/null` on the semantic-release line, so it looked like
|
|
48
|
+
# total silence rather than a build error -- confirmed locally:
|
|
49
|
+
# reproducible without --no-sync, gone with it. --no-sync trusts
|
|
50
|
+
# the venv exactly as the earlier `uv sync --no-install-project`
|
|
51
|
+
# left it.
|
|
52
|
+
run: |
|
|
53
|
+
CURRENT="$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")"
|
|
54
|
+
NEXT="$(uv run --no-sync semantic-release version --print 2>/dev/null)"
|
|
55
|
+
echo "Current version: $CURRENT"
|
|
56
|
+
echo "Next version: $NEXT"
|
|
57
|
+
echo "version=$NEXT" >> "$GITHUB_OUTPUT"
|
|
58
|
+
if [ "$NEXT" != "$CURRENT" ]; then
|
|
59
|
+
echo "released=true" >> "$GITHUB_OUTPUT"
|
|
60
|
+
else
|
|
61
|
+
echo "released=false" >> "$GITHUB_OUTPUT"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
build_wheels:
|
|
65
|
+
name: Build wheels on ${{ matrix.os }}
|
|
66
|
+
needs:
|
|
67
|
+
- determine-version
|
|
68
|
+
if: needs.determine-version.outputs.released == 'true'
|
|
69
|
+
runs-on: ${{ matrix.os }}
|
|
70
|
+
strategy:
|
|
71
|
+
fail-fast: false
|
|
72
|
+
matrix:
|
|
73
|
+
# Linux only for now, deliberately -- macos-13/macos-14 legs
|
|
74
|
+
# both failed on the first real release run (macOS: Homebrew's
|
|
75
|
+
# latest gfortran links libgfortran/libquadmath requiring macOS
|
|
76
|
+
# 14+, tripping delocate-wheel's deployment-target check; see
|
|
77
|
+
# the CIBW_ENVIRONMENT_MACOS comment below for the fix, prepared
|
|
78
|
+
# but not yet re-verified end to end) -- narrowing to Linux
|
|
79
|
+
# avoids burning macOS runner minutes on repeated iterations
|
|
80
|
+
# while that's still being sorted out. Windows needs a whole
|
|
81
|
+
# separate MinGW/gfortran toolchain story, and Linux aarch64
|
|
82
|
+
# would mean QEMU-emulated compiles (slow, fragile for a first
|
|
83
|
+
# pass) -- both left as a follow-up too.
|
|
84
|
+
os: [ubuntu-latest]
|
|
85
|
+
|
|
86
|
+
steps:
|
|
87
|
+
- name: Setup | Checkout Repository
|
|
88
|
+
# No tag exists yet at this point -- that's the whole point of
|
|
89
|
+
# this reordering (see determine-version/release comments below).
|
|
90
|
+
# github.sha is fixed for the entire workflow run, so this and
|
|
91
|
+
# every other job here build from the exact same commit
|
|
92
|
+
# determine-version already computed a version for for.
|
|
93
|
+
uses: actions/checkout@v4
|
|
94
|
+
with:
|
|
95
|
+
submodules: recursive
|
|
96
|
+
|
|
97
|
+
- name: Setup | Stamp the version determine-version computed
|
|
98
|
+
# No tag/commit exists for this version yet -- release (below)
|
|
99
|
+
# only creates one once these wheels are confirmed good. Patch
|
|
100
|
+
# the version strings locally (uncommitted, this checkout is
|
|
101
|
+
# thrown away after the job) purely so the wheel filenames and
|
|
102
|
+
# METADATA carry the version that *will* be tagged, instead of
|
|
103
|
+
# whatever version.toml/`__init__.py` still say on plain main.
|
|
104
|
+
run: |
|
|
105
|
+
sed -i 's/^version = ".*"/version = "${{ needs.determine-version.outputs.version }}"/' pyproject.toml
|
|
106
|
+
sed -i 's/^__version__ = ".*"/__version__ = "${{ needs.determine-version.outputs.version }}"/' src/pymstm/__init__.py
|
|
107
|
+
|
|
108
|
+
- name: Build wheels
|
|
109
|
+
uses: pypa/cibuildwheel@v2.21
|
|
110
|
+
env:
|
|
111
|
+
# cp39/cp310 dropped for good (see pyproject.toml's
|
|
112
|
+
# requires-python comment) -- two independent, real cibuildwheel
|
|
113
|
+
# failures below cp311: cp39 segfaulted (SIGSEGV) deep in a
|
|
114
|
+
# two-sphere solve (ruled out compiler version and f2py's
|
|
115
|
+
# legacy distutils backend as causes, both survived); cp310
|
|
116
|
+
# crashed earlier, during the f2py build itself (KeyError:
|
|
117
|
+
# 'void' in numpy's own crackfortran). Both are the only builds
|
|
118
|
+
# resolving a numpy old enough to hit these, and both Python
|
|
119
|
+
# versions are in their final year of upstream support anyway
|
|
120
|
+
# -- not worth separately chasing two legacy-numpy-version bugs
|
|
121
|
+
# for them.
|
|
122
|
+
# PyPy/musllinux skipped -- Fortran extensions aren't a realistic
|
|
123
|
+
# target there and it doubles build time for no real benefit.
|
|
124
|
+
CIBW_BUILD: "cp311-* cp312-* cp313-*"
|
|
125
|
+
CIBW_SKIP: "*-musllinux*"
|
|
126
|
+
# cibuildwheel's own default architecture set for a Linux
|
|
127
|
+
# x86_64 runner also includes i686 (32-bit) -- confirmed via a
|
|
128
|
+
# real run: cp311/cp312/cp313 x86_64 wheels all built cleanly,
|
|
129
|
+
# then it moved on to cp311-manylinux_i686, where numpy has no
|
|
130
|
+
# prebuilt wheel, forcing a ~3+ minute from-source numpy build
|
|
131
|
+
# just to get started. Nobody needs 32-bit wheels for this.
|
|
132
|
+
CIBW_ARCHS_LINUX: "x86_64"
|
|
133
|
+
CIBW_ARCHS_MACOS: "auto"
|
|
134
|
+
CIBW_BUILD_VERBOSITY: "1"
|
|
135
|
+
# manylinux images are AlmaLinux/CentOS-based -- gcc-gfortran is
|
|
136
|
+
# in the base repos on both manylinux2014 and manylinux_2_28.
|
|
137
|
+
CIBW_BEFORE_ALL_LINUX: "yum install -y gcc-gfortran"
|
|
138
|
+
# No CIBW_BEFORE_ALL_MACOS `brew install gcc` -- GitHub's macOS
|
|
139
|
+
# runner images ship gfortran-13/14/15 pre-installed (see
|
|
140
|
+
# actions/runner-images' own macos-14-arm64-Readme.md), and
|
|
141
|
+
# NumPy's own wheels.yml uses exactly this pinned-version
|
|
142
|
+
# approach (`FC=gfortran-13`, no brew install at all) rather
|
|
143
|
+
# than installing Homebrew's *latest* gcc fresh. That distinction
|
|
144
|
+
# matters here, not just for speed: the first real run's macOS
|
|
145
|
+
# legs failed because a freshly `brew install`ed gcc links
|
|
146
|
+
# libgfortran/libquadmath requiring macOS 14+, which
|
|
147
|
+
# delocate-wheel then refuses to repair for an 11.0-targeted
|
|
148
|
+
# wheel -- the older, pre-installed gfortran-13 doesn't have
|
|
149
|
+
# that mismatch. Not yet re-verified end to end (matrix is
|
|
150
|
+
# Linux-only above until that's settled) -- prepared so macOS
|
|
151
|
+
# can be re-added with a real fix instead of the guess that
|
|
152
|
+
# failed the first time.
|
|
153
|
+
CIBW_ENVIRONMENT_MACOS: "FC=gfortran-13"
|
|
154
|
+
# Smoke test: actually import and run a tiny solve inside the
|
|
155
|
+
# built wheel (in an isolated venv cibuildwheel creates), not
|
|
156
|
+
# just an import check -- catches a wheel that imports fine but
|
|
157
|
+
# is missing/mislinked its compiled extension.
|
|
158
|
+
#
|
|
159
|
+
# `import pymstm;` MUST stay on the same source line as the
|
|
160
|
+
# opening quote below -- YAML's `>` folding replaces every line
|
|
161
|
+
# break with a single space, so a break right after `python -c
|
|
162
|
+
# "` folds into a *leading space inside the quoted string*
|
|
163
|
+
# (`python -c " import pymstm; ...`), and `python -c` raises
|
|
164
|
+
# IndentationError: unexpected indent on any leading whitespace
|
|
165
|
+
# in top-level exec'd code. Confirmed via a real failed run.
|
|
166
|
+
CIBW_TEST_COMMAND: >
|
|
167
|
+
python -c "import pymstm;
|
|
168
|
+
m = pymstm.MSTM();
|
|
169
|
+
m.set_spheres(radii=[1.0,1.0], positions=[[-1.5,0,0],[1.5,0,0]], orders=[6,6], ref_re=[1.5,1.5], ref_im=[0.01,0.01]);
|
|
170
|
+
m.set_medium_ref(1.0, 0.0);
|
|
171
|
+
m.set_incident(alpha_deg=0.0, beta_deg=0.0);
|
|
172
|
+
m.set_solver_params(eps=1e-3, max_iter=200);
|
|
173
|
+
m.set_verbose(False);
|
|
174
|
+
m.prepare();
|
|
175
|
+
r = m.solve();
|
|
176
|
+
m.finalize();
|
|
177
|
+
assert r['qext_tot'] > 0"
|
|
178
|
+
|
|
179
|
+
- uses: actions/upload-artifact@v4
|
|
180
|
+
with:
|
|
181
|
+
name: wheels-${{ matrix.os }}
|
|
182
|
+
path: ./wheelhouse/*.whl
|
|
183
|
+
|
|
184
|
+
release:
|
|
185
|
+
name: Tag and create the GitHub Release (wheels already verified)
|
|
186
|
+
runs-on: ubuntu-latest
|
|
187
|
+
needs:
|
|
188
|
+
- determine-version
|
|
189
|
+
- build_wheels
|
|
190
|
+
|
|
191
|
+
concurrency:
|
|
192
|
+
group: ${{ github.workflow }}-release-${{ github.ref_name }}
|
|
193
|
+
cancel-in-progress: false
|
|
194
|
+
permissions:
|
|
195
|
+
contents: write
|
|
196
|
+
|
|
197
|
+
outputs:
|
|
198
|
+
released: ${{ steps.release.outputs.released }}
|
|
199
|
+
tag: ${{ steps.release.outputs.tag }}
|
|
200
|
+
version: ${{ steps.release.outputs.version }}
|
|
201
|
+
|
|
202
|
+
steps:
|
|
203
|
+
- name: Setup | Checkout Repository on Release Branch
|
|
204
|
+
uses: actions/checkout@v4
|
|
205
|
+
with:
|
|
206
|
+
ref: ${{ github.ref_name }}
|
|
207
|
+
fetch-depth: 0
|
|
208
|
+
submodules: recursive
|
|
209
|
+
|
|
210
|
+
- name: Setup | Force release branch to be at workflow sha
|
|
211
|
+
run: git reset --hard ${{ github.sha }}
|
|
212
|
+
|
|
213
|
+
- name: Setup | Install gfortran
|
|
214
|
+
# `uv sync` also builds/installs pymstm itself (not just the
|
|
215
|
+
# `build` extra's own deps), and pyproject.toml's
|
|
216
|
+
# no-build-isolation-package = ["pymstm"] means that build needs
|
|
217
|
+
# gfortran and meson-python already present in *this* venv --
|
|
218
|
+
# same reason test.yml installs it before syncing.
|
|
219
|
+
run: sudo apt-get update && sudo apt-get install -y gfortran
|
|
220
|
+
|
|
221
|
+
- name: Setup | Install uv
|
|
222
|
+
uses: astral-sh/setup-uv@v4
|
|
223
|
+
|
|
224
|
+
- name: Setup | Install build dependencies
|
|
225
|
+
# `build-ext` for meson/ninja/meson-python (needed to build
|
|
226
|
+
# pymstm itself, see gfortran step above) without pytest/
|
|
227
|
+
# pytest-cov along for the ride -- this job never runs the test
|
|
228
|
+
# suite, that's test.yml's job. `build` for
|
|
229
|
+
# python-semantic-release.
|
|
230
|
+
run: uv sync --extra build --extra build-ext
|
|
231
|
+
|
|
232
|
+
- name: Evaluate | Verify upstream has NOT changed
|
|
233
|
+
# Wheels take a while to build -- more important here than it
|
|
234
|
+
# was before this job moved to run last, since there's now a
|
|
235
|
+
# longer window for main to have drifted between our checkout
|
|
236
|
+
# above and the push below.
|
|
237
|
+
shell: bash
|
|
238
|
+
run: |
|
|
239
|
+
set +o pipefail
|
|
240
|
+
|
|
241
|
+
UPSTREAM_BRANCH_NAME="$(git status -sb | head -n 1 | cut -d' ' -f2 | grep -E '\.{3}' | cut -d'.' -f4)"
|
|
242
|
+
printf '%s\n' "Upstream branch name: $UPSTREAM_BRANCH_NAME"
|
|
243
|
+
|
|
244
|
+
set -o pipefail
|
|
245
|
+
|
|
246
|
+
if [ -z "$UPSTREAM_BRANCH_NAME" ]; then
|
|
247
|
+
printf >&2 '%s\n' "::error::Unable to determine upstream branch name!"
|
|
248
|
+
exit 1
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
git fetch "${UPSTREAM_BRANCH_NAME%%/*}"
|
|
252
|
+
|
|
253
|
+
if ! UPSTREAM_SHA="$(git rev-parse "$UPSTREAM_BRANCH_NAME")"; then
|
|
254
|
+
printf >&2 '%s\n' "::error::Unable to determine upstream branch sha!"
|
|
255
|
+
exit 1
|
|
256
|
+
fi
|
|
257
|
+
|
|
258
|
+
HEAD_SHA="$(git rev-parse HEAD)"
|
|
259
|
+
|
|
260
|
+
if [ "$HEAD_SHA" != "$UPSTREAM_SHA" ]; then
|
|
261
|
+
printf >&2 '%s\n' "[HEAD SHA] $HEAD_SHA != $UPSTREAM_SHA [UPSTREAM SHA]"
|
|
262
|
+
printf >&2 '%s\n' "::error::Upstream has changed, aborting release..."
|
|
263
|
+
exit 1
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
printf '%s\n' "Verified upstream branch has not changed, continuing with release..."
|
|
267
|
+
|
|
268
|
+
- name: Action | Semantic Version Release
|
|
269
|
+
# Bumps pyproject.toml/src/pymstm/__init__.py's version, builds
|
|
270
|
+
# the sdist (build_command below), commits, tags, pushes, and
|
|
271
|
+
# creates the GitHub Release (sdist attached as an asset) --
|
|
272
|
+
# only reached after build_wheels has already succeeded, so
|
|
273
|
+
# (unlike the very first version of this pipeline) a tag/release
|
|
274
|
+
# only ever gets created once we already know real wheels exist
|
|
275
|
+
# for it. Recomputes the same version determine-version already
|
|
276
|
+
# printed (nothing has changed the commit history since), so the
|
|
277
|
+
# wheels build_wheels already built and stamped stay correct.
|
|
278
|
+
id: release
|
|
279
|
+
env:
|
|
280
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
281
|
+
run: |
|
|
282
|
+
git config user.name "github-actions"
|
|
283
|
+
git config user.email "actions@users.noreply.github.com"
|
|
284
|
+
uv run semantic-release -v version
|
|
285
|
+
|
|
286
|
+
- name: Publish | Upload sdist to GitHub Release Assets
|
|
287
|
+
if: steps.release.outputs.released == 'true'
|
|
288
|
+
env:
|
|
289
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
290
|
+
run: uv run semantic-release publish
|
|
291
|
+
|
|
292
|
+
publish:
|
|
293
|
+
name: Publish to PyPI and attach wheels to the GitHub Release
|
|
294
|
+
needs:
|
|
295
|
+
- release
|
|
296
|
+
- build_wheels
|
|
297
|
+
runs-on: ubuntu-latest
|
|
298
|
+
|
|
299
|
+
environment:
|
|
300
|
+
name: pypi
|
|
301
|
+
url: https://pypi.org/p/pymstm
|
|
302
|
+
permissions:
|
|
303
|
+
id-token: write
|
|
304
|
+
contents: write
|
|
305
|
+
|
|
306
|
+
steps:
|
|
307
|
+
- name: Download all wheels
|
|
308
|
+
uses: actions/download-artifact@v4
|
|
309
|
+
with:
|
|
310
|
+
pattern: wheels-*
|
|
311
|
+
path: dist
|
|
312
|
+
merge-multiple: true
|
|
313
|
+
|
|
314
|
+
- name: Download sdist from the GitHub Release
|
|
315
|
+
env:
|
|
316
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
317
|
+
run: |
|
|
318
|
+
gh release download ${{ needs.release.outputs.tag }} \
|
|
319
|
+
--repo ${{ github.repository }} \
|
|
320
|
+
--pattern '*.tar.gz' \
|
|
321
|
+
--dir dist
|
|
322
|
+
|
|
323
|
+
- name: Publish | Upload wheels to GitHub Release Assets
|
|
324
|
+
env:
|
|
325
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
326
|
+
run: |
|
|
327
|
+
gh release upload ${{ needs.release.outputs.tag }} dist/*.whl \
|
|
328
|
+
--repo ${{ github.repository }} \
|
|
329
|
+
--clobber
|
|
330
|
+
|
|
331
|
+
- name: Setup | Install uv
|
|
332
|
+
uses: astral-sh/setup-uv@v4
|
|
333
|
+
|
|
334
|
+
- name: Publish | Publish to PyPI
|
|
335
|
+
run: uv publish dist/*
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
name: Testing
|
|
2
|
+
on:
|
|
3
|
+
workflow_call:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
pull_request:
|
|
6
|
+
push:
|
|
7
|
+
branches: [main]
|
|
8
|
+
jobs:
|
|
9
|
+
unittest:
|
|
10
|
+
name: PyTest
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
with:
|
|
15
|
+
submodules: recursive
|
|
16
|
+
- name: Install gfortran
|
|
17
|
+
# Needed for `uv sync` to build the f2py extension (meson-python
|
|
18
|
+
# drives numpy.f2py -c against external/mstm/, see meson.build).
|
|
19
|
+
run: sudo apt-get update && sudo apt-get install -y gfortran
|
|
20
|
+
- name: Install uv
|
|
21
|
+
id: setup-python
|
|
22
|
+
uses: astral-sh/setup-uv@v4
|
|
23
|
+
with:
|
|
24
|
+
enable-cache: true
|
|
25
|
+
- name: Install dependencies (builds the f2py extension)
|
|
26
|
+
run: uv sync --extra dev
|
|
27
|
+
- name: Cache | MSTM CLI reference binary
|
|
28
|
+
id: cache-cli
|
|
29
|
+
uses: actions/cache@v4
|
|
30
|
+
with:
|
|
31
|
+
path: build/mstm
|
|
32
|
+
# external/mstm is a git submodule pinned to a fixed commit in
|
|
33
|
+
# .gitmodules -- it essentially never changes between runs, so
|
|
34
|
+
# hashing its checked-out content (plus the Makefile that
|
|
35
|
+
# compiles it) is a reliable "did the CLI's own inputs change"
|
|
36
|
+
# key, letting most runs skip recompiling it entirely.
|
|
37
|
+
key: ${{ runner.os }}-mstm-cli-${{ hashFiles('external/mstm/december2023/**', 'Makefile') }}
|
|
38
|
+
|
|
39
|
+
- name: Build the standalone MSTM CLI reference binary
|
|
40
|
+
# test_compatibility.py skips itself if this isn't present -- but
|
|
41
|
+
# we want that cross-check to actually run in CI, not silently
|
|
42
|
+
# skip. Skipped entirely on a cache hit above -- `make`'s own
|
|
43
|
+
# mtime-based staleness check isn't reliable here since a fresh
|
|
44
|
+
# checkout + cache restore don't produce trustworthy relative
|
|
45
|
+
# timestamps between sources and the cached binary.
|
|
46
|
+
if: steps.cache-cli.outputs.cache-hit != 'true'
|
|
47
|
+
run: make cli
|
|
48
|
+
- name: Test with pytest
|
|
49
|
+
run: uv run pytest tests/ -v
|
pymstm-1.0.0/.gitignore
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
build/
|
|
2
|
+
src/pymstm/libmstm.so
|
|
3
|
+
|
|
4
|
+
## Devenv
|
|
5
|
+
.devenv*
|
|
6
|
+
devenv.local.nix
|
|
7
|
+
devenv.local.yaml
|
|
8
|
+
|
|
9
|
+
# direnv
|
|
10
|
+
.direnv
|
|
11
|
+
|
|
12
|
+
# pre-commit
|
|
13
|
+
.pre-commit-config.yaml
|
|
14
|
+
|
|
15
|
+
## Python
|
|
16
|
+
# Byte-compiled / optimized / DLL files
|
|
17
|
+
__pycache__/
|
|
18
|
+
*.py[codz]
|
|
19
|
+
*$py.class
|
|
20
|
+
|
|
21
|
+
# C extensions
|
|
22
|
+
*.so
|
|
23
|
+
|
|
24
|
+
# Distribution / packaging
|
|
25
|
+
.Python
|
|
26
|
+
build/
|
|
27
|
+
develop-eggs/
|
|
28
|
+
dist/
|
|
29
|
+
downloads/
|
|
30
|
+
eggs/
|
|
31
|
+
.eggs/
|
|
32
|
+
lib/
|
|
33
|
+
lib64/
|
|
34
|
+
parts/
|
|
35
|
+
sdist/
|
|
36
|
+
var/
|
|
37
|
+
wheels/
|
|
38
|
+
share/python-wheels/
|
|
39
|
+
*.egg-info/
|
|
40
|
+
.installed.cfg
|
|
41
|
+
*.egg
|
|
42
|
+
MANIFEST
|
|
43
|
+
|
|
44
|
+
# PyInstaller
|
|
45
|
+
# Usually these files are written by a python script from a template
|
|
46
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
47
|
+
*.manifest
|
|
48
|
+
*.spec
|
|
49
|
+
|
|
50
|
+
# Installer logs
|
|
51
|
+
pip-log.txt
|
|
52
|
+
pip-delete-this-directory.txt
|
|
53
|
+
|
|
54
|
+
# Unit test / coverage reports
|
|
55
|
+
htmlcov/
|
|
56
|
+
.tox/
|
|
57
|
+
.nox/
|
|
58
|
+
.coverage
|
|
59
|
+
.coverage.*
|
|
60
|
+
.cache
|
|
61
|
+
nosetests.xml
|
|
62
|
+
coverage.xml
|
|
63
|
+
*.cover
|
|
64
|
+
*.py.cover
|
|
65
|
+
*.lcov
|
|
66
|
+
.hypothesis/
|
|
67
|
+
.pytest_cache/
|
|
68
|
+
cover/
|
|
69
|
+
|
|
70
|
+
# Translations
|
|
71
|
+
*.mo
|
|
72
|
+
*.pot
|
|
73
|
+
|
|
74
|
+
# Django stuff:
|
|
75
|
+
*.log
|
|
76
|
+
local_settings.py
|
|
77
|
+
db.sqlite3
|
|
78
|
+
db.sqlite3-journal
|
|
79
|
+
|
|
80
|
+
# Flask stuff:
|
|
81
|
+
instance/
|
|
82
|
+
.webassets-cache
|
|
83
|
+
|
|
84
|
+
# Scrapy stuff:
|
|
85
|
+
.scrapy
|
|
86
|
+
|
|
87
|
+
# Sphinx documentation
|
|
88
|
+
docs/_build/
|
|
89
|
+
|
|
90
|
+
# PyBuilder
|
|
91
|
+
.pybuilder/
|
|
92
|
+
target/
|
|
93
|
+
|
|
94
|
+
# Jupyter Notebook
|
|
95
|
+
.ipynb_checkpoints
|
|
96
|
+
|
|
97
|
+
# IPython
|
|
98
|
+
profile_default/
|
|
99
|
+
ipython_config.py
|
|
100
|
+
|
|
101
|
+
# pyenv
|
|
102
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
103
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
104
|
+
# .python-version
|
|
105
|
+
|
|
106
|
+
# pipenv
|
|
107
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
108
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
109
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
110
|
+
# install all needed dependencies.
|
|
111
|
+
# Pipfile.lock
|
|
112
|
+
|
|
113
|
+
# UV
|
|
114
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
115
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
116
|
+
# commonly ignored for libraries.
|
|
117
|
+
# uv.lock
|
|
118
|
+
|
|
119
|
+
# poetry
|
|
120
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
121
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
122
|
+
# commonly ignored for libraries.
|
|
123
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
124
|
+
# poetry.lock
|
|
125
|
+
# poetry.toml
|
|
126
|
+
|
|
127
|
+
# pdm
|
|
128
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
129
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
130
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
131
|
+
# pdm.lock
|
|
132
|
+
# pdm.toml
|
|
133
|
+
.pdm-python
|
|
134
|
+
.pdm-build/
|
|
135
|
+
|
|
136
|
+
# pixi
|
|
137
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
138
|
+
# pixi.lock
|
|
139
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
140
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
141
|
+
.pixi/*
|
|
142
|
+
!.pixi/config.toml
|
|
143
|
+
|
|
144
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
145
|
+
__pypackages__/
|
|
146
|
+
|
|
147
|
+
# Celery stuff
|
|
148
|
+
celerybeat-schedule*
|
|
149
|
+
celerybeat.pid
|
|
150
|
+
|
|
151
|
+
# Redis
|
|
152
|
+
*.rdb
|
|
153
|
+
*.aof
|
|
154
|
+
*.pid
|
|
155
|
+
|
|
156
|
+
# RabbitMQ
|
|
157
|
+
mnesia/
|
|
158
|
+
rabbitmq/
|
|
159
|
+
rabbitmq-data/
|
|
160
|
+
|
|
161
|
+
# ActiveMQ
|
|
162
|
+
activemq-data/
|
|
163
|
+
|
|
164
|
+
# SageMath parsed files
|
|
165
|
+
*.sage.py
|
|
166
|
+
|
|
167
|
+
# Environments
|
|
168
|
+
.env
|
|
169
|
+
.envrc
|
|
170
|
+
.venv
|
|
171
|
+
env/
|
|
172
|
+
venv/
|
|
173
|
+
ENV/
|
|
174
|
+
env.bak/
|
|
175
|
+
venv.bak/
|
|
176
|
+
|
|
177
|
+
# Spyder project settings
|
|
178
|
+
.spyderproject
|
|
179
|
+
.spyproject
|
|
180
|
+
|
|
181
|
+
# Rope project settings
|
|
182
|
+
.ropeproject
|
|
183
|
+
|
|
184
|
+
# mkdocs documentation
|
|
185
|
+
/site
|
|
186
|
+
|
|
187
|
+
# mypy
|
|
188
|
+
.mypy_cache/
|
|
189
|
+
.dmypy.json
|
|
190
|
+
dmypy.json
|
|
191
|
+
|
|
192
|
+
# Pyre type checker
|
|
193
|
+
.pyre/
|
|
194
|
+
|
|
195
|
+
# pytype static type analyzer
|
|
196
|
+
.pytype/
|
|
197
|
+
|
|
198
|
+
# Cython debug symbols
|
|
199
|
+
cython_debug/
|
|
200
|
+
|
|
201
|
+
# PyCharm
|
|
202
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
203
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
204
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
205
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
206
|
+
# .idea/
|
|
207
|
+
|
|
208
|
+
# Abstra
|
|
209
|
+
# Abstra is an AI-powered process automation framework.
|
|
210
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
211
|
+
# Learn more at https://abstra.io/docs
|
|
212
|
+
.abstra/
|
|
213
|
+
|
|
214
|
+
# Visual Studio Code
|
|
215
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
216
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
217
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
218
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
219
|
+
# .vscode/
|
|
220
|
+
# Temporary file for partial code execution
|
|
221
|
+
tempCodeRunnerFile.py
|
|
222
|
+
|
|
223
|
+
# Ruff stuff:
|
|
224
|
+
.ruff_cache/
|
|
225
|
+
|
|
226
|
+
# PyPI configuration file
|
|
227
|
+
.pypirc
|
|
228
|
+
|
|
229
|
+
# Marimo
|
|
230
|
+
marimo/_static/
|
|
231
|
+
marimo/_lsp/
|
|
232
|
+
__marimo__/
|
|
233
|
+
|
|
234
|
+
# Streamlit
|
|
235
|
+
.streamlit/secrets.toml
|
|
236
|
+
|
|
237
|
+
## C++
|
|
238
|
+
# Prerequisites
|
|
239
|
+
*.d
|
|
240
|
+
|
|
241
|
+
# Compiled Object files
|
|
242
|
+
*.slo
|
|
243
|
+
*.lo
|
|
244
|
+
*.o
|
|
245
|
+
*.obj
|
|
246
|
+
|
|
247
|
+
# Precompiled Headers
|
|
248
|
+
*.gch
|
|
249
|
+
*.pch
|
|
250
|
+
|
|
251
|
+
# Linker files
|
|
252
|
+
*.ilk
|
|
253
|
+
|
|
254
|
+
# Debugger Files
|
|
255
|
+
*.pdb
|
|
256
|
+
|
|
257
|
+
# Compiled Dynamic libraries
|
|
258
|
+
*.so
|
|
259
|
+
*.dylib
|
|
260
|
+
*.dll
|
|
261
|
+
*.so.*
|
|
262
|
+
|
|
263
|
+
# Fortran module files
|
|
264
|
+
*.mod
|
|
265
|
+
*.smod
|
|
266
|
+
|
|
267
|
+
# Compiled Static libraries
|
|
268
|
+
*.lai
|
|
269
|
+
*.la
|
|
270
|
+
*.a
|
|
271
|
+
*.lib
|
|
272
|
+
|
|
273
|
+
# Executables
|
|
274
|
+
*.exe
|
|
275
|
+
*.out
|
|
276
|
+
*.app
|
|
277
|
+
|
|
278
|
+
# Build directories
|
|
279
|
+
build/
|
|
280
|
+
Build/
|
|
281
|
+
build-*/
|
|
282
|
+
|
|
283
|
+
# CMake generated files
|
|
284
|
+
CMakeFiles/
|
|
285
|
+
CMakeCache.txt
|
|
286
|
+
cmake_install.cmake
|
|
287
|
+
install_manifest.txt
|
|
288
|
+
compile_commands.json
|
|
289
|
+
|
|
290
|
+
# Temporary files
|
|
291
|
+
*.tmp
|
|
292
|
+
*.log
|
|
293
|
+
*.bak
|
|
294
|
+
*.swp
|
|
295
|
+
|
|
296
|
+
# vcpkg
|
|
297
|
+
vcpkg_installed/
|
|
298
|
+
|
|
299
|
+
# debug information files
|
|
300
|
+
*.dwo
|
|
301
|
+
|
|
302
|
+
# test output & cache
|
|
303
|
+
Testing/
|
|
304
|
+
.cache/
|
pymstm-1.0.0/.gitmodules
ADDED