Updating module pins
PROTEUS pins the exact version of every module it depends on, and pyproject.toml
is the single source of truth for those pins. This page is the maintainer-side
companion to Diagnose and update: the doctor page explains how a
user brings their installation into line with the pins, while this page
explains how a maintainer changes the pins and how that change propagates
through the rest of the stack.
For the current pinned versions of every module, see the Module versions reference.
The two kinds of pin
PROTEUS uses two pinning mechanisms, and which one applies depends on how the module is distributed.
| Pin type | Where it lives in pyproject.toml |
Pin value | Modules |
|---|---|---|---|
| PyPI floor | [project] dependencies |
Minimum version bound, e.g. fwl-aragog>=26.05.13 |
fwl-janus, fwl-mors, fwl-calliope, fwl-zephyrus, fwl-aragog, fwl-zalmoxis |
| PyPI floor (optional) | [project.optional-dependencies] |
Minimum version bound on an optional backend | fwl-vulcan, atmodeller |
| Git ref | [tool.proteus.modules.<name>] |
Exact commit SHA, tag, or branch in a ref field |
AGNI, SOCRATES, SPIDER, BOREAS, LovePy |
A third entry, PETSc, is pinned in [tool.proteus.modules.petsc] by the SHA-256
of a pre-built archive rather than a git ref, because it is downloaded as a
binary from OSF.
PyPI floors are minimum bounds. When a user runs pip install -e ".[develop]",
pip resolves the newest release that satisfies every floor. The floor is the
oldest version PROTEUS supports, not an exact pin, so a user may legitimately
have a newer release installed than the floor names.
Git refs are exact. A commit SHA reproduces the same external source every time, which is why CI and local installs of the same PROTEUS commit build identical AGNI, SOCRATES, and SPIDER checkouts.
How the update process works
Everything downstream reads from the same table, so a pin only needs to be changed in one place:
tools/get_*.shread git pins throughtools/_module_pins.py(python tools/_module_pins.py agni refprints the pinned AGNI commit) and clone or check out that ref.- pip resolves the PyPI floors at install time.
- The CI composite action reads
[tool.proteus.modules]so branch builds use exactly the pinned external state. tools/generate_version_badges.pyrewrites the badge tables in the Module versions reference from the same pins.proteus doctorandproteus updatecompare an installation against the pins and report or apply fixes (see Diagnose and update). Git-commit drift is checked for AGNI and SOCRATES; the other git modules are pinned but not drift-checked by the doctor.
Because of this, bumping a module is a single-line edit followed by a badge refresh and a local re-sync.
Procedure
-
Edit the pin in
pyproject.toml.- PyPI module: change the floor in
[project] dependencies, for examplefwl-calliope>=26.06.01. - Git module: change the
refin[tool.proteus.modules.<name>]to the new commit SHA, tag, or branch.
- PyPI module: change the floor in
-
Regenerate the badge tables:
python tools/generate_version_badges.pyThis updates the markers in
docs/Reference/module_versions.mdso the reference page matches the new pins. Commit the regenerated page alongsidepyproject.toml. -
Bring your own installation into line with the new pin:
- PyPI module:
proteus update(orpip install -U "<name>>=<version>"for a wheel install). - Git module:
bash tools/get_<module>.sh(for SOCRATES, add--forceto discard local modifications to the checkout, that is, changes to tracked files or commits not pushed to a remote; the compiled build tree is left in place).
- PyPI module:
-
Verify:
proteus doctorThe failing or drifted check now reads
ok. -
Commit and open a pull request containing both the
pyproject.tomledit and the regeneratedmodule_versions.md. CI uses the same pins, so the build is reproducible from the branch alone.
Keep the badge page in the same commit
tools/generate_version_badges.py only rewrites content between the
<!-- BEGIN ... --> and <!-- END ... --> markers, so the regenerated diff
is small. Committing it with the pin change keeps the reference page from
drifting out of sync with pyproject.toml.
Case examples
Case 1: bump a PyPI module to a new release
A new fwl-calliope release is out and PROTEUS should adopt it. Raise the floor
in [project] dependencies:
- "fwl-calliope>=26.05.13",
+ "fwl-calliope>=26.06.01",
Then refresh the badges and re-sync:
python tools/generate_version_badges.py
proteus update # pulls the new release into the active environment
proteus doctor # fwl-calliope now reports ok
For an editable checkout, proteus update runs git pull && pip install -e .
in the CALLIOPE checkout instead of fetching a wheel.
Case 2: move a git module to a new commit
AGNI has merged a fix PROTEUS needs. Replace the ref in
[tool.proteus.modules.agni] with the new commit SHA:
[tool.proteus.modules.agni]
url = "https://github.com/nichollsh/AGNI.git"
- ref = "b06a3fed51e0f1610556634d5b5a5e0425428f0e"
+ ref = "179472b36b14e15bb125666cd8c9c6f231a2e907"
Refresh the badges, then check out the pinned commit and rebuild:
python tools/generate_version_badges.py
bash tools/get_agni.sh
proteus doctor # the AGNI commit-drift warning clears
Before the re-sync, proteus doctor reports the drift explicitly, for example
AGNI: 1.10.1 (bf65a56c) differs from pin (179472b). After get_agni.sh
checks out the pinned SHA, the check reads ok.
Case 3: choose between a commit, a tag, and a branch
The ref field accepts a commit SHA, a tag, or a branch name. They trade
reproducibility against convenience:
- Commit SHA (AGNI, SOCRATES, SPIDER): fully reproducible. The same PROTEUS commit always builds the same external source. Use this for any module whose exact state affects simulation results.
- Tag: reproducible as long as the upstream tag is not moved. Convenient when a module publishes named releases.
- Branch (LovePy tracks
main): always pulls the latest commit on that branch, so two installs of the same PROTEUS commit can differ. Acceptable only for optional modules where exact reproducibility is not required.
When in doubt, pin to a commit SHA. A branch pin is a deliberate choice to follow upstream, not a default.
Some modules deliberately have no git entry
VULCAN, like fwl-aragog and fwl-zalmoxis, is a single-source PyPI package, so
it is pinned only by its floor in [project.optional-dependencies]. Its
setup script checks out the git tag matching that floor, so the editable
checkout and the published release cannot diverge. Do not add a second pin
for these in [tool.proteus.modules].
Propagating the change to other developers
Once the pin change is merged, other developers pick it up the same way a user applies any pin change:
git pull
proteus update
This re-syncs every module whose installed version no longer satisfies the new
pin. When several components move at once (for example after a large merge),
proteus update-all performs a full refresh of the whole stack. Both commands
are documented in Diagnose and update.
See also: Diagnose and update | Module versions reference | Development standards | Installation