acellera-gufe 1.13.1__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.
Files changed (175) hide show
  1. acellera_gufe-1.13.1/.git-blame-ignore-revs +4 -0
  2. acellera_gufe-1.13.1/.gitattributes +0 -0
  3. acellera_gufe-1.13.1/.github/PULL_REQUEST_TEMPLATE/release-prep.md +22 -0
  4. acellera_gufe-1.13.1/.github/pull_request_template.md +27 -0
  5. acellera_gufe-1.13.1/.github/workflows/ci.yaml +153 -0
  6. acellera_gufe-1.13.1/.github/workflows/clean_cache.yaml +31 -0
  7. acellera_gufe-1.13.1/.github/workflows/conda_cron.yaml +91 -0
  8. acellera_gufe-1.13.1/.github/workflows/griffe-api-break-check.yaml +59 -0
  9. acellera_gufe-1.13.1/.github/workflows/griffe-api-break-comment.yaml +103 -0
  10. acellera_gufe-1.13.1/.github/workflows/mypy.yaml +45 -0
  11. acellera_gufe-1.13.1/.gitignore +165 -0
  12. acellera_gufe-1.13.1/.pre-commit-config.yaml +41 -0
  13. acellera_gufe-1.13.1/.readthedocs.yaml +24 -0
  14. acellera_gufe-1.13.1/CITATION.cff +55 -0
  15. acellera_gufe-1.13.1/LICENSE +21 -0
  16. acellera_gufe-1.13.1/MANIFEST.in +8 -0
  17. acellera_gufe-1.13.1/PKG-INFO +56 -0
  18. acellera_gufe-1.13.1/README.md +35 -0
  19. acellera_gufe-1.13.1/devtools/raise-or-close-issue.py +29 -0
  20. acellera_gufe-1.13.1/docs/CHANGELOG.rst +302 -0
  21. acellera_gufe-1.13.1/docs/Makefile +20 -0
  22. acellera_gufe-1.13.1/docs/_static/.gitkeep +0 -0
  23. acellera_gufe-1.13.1/docs/_static/alchemical_network_diagram.svg +460 -0
  24. acellera_gufe-1.13.1/docs/_static/gufe_protocol_diagram.svg +922 -0
  25. acellera_gufe-1.13.1/docs/_static/ligand_network_diagram.svg +315 -0
  26. acellera_gufe-1.13.1/docs/api.rst +23 -0
  27. acellera_gufe-1.13.1/docs/concepts/included_models.rst +294 -0
  28. acellera_gufe-1.13.1/docs/concepts/index.rst +15 -0
  29. acellera_gufe-1.13.1/docs/concepts/logging.rst +173 -0
  30. acellera_gufe-1.13.1/docs/concepts/serialization.rst +20 -0
  31. acellera_gufe-1.13.1/docs/concepts/tokenizables.rst +378 -0
  32. acellera_gufe-1.13.1/docs/conf.py +90 -0
  33. acellera_gufe-1.13.1/docs/environment.yaml +12 -0
  34. acellera_gufe-1.13.1/docs/how-tos/component.rst +150 -0
  35. acellera_gufe-1.13.1/docs/how-tos/custom_quantities.rst +28 -0
  36. acellera_gufe-1.13.1/docs/how-tos/index.rst +17 -0
  37. acellera_gufe-1.13.1/docs/how-tos/protocol.rst +797 -0
  38. acellera_gufe-1.13.1/docs/how-tos/serialization.rst +253 -0
  39. acellera_gufe-1.13.1/docs/index.rst +50 -0
  40. acellera_gufe-1.13.1/docs/installation.rst +67 -0
  41. acellera_gufe-1.13.1/docs/make.bat +35 -0
  42. acellera_gufe-1.13.1/environment.yml +25 -0
  43. acellera_gufe-1.13.1/news/TEMPLATE.rst +23 -0
  44. acellera_gufe-1.13.1/pyproject.toml +101 -0
  45. acellera_gufe-1.13.1/rever.xsh +7 -0
  46. acellera_gufe-1.13.1/setup.cfg +4 -0
  47. acellera_gufe-1.13.1/src/acellera_gufe.egg-info/PKG-INFO +56 -0
  48. acellera_gufe-1.13.1/src/acellera_gufe.egg-info/SOURCES.txt +173 -0
  49. acellera_gufe-1.13.1/src/acellera_gufe.egg-info/dependency_links.txt +1 -0
  50. acellera_gufe-1.13.1/src/acellera_gufe.egg-info/not-zip-safe +1 -0
  51. acellera_gufe-1.13.1/src/acellera_gufe.egg-info/top_level.txt +1 -0
  52. acellera_gufe-1.13.1/src/gufe/__init__.py +36 -0
  53. acellera_gufe-1.13.1/src/gufe/archival.py +111 -0
  54. acellera_gufe-1.13.1/src/gufe/chemicalsystem.py +203 -0
  55. acellera_gufe-1.13.1/src/gufe/components/__init__.py +7 -0
  56. acellera_gufe-1.13.1/src/gufe/components/component.py +42 -0
  57. acellera_gufe-1.13.1/src/gufe/components/errors.py +6 -0
  58. acellera_gufe-1.13.1/src/gufe/components/explicitmoleculecomponent.py +163 -0
  59. acellera_gufe-1.13.1/src/gufe/components/proteincomponent.py +768 -0
  60. acellera_gufe-1.13.1/src/gufe/components/smallmoleculecomponent.py +362 -0
  61. acellera_gufe-1.13.1/src/gufe/components/solvatedpdbcomponent.py +510 -0
  62. acellera_gufe-1.13.1/src/gufe/components/solventcomponent.py +151 -0
  63. acellera_gufe-1.13.1/src/gufe/compression.py +16 -0
  64. acellera_gufe-1.13.1/src/gufe/custom_typing.py +8 -0
  65. acellera_gufe-1.13.1/src/gufe/ligandnetwork.py +253 -0
  66. acellera_gufe-1.13.1/src/gufe/mapping/__init__.py +9 -0
  67. acellera_gufe-1.13.1/src/gufe/mapping/atom_mapper.py +28 -0
  68. acellera_gufe-1.13.1/src/gufe/mapping/atom_mapping.py +48 -0
  69. acellera_gufe-1.13.1/src/gufe/mapping/componentmapping.py +33 -0
  70. acellera_gufe-1.13.1/src/gufe/mapping/errors.py +6 -0
  71. acellera_gufe-1.13.1/src/gufe/mapping/ligandatommapping.py +328 -0
  72. acellera_gufe-1.13.1/src/gufe/molhashing.py +31 -0
  73. acellera_gufe-1.13.1/src/gufe/network.py +132 -0
  74. acellera_gufe-1.13.1/src/gufe/protocols/__init__.py +15 -0
  75. acellera_gufe-1.13.1/src/gufe/protocols/errors.py +44 -0
  76. acellera_gufe-1.13.1/src/gufe/protocols/protocol.py +420 -0
  77. acellera_gufe-1.13.1/src/gufe/protocols/protocoldag.py +584 -0
  78. acellera_gufe-1.13.1/src/gufe/protocols/protocolunit.py +445 -0
  79. acellera_gufe-1.13.1/src/gufe/serialization/__init__.py +0 -0
  80. acellera_gufe-1.13.1/src/gufe/serialization/json.py +363 -0
  81. acellera_gufe-1.13.1/src/gufe/serialization/msgpack.py +152 -0
  82. acellera_gufe-1.13.1/src/gufe/settings/__init__.py +5 -0
  83. acellera_gufe-1.13.1/src/gufe/settings/models.py +214 -0
  84. acellera_gufe-1.13.1/src/gufe/settings/typing.py +154 -0
  85. acellera_gufe-1.13.1/src/gufe/storage/__init__.py +1 -0
  86. acellera_gufe-1.13.1/src/gufe/storage/errors.py +17 -0
  87. acellera_gufe-1.13.1/src/gufe/storage/externalresource/__init__.py +3 -0
  88. acellera_gufe-1.13.1/src/gufe/storage/externalresource/base.py +216 -0
  89. acellera_gufe-1.13.1/src/gufe/storage/externalresource/filestorage.py +81 -0
  90. acellera_gufe-1.13.1/src/gufe/storage/externalresource/memorystorage.py +50 -0
  91. acellera_gufe-1.13.1/src/gufe/tests/__init__.py +1 -0
  92. acellera_gufe-1.13.1/src/gufe/tests/conftest.py +415 -0
  93. acellera_gufe-1.13.1/src/gufe/tests/data/181l.cif +2663 -0
  94. acellera_gufe-1.13.1/src/gufe/tests/data/181l.pdb +2657 -0
  95. acellera_gufe-1.13.1/src/gufe/tests/data/181l_openmmClean.cif +2693 -0
  96. acellera_gufe-1.13.1/src/gufe/tests/data/181l_wrapped_over_pbc.pdb.gz +0 -0
  97. acellera_gufe-1.13.1/src/gufe/tests/data/__init__.py +2 -0
  98. acellera_gufe-1.13.1/src/gufe/tests/data/a2a.cif.gz +0 -0
  99. acellera_gufe-1.13.1/src/gufe/tests/data/a2a.pdb.gz +0 -0
  100. acellera_gufe-1.13.1/src/gufe/tests/data/a2a_single_fragment.pdb.gz +0 -0
  101. acellera_gufe-1.13.1/src/gufe/tests/data/alchemical_archive.json +1 -0
  102. acellera_gufe-1.13.1/src/gufe/tests/data/all_settings.json +25 -0
  103. acellera_gufe-1.13.1/src/gufe/tests/data/atropisomeric_mol.sdf +58 -0
  104. acellera_gufe-1.13.1/src/gufe/tests/data/benzene_modifications.sdf +240 -0
  105. acellera_gufe-1.13.1/src/gufe/tests/data/ethane.sdf +25 -0
  106. acellera_gufe-1.13.1/src/gufe/tests/data/hif2a_solvent_1_155.cif.gz +0 -0
  107. acellera_gufe-1.13.1/src/gufe/tests/data/hif2a_solvent_1_155.pdb.gz +0 -0
  108. acellera_gufe-1.13.1/src/gufe/tests/data/ligand_network.graphml +28 -0
  109. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/1,3,7-trimethylnaphthalene.mol2 +63 -0
  110. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/1-butyl-4-methylbenzene.mol2 +62 -0
  111. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/2,6-dimethylnaphthalene.mol2 +57 -0
  112. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/2-methyl-6-propylnaphthalene.mol2 +69 -0
  113. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/2-methylnaphthalene.mol2 +51 -0
  114. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/2-naftanol.mol2 +47 -0
  115. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/README.md +1 -0
  116. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/__init__.py +0 -0
  117. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/methylcyclohexane.mol2 +50 -0
  118. acellera_gufe-1.13.1/src/gufe/tests/data/lomap_basic/toluene.mol2 +38 -0
  119. acellera_gufe-1.13.1/src/gufe/tests/data/multi_molecule.sdf +22 -0
  120. acellera_gufe-1.13.1/src/gufe/tests/data/offxml_settings.json +18 -0
  121. acellera_gufe-1.13.1/src/gufe/tests/data/pxr_1nrl.pdb.gz +0 -0
  122. acellera_gufe-1.13.1/src/gufe/tests/data/toluene.mol2 +38 -0
  123. acellera_gufe-1.13.1/src/gufe/tests/dev/__init__.py +0 -0
  124. acellera_gufe-1.13.1/src/gufe/tests/dev/serialization_test_templates.py +30 -0
  125. acellera_gufe-1.13.1/src/gufe/tests/storage/test_externalresource.py +254 -0
  126. acellera_gufe-1.13.1/src/gufe/tests/test_alchemicalnetwork.py +72 -0
  127. acellera_gufe-1.13.1/src/gufe/tests/test_archival.py +121 -0
  128. acellera_gufe-1.13.1/src/gufe/tests/test_chemicalsystem.py +179 -0
  129. acellera_gufe-1.13.1/src/gufe/tests/test_explicitmoleculecomponent.py +54 -0
  130. acellera_gufe-1.13.1/src/gufe/tests/test_ligand_network.py +385 -0
  131. acellera_gufe-1.13.1/src/gufe/tests/test_ligandatommapping.py +401 -0
  132. acellera_gufe-1.13.1/src/gufe/tests/test_mapping +0 -0
  133. acellera_gufe-1.13.1/src/gufe/tests/test_mapping.py +67 -0
  134. acellera_gufe-1.13.1/src/gufe/tests/test_mapping_visualization.py +269 -0
  135. acellera_gufe-1.13.1/src/gufe/tests/test_models.py +484 -0
  136. acellera_gufe-1.13.1/src/gufe/tests/test_molhashing.py +21 -0
  137. acellera_gufe-1.13.1/src/gufe/tests/test_proteincomponent.py +492 -0
  138. acellera_gufe-1.13.1/src/gufe/tests/test_protocol.py +916 -0
  139. acellera_gufe-1.13.1/src/gufe/tests/test_protocoldag.py +313 -0
  140. acellera_gufe-1.13.1/src/gufe/tests/test_protocolresult.py +56 -0
  141. acellera_gufe-1.13.1/src/gufe/tests/test_protocolunit.py +142 -0
  142. acellera_gufe-1.13.1/src/gufe/tests/test_serialization_json.py +382 -0
  143. acellera_gufe-1.13.1/src/gufe/tests/test_serialization_migration.py +266 -0
  144. acellera_gufe-1.13.1/src/gufe/tests/test_serialization_msgpack.py +113 -0
  145. acellera_gufe-1.13.1/src/gufe/tests/test_smallmoleculecomponent.py +515 -0
  146. acellera_gufe-1.13.1/src/gufe/tests/test_solvatedpdbcomponent.py +378 -0
  147. acellera_gufe-1.13.1/src/gufe/tests/test_solvents.py +94 -0
  148. acellera_gufe-1.13.1/src/gufe/tests/test_tokenization.py +659 -0
  149. acellera_gufe-1.13.1/src/gufe/tests/test_transformation.py +336 -0
  150. acellera_gufe-1.13.1/src/gufe/tests/test_utils.py +259 -0
  151. acellera_gufe-1.13.1/src/gufe/tokenization.py +1274 -0
  152. acellera_gufe-1.13.1/src/gufe/transformations/__init__.py +3 -0
  153. acellera_gufe-1.13.1/src/gufe/transformations/transformation.py +387 -0
  154. acellera_gufe-1.13.1/src/gufe/utils.py +286 -0
  155. acellera_gufe-1.13.1/src/gufe/vendor/__init__.py +0 -0
  156. acellera_gufe-1.13.1/src/gufe/vendor/openff/__init__.py +0 -0
  157. acellera_gufe-1.13.1/src/gufe/vendor/openff/interchange/__init__.py +0 -0
  158. acellera_gufe-1.13.1/src/gufe/vendor/openff/interchange/_annotations.py +41 -0
  159. acellera_gufe-1.13.1/src/gufe/vendor/openff/interchange/_packmol.py +29 -0
  160. acellera_gufe-1.13.1/src/gufe/vendor/openff/interchange/pydantic.py +21 -0
  161. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/PdbxContainers.py +837 -0
  162. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/PdbxReader.py +459 -0
  163. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/__init__.py +0 -0
  164. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/data/pdbNames.xml +278 -0
  165. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/data/residues.xml +902 -0
  166. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/data/residues_orig.xml +902 -0
  167. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/element.py +315 -0
  168. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/pdbfile.py +627 -0
  169. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/pdbstructure.py +1189 -0
  170. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/pdbxfile.py +504 -0
  171. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/singelton.py +17 -0
  172. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/topology.py +588 -0
  173. acellera_gufe-1.13.1/src/gufe/vendor/pdb_file/unitcell.py +125 -0
  174. acellera_gufe-1.13.1/src/gufe/visualization/__init__.py +5 -0
  175. acellera_gufe-1.13.1/src/gufe/visualization/mapping_visualization.py +563 -0
