Note that this file is going to be AI Generated. If you're working on this, have your agent do the job.
Release tested commits from main using matching version tags and GitHub Releases.
Publish the source distribution and repaired wheels to PyPI. Wheels support
CPython 3.11–3.14 on Linux x86_64 (manylinux_2_28) and macOS 14+ on Intel and
Apple Silicon. Windows is not supported. Conda-forge packages follow recipe review.
For 0.1.1, all twelve wheels are live on PyPI. The tested source archive is
attached to the GitHub release.
PyPI rejected the archive because pele-0.1.1.tar.gz was previously uploaded
and deleted; deleted filenames cannot be reused.
The publication job therefore reports failure after successfully uploading the
wheels. Use a new version for the next PyPI release.
Keep the version identical in pyproject.toml, meson.build, and
conda-recipe/recipe.yaml. The initial version is 0.1.1.
Run both the Tests and Release artifacts workflows successfully on the release
commit. Release artifacts builds the source archive once, then builds and tests
all 12 wheels from that archive on Linux and macOS with Python 3.11–3.14,
including generated GUI forms. Python versions run in separate jobs on standard
runners. Wheel jobs build pinned native dependencies,
including macOS OpenMP. macOS jobs reuse completed dependency builds only when
the source recipe, architecture, compilers, SDK, OS and deployment target match.
macOS jobs install SHA-verified Sonoma GCC bottles
to keep the bundled Fortran runtimes compatible with macOS 14. Jobs repair the wheels
with auditwheel/delocate, then run installed-package tests with native-library
search paths cleared. The tests reject libraries loaded from the build prefix or
Homebrew. All wheel jobs must pass before publication. Distribution builds
use native=false; use -Dnative=true only for local CPU-specific builds.
The native wheel dependency builder is ci/build-wheel-deps.sh; its source URLs
and SHA256 values are pinned. LICENSE-THIRD-PARTY records redistributed-library
notices. Before changing dependencies, verify their licenses, source availability,
and ABI/macOS deployment requirements. Delocate must retain its deployment-target
checks; auditwheel must successfully repair to the declared manylinux policy.
To validate locally, first install C/C++/Fortran compilers, SUNDIALS, Eigen, LAPACK headers, and OpenMP, then run:
pip install build twine
python -m build -Csetup-args=-Dnative=false -Csetup-args=-Dlammps=disabled
python -m twine check --strict dist/pele-0.1.1.tar.gzThe default python -m build builds a source archive and then builds its wheel
from that archive. Keep the checkout committed: Meson creates the source archive
from Git's committed files. The compiled LAMMPS integration is excluded from the
generic distribution; the Python LAMMPS fallback remains available through the
lammps extra.
For a local Linux conda build outside conda-forge, supply its standard-library variants explicitly (conda-forge injects these during staging):
rattler-build build -r conda-recipe/recipe.yaml -c conda-forge \
--variant c_stdlib=sysroot --variant c_stdlib_version=2.17A fixed random seed does not guarantee identical numerical results across platforms. CPU instructions, compilers and math libraries can round intermediate operations differently. Non-convex optimization can amplify differences in the last bits and reach different stationary points, even when the initial coordinates and random-generator state agree exactly.
For example, the tested macOS ARM NumPy 2.5.4 wheel for CPython 3.14 uses a
fused multiply-add to compute
x1*x1 + x2*x2 in its legacy Gaussian conversion. Fusing the multiply and add
rounds that combined operation once; separate operations round the product first.
Replaying this arithmetic reproduced all 54 recorded macOS Gaussian values,
including six that differed from Linux despite identical generator states.
NumPy's conversion source
shows the expression involved.
The seeded LJ18 investigation
also recorded a difference of one unit in the last place (1 ULP) in the first
native minimization step. The resulting macOS saddle had exactly one unstable physical
mode and a force RMS of 8.08e-5, satisfying the 1e-4 stopping tolerance.
Its transverse curvature search nevertheless exhausted 100 iterations with an
RMS of 1.96e-5, above its separate 1e-5 tolerance. At the same fixed coordinates,
that search converged after 103 iterations when given a larger budget. A small
iteration cap can therefore reject a valid candidate on one platform while
passing on another. The trace on PR #183
reproduced this ARM result; its Intel macOS wheel trace
found the same cause, with the fixed-coordinate searches needing up to 117 iterations.
A later Intel macOS Python 3.12 trajectory trace
reused one wheel across two runners and repeated the original seeded accounting
fixture. All 44 starting configurations agreed bit for bit, but four searches
failed: three after 21 genuine positive-curvature decisions, and one after
exhausting 100 outer iterations with two unstable modes and a large force RMS.
None of the 1,064 recorded primary snapshots misclassified the curvature sign,
and evaluation accounting remained exact. In one positive-curvature failure,
independent replay confirmed a fresh force RMS of 4.85e-4, above 1e-4, and
48 positive projected physical curvatures, with the lowest +0.10566.
These were legitimate failed searches, unlike the valid saddle rejected by the
100-iteration cap. The trace reproduces the abort pattern; the earlier CI
failure's exact coordinates were not recorded. Accounting tests therefore start
near the existing known saddle, with a physical perturbation that still requires
refinement, and retain their success and exact-count assertions. A loosely
quenched random configuration does not guarantee a successful global
transition-state search within a finite iteration budget.
Create accounts on PyPI and TestPyPI. Configure a pending Trusted Publisher on each service with these values:
| Field | PyPI | TestPyPI |
|---|---|---|
| Project name | pele |
pele |
| GitHub owner | pele-python |
pele-python |
| Repository | pele |
pele |
| Workflow filename | release.yml |
release.yml |
| Environment | pypi |
testpypi |
Create the corresponding GitHub environments under Settings → Environments if they do not exist. Trusted Publishing uses GitHub's identity token; no PyPI API key is needed. A pending publisher does not reserve a package name until its first upload.
On GitHub, open Actions → Release artifacts → Run workflow. Select main and
check the TestPyPI input. Publishing begins only after every validation job passes.
A dispatch with the input unchecked validates artifacts without publishing.
Test a binary installation in a fresh supported environment:
pip install --only-binary=:all: --no-deps --index-url https://test.pypi.org/simple/ \
pele==0.1.1Install the runtime dependencies listed in pyproject.toml before using
--no-deps. Use a new version for each revised TestPyPI upload; distribution
filenames cannot be replaced.
Fetch main from pele-python/pele into a clean release checkout. Once the
workflows pass and publishing accounts are configured, create and push an
annotated tag:
git tag -a v0.1.1 -m 'pele 0.1.1'
git push https://github.com/pele-python/pele.git v0.1.1Create a GitHub Release for v0.1.1 and publish it. The Release artifacts workflow
requires the tag to match the package version, validates the distribution, and
publishes the source archive and all repaired wheels to PyPI. Creating a tag
alone does not upload a package.
The recipe in this repository uses a local source path for development builds.
For 0.1.1, use the tested GitHub release archive instead of a PyPI source URL:
source:
url: https://github.com/pele-python/pele/releases/download/v0.1.1/pele-0.1.1.tar.gz
sha256: 53cc1f0b32371551817044b21efcfa004f044fa47b64d0e7594b27adda97a3deConda-forge currently has SQLAlchemy 1.4 builds through Python 3.13. For the
initial conda recipe, require python >=3.11,<3.14 and skip other Python
variants. PyPI wheels support Python 3.14 using SQLAlchemy's Python fallback.
For future versions, use the PyPI source archive once its upload succeeds.
After the PyPI source archive is published, find its exact URL and SHA256 at
https://pypi.org/pypi/pele/<version>/json (the urls entry whose packagetype is
sdist). Replace the recipe's entire source block with:
source:
url: <the published sdist URL>
sha256: <its SHA256 digest>Copy the resulting recipe to recipes/pele/recipe.yaml in a fork of
conda-forge/staged-recipes, and
submit a pull request. Keep spraharsh under recipe-maintainers. The source URL
and checksum refer to the same tested distribution used for PyPI. Conda-forge
review and feedstock builds are required before conda install -c conda-forge pele becomes available.
For subsequent releases, publish a new version and update the version, source
checksum, and dependencies in conda-forge/pele-feedstock. Start a maintenance
branch only when an older supported release needs fixes alongside newer work.
PyPI Trusted Publishing and conda-forge submission instructions describe the account and review steps.