@@ -0,0 +1,4 @@
1
+ # https://github.com/OpenFreeEnergy/gufe/pull/421 -- big auto format MMH
2
+ d27100a5b7b303df155e2b6d7874883d105e24bf
3
+ # https://github.com/OpenFreeEnergy/gufe/pull/431 -- fix some files that didn't get formatted MMH
4
+ f8c49d59e756130a995d02dfe04d7a91acb1d791
File without changes
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: Release preparation
3
+ about: Prepare a new release for this package
4
+ title: 'Release : '
5
+ labels: 'release-prep'
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ To create a new release, please do the following:
11
+ - [ ] make any changes to the repo needed to accommodate the release
12
+ - [ ] check `environment.yml` for any updates needed; create any issues needed to update versions in next release cycle
13
+ - [ ] run [`rever`](https://regro.github.io/rever-docs/index.html#rever-releaser-of-versions) to generate the `CHANGELOG` entry from `news` items: `rever <version_number>`
14
+ - inspect `CHANGELOG`, adjust as necessary
15
+ - [ ] merge this PR into `main`
16
+
17
+
18
+ After you have merged this PR, please also:
19
+ - [ ] create a release here in GitHub, including generating detailed release notes
20
+ - [ ] in the summary release notes, also link to the `CHANGELOG` entry for this release in the `gufe` docs
21
+ - [ ] await automated PR on `conda-forge` [`gufe-feedstock` `meta.yaml`](https://github.com/conda-forge/gufe-feedstock/blob/main/recipe/meta.yaml)
22
+ - [ ] review and merge
@@ -0,0 +1,27 @@
1
+ <!--
2
+ Thank you for pull request.
3
+ Below are a few things we ask you kindly to self-check before getting a review. Remove checks that are not relevant.
4
+ -->
5
+
6
+ <!--
7
+ Please note any issues this fixes using [closing keywords]( https://help.github.com/articles/closing-issues-using-keywords/ ):
8
+ -->
9
+
10
+ <!--
11
+ see https://regro.github.io/rever-docs/news.html for details on how to add news entry (you do not need to run the rever command)
12
+ -->
13
+ Tips
14
+ * Comment "pre-commit.ci autofix" to have pre-commit.ci atomically format your PR.
15
+ Since this will create a commit, it is best to make this comment when you are finished with your work.
16
+
17
+ ## LLM / AI generated code disclosure
18
+ <!-- Please update this disclosure to reflect if you did or did not use LLMs / AI to generate code -->
19
+ LLMs or other AI-powered tools (beyond simple IDE use cases) were used in this contribution: yes / no
20
+ If yes, please provide details here:
21
+
22
+ ## Checklist
23
+ * [ ] Added a ``news`` entry
24
+ * [ ] Filled in the AI-generated code disclosure.
25
+
26
+ ## Developers certificate of origin
27
+ - [ ] I certify that this contribution is covered by the MIT License [here](https://github.com/OpenFreeEnergy/openfe/blob/main/LICENSE) and the **Developer Certificate of Origin** at <https://developercertificate.org/>.
@@ -0,0 +1,153 @@
1
+ name: "CI"
2
+ on:
3
+ # Allow for workflows to be manuallly triggered
4
+ workflow_dispatch:
5
+ pull_request:
6
+ push:
7
+ branches:
8
+ - main
9
+ - stable
10
+ - epic/*
11
+ - release
12
+ schedule:
13
+ # At 07:00 UTC on Monday and Thursday.
14
+ - cron: "0 7 * * *"
15
+
16
+ concurrency:
17
+ group: "${{ github.workflow }}-${{ github.ref }}"
18
+ cancel-in-progress: true
19
+
20
+ defaults:
21
+ run:
22
+ shell: bash -leo pipefail {0}
23
+
24
+ jobs:
25
+ tests:
26
+ runs-on: ${{ matrix.OS }}
27
+ name: "💻-${{matrix.os }} 🐍-${{ matrix.python-version }} 🎨-${{ matrix.py3Dmol }}"
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ os: ['ubuntu-latest']
32
+ py3Dmol: ["no"]
33
+ python-version:
34
+ - "3.12"
35
+ - "3.13"
36
+ - "3.14"
37
+ include:
38
+ - os: "macos-latest"
39
+ python-version: "3.14"
40
+ - os: "ubuntu-latest"
41
+ python-version: "3.12"
42
+ py3Dmol: "yes"
43
+
44
+ env:
45
+ OE_LICENSE: ${{ github.workspace }}/oe_license.txt
46
+
47
+ steps:
48
+ - uses: actions/checkout@v6
49
+ with:
50
+ fetch-depth: 0
51
+
52
+ - name: "Setup Micromamba"
53
+ uses: mamba-org/setup-micromamba@v3
54
+ with:
55
+ micromamba-binary-path: ~/.local/bin/micromamba
56
+ environment-file: environment.yml
57
+ environment-name: gufe
58
+ cache-environment: true
59
+ cache-downloads: true
60
+ create-args: >-
61
+ python=${{ matrix.python-version }}
62
+ init-shell: bash
63
+
64
+ - name: "Install py3Dmol (optional)"
65
+ if: ${{ matrix.py3Dmol == 'yes' }}
66
+ run: micromamba install py3Dmol
67
+
68
+
69
+ - name: "Install"
70
+ run: python -m pip install --no-deps -e .
71
+
72
+ - name: "Test imports"
73
+ run: |
74
+ # if we add more to this, consider changing to for + env vars
75
+ python -Ic "import gufe; print(gufe.__version__)"
76
+
77
+ - name: "Environment Information"
78
+ run: |
79
+ micromamba info
80
+ micromamba list
81
+
82
+ - name: Cache Pooch data
83
+ uses: actions/cache@v5
84
+ with:
85
+ path: |
86
+ # linux cache location
87
+ ~/.cache/gufe
88
+ # osx cache location
89
+ ~/Library/Caches/gufe
90
+ # When files are added or changed in a pooch registry
91
+ # bump this key to create a new cache, for example if
92
+ # the key is pooch-${{ matrix.os }}-1 change it to pooch-${{ matrix.os }}-2
93
+ key: pooch-${{ matrix.os }}-0
94
+
95
+ - name: "Run tests"
96
+ run: |
97
+ pytest -n 2 -v --cov=gufe --cov-report=xml
98
+
99
+ - name: codecov
100
+ if: ${{ github.repository == 'OpenFreeEnergy/gufe'
101
+ && github.event != 'schedule' }}
102
+ uses: codecov/codecov-action@v5
103
+ with:
104
+ token: ${{ secrets.CODECOV_TOKEN }}
105
+ files: coverage.xml
106
+ fail_ci_if_error: False
107
+ verbose: True
108
+
109
+
110
+ package_build_and_test:
111
+ runs-on: ubuntu-latest
112
+ name: "package build and install test"
113
+
114
+ steps:
115
+ - uses: actions/checkout@v6
116
+ with:
117
+ fetch-depth: 0
118
+
119
+ - name: "Setup Micromamba"
120
+ uses: mamba-org/setup-micromamba@v3
121
+ with:
122
+ environment-file: environment.yml
123
+ environment-name: gufe
124
+ cache-environment: true
125
+ cache-downloads: true
126
+ create-args: >-
127
+ python=3.12
128
+ init-shell: bash
129
+
130
+ - name: "install extra deps"
131
+ run: pip install pipx wheel twine readme-renderer
132
+
133
+ - name: "build sdist"
134
+ run: pipx run build --sdist --outdir dist
135
+
136
+ - name: "check package build"
137
+ run: |
138
+ dist=$(ls -t1 dist/gufe-*tar.gz | head -n1)
139
+ test -n "${dist}" || { echo "no distribution found"; exit 1; }
140
+ twine check $dist
141
+
142
+ - name: "install from source dist"
143
+ working-directory: ./dist
144
+ run: python -m pip install gufe-*tar.gz
145
+
146
+ - name: "install checks"
147
+ working-directory: ./dist
148
+ run: |
149
+ python -Ic "import gufe; print(gufe.__version__)"
150
+
151
+ - name: "run tests"
152
+ working-directory: ./dist
153
+ run: pytest -n auto --pyargs gufe
@@ -0,0 +1,31 @@
1
+ # from https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manage-caches#force-deleting-cache-entries
2
+ name: Cleanup github runner caches on closed pull requests
3
+ on:
4
+ workflow_dispatch:
5
+ pull_request:
6
+ types:
7
+ - closed
8
+
9
+ jobs:
10
+ cleanup:
11
+ runs-on: ubuntu-latest
12
+ permissions:
13
+ actions: write
14
+ steps:
15
+ - name: Cleanup
16
+ run: |
17
+ echo "Fetching list of cache keys"
18
+ cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id')
19
+
20
+ ## Setting this to not fail the workflow while deleting cache keys.
21
+ set +e
22
+ echo "Deleting caches..."
23
+ for cacheKey in $cacheKeysForPR
24
+ do
25
+ gh cache delete $cacheKey
26
+ done
27
+ echo "Done"
28
+ env:
29
+ GH_TOKEN: ${{ github.token }}
30
+ GH_REPO: ${{ github.repository }}
31
+ BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge
@@ -0,0 +1,91 @@
1
+ name: "conda_cron"
2
+ on:
3
+ # Allow for manual trigger of workflow
4
+ workflow_dispatch:
5
+ schedule:
6
+ # At 07:00 UTC every day
7
+ - cron: "0 7 * * *"
8
+
9
+ concurrency:
10
+ group: "${{ github.workflow }}-${{ github.ref }}"
11
+ cancel-in-progress: true
12
+
13
+ defaults:
14
+ run:
15
+ shell: bash -leo pipefail {0}
16
+
17
+ jobs:
18
+ condacheck:
19
+ runs-on: ${{ matrix.OS }}
20
+ name: "daily conda check"
21
+ strategy:
22
+ fail-fast: false
23
+ matrix:
24
+ os: ['ubuntu-latest', 'macos-latest']
25
+ python-version:
26
+ - "3.11"
27
+ - "3.12"
28
+ - "3.13"
29
+
30
+ steps:
31
+ - name: Checkout Code
32
+ uses: actions/checkout@v6
33
+ with:
34
+ fetch-depth: 0
35
+ path: gufe_repo
36
+
37
+ - name: Get Latest Version
38
+ id: latest-version
39
+ working-directory: gufe_repo
40
+ run: |
41
+ REPO="${{ github.repository }}"
42
+ VERSION=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
43
+ "https://api.github.com/repos/$REPO/releases/latest" | jq -r '.tag_name | ltrimstr("v")')
44
+ echo $VERSION
45
+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
46
+
47
+ - name: setup micromamba
48
+ uses: mamba-org/setup-micromamba@v2
49
+ with:
50
+ environment-name: gufe
51
+ cache-environment: true
52
+ cache-downloads: true
53
+ create-args: >-
54
+ python=${{ matrix.python-version }}
55
+ gufe=${{ steps.latest-version.outputs.VERSION }}
56
+ pooch
57
+ pytest
58
+ pytest-xdist
59
+ pygithub
60
+ condarc: |
61
+ channels:
62
+ - conda-forge
63
+ init-shell: bash
64
+
65
+ - name: Cache Pooch data
66
+ uses: actions/cache@v5
67
+ with:
68
+ path: |
69
+ # linux cache location
70
+ ~/.cache/gufe
71
+ # osx cache location
72
+ ~/Library/Caches/gufe
73
+ # When files are added or changed in a pooch registry
74
+ # bump this key to create a new cache, for example if
75
+ # the key is pooch-${{ matrix.os }}-1 change it to pooch-${{ matrix.os }}-2
76
+ key: pooch-${{ matrix.os }}-0
77
+
78
+ - id: run-tests
79
+ name: run tests
80
+ run: |
81
+ python -c 'import gufe;print(gufe.__version__)'
82
+ pytest -n auto --pyargs gufe
83
+
84
+ - name: raise-or-close-issue
85
+ if: ${{ always() }}
86
+ working-directory: gufe_repo
87
+ env:
88
+ CI_OUTCOME: ${{ steps.run-tests.outcome }}
89
+ TITLE: "[CI] CONDA CRON FAILURE ${{ matrix.os }} python ${{ matrix.python-version }}"
90
+ GITHUB_TOKEN: ${{ github.token }}
91
+ run: python devtools/raise-or-close-issue.py
@@ -0,0 +1,59 @@
1
+ name: "API break check"
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ defaults:
12
+ run:
13
+ shell: bash -leo pipefail {0}
14
+
15
+ jobs:
16
+ griffe:
17
+ runs-on: ubuntu-latest
18
+
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ with:
22
+ fetch-depth: 0
23
+ persist-credentials: false
24
+
25
+ - name: Fetch base branch
26
+ run: |
27
+ git fetch --no-tags origin "${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }}"
28
+
29
+ - uses: actions/setup-python@v5
30
+ with:
31
+ python-version: "3.14"
32
+
33
+ - name: Run Griffe
34
+ id: griffe
35
+ run: |
36
+ python -m pip install -U griffe
37
+
38
+ mkdir -p api-break-result
39
+ set +e
40
+
41
+ {
42
+ echo '$ griffe check "gufe" -s src --no-inspection --no-color --verbose -a origin/${{ github.base_ref }}'
43
+ griffe check "gufe" -s src --no-inspection --no-color --verbose -a "origin/${{ github.base_ref }}"
44
+ status=$?
45
+ } > api-break-result/griffe.log 2>&1
46
+
47
+ echo "status=$status" >> "$GITHUB_OUTPUT"
48
+
49
+ - name: Upload Griffe result
50
+ if: always()
51
+ uses: actions/upload-artifact@v4
52
+ with:
53
+ name: api-break-result
54
+ path: api-break-result/
55
+ retention-days: 7
56
+
57
+ - name: Fail if API break detected
58
+ if: steps.griffe.outputs.status != '0'
59
+ run: exit 1
@@ -0,0 +1,103 @@
1
+ name: "API break check comment"
2
+
3
+ on:
4
+ workflow_run:
5
+ workflows:
6
+ - "API break check"
7
+ types:
8
+ - completed
9
+
10
+ permissions:
11
+ actions: read
12
+ issues: write
13
+ pull-requests: write
14
+
15
+ jobs:
16
+ comment:
17
+ if: github.event.workflow_run.event == 'pull_request'
18
+ runs-on: ubuntu-latest
19
+
20
+ steps:
21
+ - name: Download Griffe result
22
+ uses: actions/download-artifact@v4
23
+ with:
24
+ name: api-break-result
25
+ run-id: ${{ github.event.workflow_run.id }}
26
+ github-token: ${{ secrets.GITHUB_TOKEN }}
27
+ path: api-break-result
28
+
29
+ - name: Update PR comment
30
+ uses: actions/github-script@v7
31
+ with:
32
+ script: |
33
+ const fs = require("fs");
34
+
35
+ const prs = context.payload.workflow_run.pull_requests;
36
+ if (!prs || prs.length === 0) {
37
+ core.info("No PR found for this workflow_run.");
38
+ return;
39
+ }
40
+
41
+ const prNumber = prs[0].number;
42
+ const identifier = "<!-- api-break-check -->";
43
+ const runUrl = context.payload.workflow_run.html_url;
44
+ const conclusion = context.payload.workflow_run.conclusion;
45
+
46
+ let log = "";
47
+ try {
48
+ log = fs.readFileSync("api-break-result/griffe.log", "utf8");
49
+ } catch (err) {
50
+ log = "Could not read Griffe log artifact.";
51
+ }
52
+
53
+ // Treat artifact contents as untrusted display text.
54
+ log = log.replaceAll("```", "`\u200b``");
55
+
56
+ // Truncate if log is really long
57
+ const maxLogChars = 60000;
58
+ if (log.length > maxLogChars) {
59
+ log = log.slice(0, maxLogChars) + "\n\n[truncated]";
60
+ }
61
+
62
+ const statusLine =
63
+ conclusion === "success"
64
+ ? "No API break detected ✅"
65
+ : "🚨 API breaking changes detected! 🚨";
66
+
67
+ const body = `${identifier}
68
+ ${statusLine}
69
+
70
+ [View workflow run](${runUrl})
71
+
72
+ <details>
73
+ <summary>Griffe output</summary>
74
+
75
+ \`\`\`text
76
+ ${log}
77
+ \`\`\`
78
+
79
+ </details>
80
+ `;
81
+
82
+ const { data: comments } = await github.rest.issues.listComments({
83
+ owner: context.repo.owner,
84
+ repo: context.repo.repo,
85
+ issue_number: prNumber,
86
+ });
87
+
88
+ for (const comment of comments) {
89
+ if (comment.body && comment.body.includes(identifier)) {
90
+ await github.rest.issues.deleteComment({
91
+ owner: context.repo.owner,
92
+ repo: context.repo.repo,
93
+ comment_id: comment.id,
94
+ });
95
+ }
96
+ }
97
+
98
+ await github.rest.issues.createComment({
99
+ owner: context.repo.owner,
100
+ repo: context.repo.repo,
101
+ issue_number: prNumber,
102
+ body,
103
+ });
@@ -0,0 +1,45 @@
1
+ name: "mypy"
2
+ on:
3
+ pull_request:
4
+ branches:
5
+ - main
6
+ push:
7
+ branches:
8
+ - main
9
+
10
+ concurrency:
11
+ group: "${{ github.workflow }}-${{ github.ref }}"
12
+ cancel-in-progress: true
13
+
14
+ defaults:
15
+ run:
16
+ shell: bash -leo pipefail {0}
17
+
18
+ jobs:
19
+ mypy:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v6
23
+
24
+ - name: "Setup Micromamba"
25
+ uses: mamba-org/setup-micromamba@v2
26
+ with:
27
+ environment-file: environment.yml
28
+ environment-name: gufe
29
+ cache-environment: true
30
+ cache-downloads: true
31
+ create-args: >-
32
+ python=3.12
33
+ rdkit=2025.03.4
34
+ mypy
35
+ init-shell: bash
36
+
37
+ - name: "Environment Information"
38
+ run: |
39
+ micromamba info
40
+ micromamba list
41
+
42
+ - name: "Lint with mypy"
43
+ run: |
44
+ mypy --version
45
+ mypy
@@ -0,0 +1,165 @@
1
+ docs/generated/*
2
+
3
+ # custom ignores
4
+ .xxrun
5
+ .idea/
6
+
7
+ # Byte-compiled / optimized / DLL files
8
+ __pycache__/
9
+ *.py[cod]
10
+ *$py.class
11
+ *~
12
+
13
+ # C extensions
14
+ *.so
15
+
16
+ # Distribution / packaging
17
+ .Python
18
+ build/
19
+ develop-eggs/
20
+ dist/
21
+ downloads/
22
+ eggs/
23
+ .eggs/
24
+ lib/
25
+ lib64/
26
+ parts/
27
+ sdist/
28
+ var/
29
+ wheels/
30
+ share/python-wheels/
31
+ *.egg-info/
32
+ .installed.cfg
33
+ *.egg
34
+ MANIFEST
35
+
36
+ # PyInstaller
37
+ # Usually these files are written by a python script from a template
38
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
39
+ *.manifest
40
+ *.spec
41
+
42
+ # Installer logs
43
+ pip-log.txt
44
+ pip-delete-this-directory.txt
45
+
46
+ # Unit test / coverage reports
47
+ htmlcov/
48
+ .tox/
49
+ .nox/
50
+ .coverage
51
+ .coverage.*
52
+ .cache
53
+ nosetests.xml
54
+ coverage.xml
55
+ *.cover
56
+ *.py,cover
57
+ .hypothesis/
58
+ .pytest_cache/
59
+ cover/
60
+
61
+ # Translations
62
+ *.mo
63
+ *.pot
64
+
65
+ # Django stuff:
66
+ *.log
67
+ local_settings.py
68
+ db.sqlite3
69
+ db.sqlite3-journal
70
+
71
+ # Flask stuff:
72
+ instance/
73
+ .webassets-cache
74
+
75
+ # Scrapy stuff:
76
+ .scrapy
77
+
78
+ # Sphinx documentation
79
+ docs/_build/
80
+
81
+ # PyBuilder
82
+ .pybuilder/
83
+ target/
84
+
85
+ # Jupyter Notebook
86
+ .ipynb_checkpoints
87
+
88
+ # IPython
89
+ profile_default/
90
+ ipython_config.py
91
+
92
+ # pyenv
93
+ # For a library or package, you might want to ignore these files since the code is
94
+ # intended to run in multiple environments; otherwise, check them in:
95
+ # .python-version
96
+
97
+ # pipenv
98
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
99
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
100
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
101
+ # install all needed dependencies.
102
+ #Pipfile.lock
103
+
104
+ # poetry
105
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
106
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
107
+ # commonly ignored for libraries.
108
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
109
+ #poetry.lock
110
+
111
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
112
+ __pypackages__/
113
+
114
+ # Celery stuff
115
+ celerybeat-schedule
116
+ celerybeat.pid
117
+
118
+ # SageMath parsed files
119
+ *.sage.py
120
+
121
+ # Environments
122
+ .env
123
+ .venv
124
+ env/
125
+ venv/
126
+ ENV/
127
+ env.bak/
128
+ venv.bak/
129
+
130
+ # Spyder project settings
131
+ .spyderproject
132
+ .spyproject
133
+
134
+ # Rope project settings
135
+ .ropeproject
136
+
137
+ # mkdocs documentation
138
+ /site
139
+
140
+ # mypy
141
+ .mypy_cache/
142
+ .dmypy.json
143
+ dmypy.json
144
+
145
+ # Pyre type checker
146
+ .pyre/
147
+
148
+ # pytype static type analyzer
149
+ .pytype/
150
+
151
+ # Cython debug symbols
152
+ cython_debug/
153
+
154
+ # PyCharm
155
+ # JetBrains specific template is maintainted in a separate JetBrains.gitignore that can
156
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
157
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
158
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
159
+ #.idea/
160
+
161
+ # vim
162
+ *.swp
163
+
164
+ # Rever
165
+ rever/