easyscience 2.2.0__tar.gz → 2.3.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 (222) hide show
  1. easyscience-2.3.1/.badgery.yaml +72 -0
  2. easyscience-2.3.1/.codecov.yml +8 -0
  3. easyscience-2.3.1/.copier-answers.yml +20 -0
  4. easyscience-2.3.1/.coveragerc +3 -0
  5. easyscience-2.3.1/.github/actions/download-artifact/action.yml +50 -0
  6. easyscience-2.3.1/.github/actions/github-script/action.yml +19 -0
  7. easyscience-2.3.1/.github/actions/setup-easyscience-bot/action.yml +40 -0
  8. easyscience-2.3.1/.github/actions/setup-pixi/action.yml +44 -0
  9. easyscience-2.3.1/.github/actions/upload-artifact/action.yml +49 -0
  10. easyscience-2.3.1/.github/actions/upload-codecov/action.yml +42 -0
  11. easyscience-2.3.1/.github/configs/pages-deployment.json +6 -0
  12. easyscience-2.3.1/.github/configs/rulesets-develop.json +37 -0
  13. easyscience-2.3.1/.github/configs/rulesets-gh-pages.json +19 -0
  14. easyscience-2.3.1/.github/configs/rulesets-master.json +30 -0
  15. easyscience-2.3.1/.github/scripts/backmerge-conflict-issue.js +69 -0
  16. easyscience-2.3.1/.github/workflows/backmerge.yml +109 -0
  17. easyscience-2.3.1/.github/workflows/cleanup.yml +84 -0
  18. easyscience-2.3.1/.github/workflows/coverage.yml +94 -0
  19. easyscience-2.3.1/.github/workflows/dashboard.yml +104 -0
  20. easyscience-2.3.1/.github/workflows/docs.yml +184 -0
  21. easyscience-2.3.1/.github/workflows/issues-labels.yml +42 -0
  22. easyscience-2.3.1/.github/workflows/lint-format.yml +130 -0
  23. easyscience-2.3.1/.github/workflows/pr-labels.yml +56 -0
  24. easyscience-2.3.1/.github/workflows/pypi-publish.yml +46 -0
  25. easyscience-2.3.1/.github/workflows/pypi-test.yml +80 -0
  26. easyscience-2.3.1/.github/workflows/release-notes.yml +71 -0
  27. easyscience-2.3.1/.github/workflows/release-pr.yml +55 -0
  28. easyscience-2.3.1/.github/workflows/security.yml +93 -0
  29. easyscience-2.3.1/.github/workflows/test-trigger.yml +40 -0
  30. easyscience-2.3.1/.github/workflows/test.yml +271 -0
  31. easyscience-2.3.1/.github/workflows/tutorial-tests-trigger.yml +40 -0
  32. easyscience-2.3.1/.github/workflows/tutorial-tests.yml +64 -0
  33. {easyscience-2.2.0 → easyscience-2.3.1}/.gitignore +25 -32
  34. easyscience-2.3.1/.pre-commit-config.yaml +61 -0
  35. easyscience-2.3.1/.prettierignore +17 -0
  36. easyscience-2.3.1/CONTRIBUTING.md +406 -0
  37. {easyscience-2.2.0 → easyscience-2.3.1}/LICENSE +1 -2
  38. easyscience-2.3.1/PKG-INFO +112 -0
  39. easyscience-2.3.1/README.md +44 -0
  40. easyscience-2.3.1/codecov.yml +13 -0
  41. easyscience-2.3.1/docs/docs/api-reference/base_classes.md +1 -0
  42. easyscience-2.3.1/docs/docs/api-reference/fitting.md +1 -0
  43. easyscience-2.3.1/docs/docs/api-reference/global_object.md +1 -0
  44. easyscience-2.3.1/docs/docs/api-reference/index.md +26 -0
  45. easyscience-2.3.1/docs/docs/api-reference/io.md +1 -0
  46. easyscience-2.3.1/docs/docs/api-reference/job.md +1 -0
  47. easyscience-2.3.1/docs/docs/api-reference/models.md +1 -0
  48. easyscience-2.3.1/docs/docs/api-reference/utils.md +1 -0
  49. easyscience-2.3.1/docs/docs/api-reference/variable.md +1 -0
  50. easyscience-2.3.1/docs/docs/assets/images/favicon.png +0 -0
  51. easyscience-2.3.1/docs/docs/assets/images/logo_dark.svg +34 -0
  52. easyscience-2.3.1/docs/docs/assets/images/logo_light.svg +34 -0
  53. easyscience-2.3.1/docs/docs/assets/javascripts/extra.js +29 -0
  54. easyscience-2.3.1/docs/docs/assets/javascripts/mathjax.js +27 -0
  55. easyscience-2.3.1/docs/docs/assets/stylesheets/extra.css +359 -0
  56. easyscience-2.3.1/docs/docs/index.md +21 -0
  57. easyscience-2.3.1/docs/docs/installation-and-setup/index.md +281 -0
  58. easyscience-2.3.1/docs/docs/introduction/index.md +67 -0
  59. easyscience-2.3.1/docs/docs/tutorials/fitting-qens.ipynb +359 -0
  60. easyscience-2.3.1/docs/docs/tutorials/fitting-sans.ipynb +349 -0
  61. easyscience-2.3.1/docs/docs/tutorials/index.md +28 -0
  62. easyscience-2.3.1/docs/docs/tutorials/progress-callback.ipynb +454 -0
  63. easyscience-2.3.1/docs/docs/user-guide/index.md +8 -0
  64. easyscience-2.3.1/docs/includes/abbreviations.md +15 -0
  65. easyscience-2.3.1/docs/mkdocs.yml +190 -0
  66. easyscience-2.3.1/docs/overrides/.icons/app.svg +4 -0
  67. easyscience-2.3.1/docs/overrides/.icons/easyscience.svg +20 -0
  68. easyscience-2.3.1/docs/overrides/.icons/google-colab.svg +7 -0
  69. easyscience-2.3.1/docs/overrides/main.html +39 -0
  70. easyscience-2.3.1/docs/overrides/partials/logo.html +15 -0
  71. easyscience-2.3.1/legacy/Examples/README.rst +4 -0
  72. easyscience-2.3.1/legacy/Examples/base/README.rst +6 -0
  73. easyscience-2.3.1/legacy/Examples/base/plot_baseclass1.py +97 -0
  74. easyscience-2.3.1/legacy/Examples/fitting/README.rst +6 -0
  75. easyscience-2.3.1/legacy/PARAMETER_DEPENDENCY_SERIALIZATION.md +259 -0
  76. easyscience-2.3.1/legacy/examples_old/dataset_examples.ipynb +1254 -0
  77. easyscience-2.3.1/legacy/examples_old/dimer_example.ipynb +1144 -0
  78. easyscience-2.3.1/legacy/examples_old/example1.py +30 -0
  79. easyscience-2.3.1/legacy/examples_old/example1_dream.py +45 -0
  80. easyscience-2.3.1/legacy/examples_old/example2.py +53 -0
  81. easyscience-2.3.1/legacy/examples_old/example3.py +101 -0
  82. easyscience-2.3.1/legacy/examples_old/example4.py +448 -0
  83. easyscience-2.3.1/legacy/examples_old/example5_broken.py +367 -0
  84. easyscience-2.3.1/legacy/examples_old/example6_broken.py +446 -0
  85. easyscience-2.3.1/legacy/examples_old/example_dataset.py +56 -0
  86. easyscience-2.3.1/legacy/examples_old/example_dataset2.py +50 -0
  87. easyscience-2.3.1/legacy/examples_old/example_dataset2pt2.py +57 -0
  88. easyscience-2.3.1/legacy/examples_old/example_dataset2pt2_broken.py +57 -0
  89. easyscience-2.3.1/legacy/examples_old/example_dataset3.py +92 -0
  90. easyscience-2.3.1/legacy/examples_old/example_dataset3pt2.py +62 -0
  91. easyscience-2.3.1/legacy/examples_old/example_dataset4.py +49 -0
  92. easyscience-2.3.1/legacy/examples_old/example_dataset4_2.py +67 -0
  93. easyscience-2.3.1/pixi.lock +10296 -0
  94. easyscience-2.3.1/pixi.toml +271 -0
  95. easyscience-2.3.1/prettierrc.toml +22 -0
  96. easyscience-2.3.1/pyproject.toml +243 -0
  97. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/__init__.py +7 -1
  98. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/base_classes/__init__.py +3 -0
  99. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/base_classes/based_base.py +54 -47
  100. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/base_classes/collection_base.py +30 -31
  101. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/base_classes/easy_list.py +56 -38
  102. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/base_classes/model_base.py +21 -20
  103. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/base_classes/new_base.py +36 -26
  104. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/base_classes/obj_base.py +14 -12
  105. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/__init__.py +3 -0
  106. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/available_minimizers.py +18 -3
  107. easyscience-2.3.1/src/easyscience/fitting/calculators/__init__.py +6 -0
  108. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/calculators/interface_factory.py +25 -26
  109. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/fitter.py +64 -55
  110. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/minimizers/__init__.py +2 -3
  111. easyscience-2.3.1/src/easyscience/fitting/minimizers/bumps_utils/__init__.py +7 -0
  112. easyscience-2.3.1/src/easyscience/fitting/minimizers/bumps_utils/eval_counter.py +27 -0
  113. easyscience-2.3.1/src/easyscience/fitting/minimizers/bumps_utils/progress_monitor.py +32 -0
  114. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/minimizers/factory.py +6 -1
  115. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/minimizers/minimizer_base.py +48 -40
  116. easyscience-2.3.1/src/easyscience/fitting/minimizers/minimizer_bumps.py +453 -0
  117. easyscience-2.3.1/src/easyscience/fitting/minimizers/minimizer_dfo.py +444 -0
  118. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/minimizers/minimizer_lmfit.py +98 -44
  119. easyscience-2.3.1/src/easyscience/fitting/minimizers/utils.py +106 -0
  120. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/fitting/multi_fitter.py +37 -20
  121. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/global_object/__init__.py +3 -0
  122. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/global_object/global_object.py +13 -12
  123. easyscience-2.3.1/src/easyscience/global_object/hugger/__init__.py +3 -0
  124. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/global_object/hugger/hugger.py +8 -6
  125. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/global_object/hugger/property.py +14 -8
  126. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/global_object/logger.py +6 -7
  127. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/global_object/map.py +27 -21
  128. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/global_object/undo_redo.py +24 -50
  129. easyscience-2.3.1/src/easyscience/io/__init__.py +12 -0
  130. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/io/serializer_base.py +64 -43
  131. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/io/serializer_component.py +25 -21
  132. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/io/serializer_dict.py +16 -13
  133. easyscience-2.3.1/src/easyscience/job/__init__.py +7 -0
  134. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/job/analysis.py +5 -5
  135. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/job/experiment.py +4 -6
  136. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/job/job.py +4 -5
  137. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/job/theoreticalmodel.py +4 -6
  138. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/legacy/dict.py +35 -26
  139. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/legacy/json.py +20 -21
  140. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/legacy/legacy_core.py +57 -33
  141. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/legacy/xml.py +21 -22
  142. easyscience-2.3.1/src/easyscience/models/__init__.py +4 -0
  143. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/models/polynomial.py +8 -7
  144. easyscience-2.3.1/src/easyscience/utils/__init__.py +3 -0
  145. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/utils/classTools.py +2 -3
  146. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/utils/classUtils.py +12 -17
  147. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/utils/decorators.py +17 -19
  148. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/utils/string.py +9 -8
  149. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/__init__.py +3 -0
  150. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/descriptor_any_type.py +13 -10
  151. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/descriptor_array.py +212 -137
  152. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/descriptor_base.py +25 -31
  153. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/descriptor_bool.py +6 -7
  154. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/descriptor_number.py +50 -37
  155. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/descriptor_str.py +6 -7
  156. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/parameter.py +239 -124
  157. {easyscience-2.2.0 → easyscience-2.3.1}/src/easyscience/variable/parameter_dependency_resolver.py +28 -19
  158. easyscience-2.3.1/tests/conftest.py +14 -0
  159. easyscience-2.3.1/tests/integration/fitting/test_fitter.py +580 -0
  160. easyscience-2.3.1/tests/integration/fitting/test_multi_fitter.py +288 -0
  161. easyscience-2.3.1/tests/unit/base_classes/__init__.py +3 -0
  162. easyscience-2.3.1/tests/unit/base_classes/test_collection_base.py +545 -0
  163. easyscience-2.3.1/tests/unit/base_classes/test_easy_list.py +526 -0
  164. easyscience-2.3.1/tests/unit/base_classes/test_model_base.py +321 -0
  165. easyscience-2.3.1/tests/unit/base_classes/test_new_base.py +217 -0
  166. easyscience-2.3.1/tests/unit/base_classes/test_obj_base.py +498 -0
  167. easyscience-2.3.1/tests/unit/fitting/__init__.py +3 -0
  168. easyscience-2.3.1/tests/unit/fitting/calculators/__init__.py +3 -0
  169. easyscience-2.3.1/tests/unit/fitting/calculators/test_interface_factory.py +560 -0
  170. easyscience-2.3.1/tests/unit/fitting/minimizers/__init__.py +3 -0
  171. easyscience-2.3.1/tests/unit/fitting/minimizers/test_factory.py +110 -0
  172. easyscience-2.3.1/tests/unit/fitting/minimizers/test_minimizer_base.py +215 -0
  173. easyscience-2.3.1/tests/unit/fitting/minimizers/test_minimizer_bumps.py +674 -0
  174. easyscience-2.3.1/tests/unit/fitting/minimizers/test_minimizer_dfo.py +832 -0
  175. easyscience-2.3.1/tests/unit/fitting/minimizers/test_minimizer_lmfit.py +555 -0
  176. easyscience-2.3.1/tests/unit/fitting/minimizers/test_utils.py +91 -0
  177. easyscience-2.3.1/tests/unit/fitting/test_fitter.py +260 -0
  178. easyscience-2.3.1/tests/unit/fitting/test_multi_fitter.py +63 -0
  179. easyscience-2.3.1/tests/unit/global_object/__init__.py +3 -0
  180. easyscience-2.3.1/tests/unit/global_object/test_entry_list_comprehensive.py +320 -0
  181. easyscience-2.3.1/tests/unit/global_object/test_global_object.py +177 -0
  182. easyscience-2.3.1/tests/unit/global_object/test_integration_comprehensive.py +456 -0
  183. easyscience-2.3.1/tests/unit/global_object/test_map.py +757 -0
  184. easyscience-2.3.1/tests/unit/global_object/test_undo_redo.py +449 -0
  185. easyscience-2.3.1/tests/unit/global_object/test_undo_redo_comprehensive.py +705 -0
  186. easyscience-2.3.1/tests/unit/io/test_serializer_base.py +716 -0
  187. easyscience-2.3.1/tests/unit/io/test_serializer_component.py +96 -0
  188. easyscience-2.3.1/tests/unit/io/test_serializer_dict.py +121 -0
  189. easyscience-2.3.1/tests/unit/legacy/__init__.py +3 -0
  190. easyscience-2.3.1/tests/unit/legacy/test_dict.py +3 -0
  191. easyscience-2.3.1/tests/unit/legacy/test_json.py +3 -0
  192. easyscience-2.3.1/tests/unit/legacy/test_xml.py +3 -0
  193. easyscience-2.3.1/tests/unit/models/__init__.py +3 -0
  194. easyscience-2.3.1/tests/unit/models/test_polynomial.py +192 -0
  195. easyscience-2.3.1/tests/unit/variable/__init__.py +3 -0
  196. easyscience-2.3.1/tests/unit/variable/test_descriptor_any_type.py +83 -0
  197. easyscience-2.3.1/tests/unit/variable/test_descriptor_array.py +1807 -0
  198. easyscience-2.3.1/tests/unit/variable/test_descriptor_base.py +225 -0
  199. easyscience-2.3.1/tests/unit/variable/test_descriptor_bool.py +81 -0
  200. easyscience-2.3.1/tests/unit/variable/test_descriptor_number.py +586 -0
  201. easyscience-2.3.1/tests/unit/variable/test_descriptor_str.py +80 -0
  202. easyscience-2.3.1/tests/unit/variable/test_parameter.py +1925 -0
  203. easyscience-2.3.1/tests/unit/variable/test_parameter_dependency_serialization.py +529 -0
  204. easyscience-2.3.1/tools/add_spdx.py +149 -0
  205. easyscience-2.3.1/tools/check_spdx.py +43 -0
  206. easyscience-2.3.1/tools/remove_spdx.py +39 -0
  207. easyscience-2.3.1/tools/test_scripts.py +55 -0
  208. easyscience-2.3.1/tools/update_docs_assets.py +91 -0
  209. easyscience-2.3.1/tools/update_github_labels.py +339 -0
  210. easyscience-2.2.0/PKG-INFO +0 -122
  211. easyscience-2.2.0/README.md +0 -45
  212. easyscience-2.2.0/pyproject.toml +0 -162
  213. easyscience-2.2.0/src/easyscience/__version__.py +0 -1
  214. easyscience-2.2.0/src/easyscience/fitting/calculators/__init__.py +0 -7
  215. easyscience-2.2.0/src/easyscience/fitting/minimizers/minimizer_bumps.py +0 -280
  216. easyscience-2.2.0/src/easyscience/fitting/minimizers/minimizer_dfo.py +0 -285
  217. easyscience-2.2.0/src/easyscience/fitting/minimizers/utils.py +0 -63
  218. easyscience-2.2.0/src/easyscience/global_object/hugger/__init__.py +0 -4
  219. easyscience-2.2.0/src/easyscience/io/__init__.py +0 -12
  220. easyscience-2.2.0/src/easyscience/job/__init__.py +0 -8
  221. easyscience-2.2.0/src/easyscience/models/__init__.py +0 -5
  222. easyscience-2.2.0/src/easyscience/utils/__init__.py +0 -3
@@ -0,0 +1,72 @@
1
+ default_branch: master
2
+ develop_branch: develop
3
+
4
+ cards:
5
+ - group: Tests
6
+ type: gh_action
7
+ title: Code/package tests (GitHub)
8
+ file: test.yml
9
+ enabled: true
10
+ - group: Tests
11
+ type: gh_action
12
+ title: Tutorial tests (GitHub)
13
+ file: tutorial-tests.yml
14
+ enabled: true
15
+
16
+ - group: Tests
17
+ type: gh_action
18
+ title: Package tests (PyPI)
19
+ file: pypi-test.yml
20
+ enabled: true
21
+
22
+ - group: Code Quality
23
+ type: codefactor
24
+ title: Code quality (CodeFactor)
25
+ enabled: true
26
+
27
+ - group: Code Quality
28
+ type: radon_mi
29
+ title: Maintainability index (radon)
30
+ report: reports/{branch}/maintainability-index.json
31
+ enabled: true
32
+
33
+ - group: Code Quality
34
+ type: radon_cc
35
+ title: Cyclomatic complexity (radon)
36
+ report: reports/{branch}/cyclomatic-complexity.json
37
+ enabled: true
38
+
39
+ - group: Size
40
+ type: radon_loc
41
+ title: Source/Logical lines of code (radon)
42
+ report: reports/{branch}/raw-metrics.json
43
+ enabled: true
44
+
45
+ - group: Size
46
+ type: radon_ff
47
+ title: Functions/Files count (radon)
48
+ report: reports/{branch}/cyclomatic-complexity.json
49
+ enabled: true
50
+
51
+ - group: Coverage
52
+ type: codecov
53
+ title: Unit test coverage (Codecov)
54
+ flag: unittests
55
+ enabled: true
56
+
57
+ - group: Coverage
58
+ type: interrogate
59
+ title: Docstring coverage (interrogate)
60
+ report: reports/{branch}/coverage-docstring.txt
61
+ enabled: true
62
+ - group: Build & Release
63
+ type: gh_action
64
+ title: Publishing (PyPI)
65
+ workflow: pypi-publish.yml
66
+ enabled: true
67
+
68
+ - group: Build & Release
69
+ type: gh_action
70
+ title: Docs build/deployment
71
+ workflow: docs.yml
72
+ enabled: true
@@ -0,0 +1,8 @@
1
+ github_checks:
2
+ annotations: true
3
+ comment:
4
+ layout: 'reach, diff, flags, files'
5
+ behavior: default
6
+ require_changes: false # if true: only post the comment if coverage changes
7
+ require_base: no # [yes :: must have a base report to post]
8
+ require_head: yes # [yes :: must have a head report to post]
@@ -0,0 +1,20 @@
1
+ # WARNING: Do not edit this file manually.
2
+ # Any changes will be overwritten by Copier.
3
+ _commit: v0.10.0
4
+ _src_path: gh:easyscience/templates
5
+ lib_docs_url: https://easyscience.github.io/core
6
+ lib_doi: 10.5281/zenodo.18163581
7
+ lib_package_name: easyscience
8
+ lib_python_max: '3.13'
9
+ lib_python_min: '3.11'
10
+ lib_repo_name: core
11
+ project_contact_email: support@easyscience.org
12
+ project_copyright_years: 2021-2026
13
+ project_extended_description: The foundation of the framework, providing reusable
14
+ building blocks for scientific libraries and applications aimed at making data
15
+ analysis easier
16
+ project_name: EasyScience
17
+ project_short_description: Core building blocks for EasyScience
18
+ project_shortcut: ES
19
+ project_type: lib
20
+ template_type: lib
@@ -0,0 +1,3 @@
1
+ [paths]
2
+ source =
3
+ src/easyscience/
@@ -0,0 +1,50 @@
1
+ name: 'Download artifact'
2
+ description: 'Generic wrapper for actions/download-artifact'
3
+ inputs:
4
+ name:
5
+ description: 'Name of the artifact to download'
6
+ required: true
7
+
8
+ path:
9
+ description: 'Destination path'
10
+ required: false
11
+ default: '.'
12
+
13
+ pattern:
14
+ description: 'Glob pattern to match artifact names (optional)'
15
+ required: false
16
+ default: ''
17
+
18
+ merge-multiple:
19
+ description: 'Merge multiple artifacts into the same directory'
20
+ required: false
21
+ default: 'false'
22
+
23
+ github-token:
24
+ description: 'GitHub token for cross-repo download (optional)'
25
+ required: false
26
+ default: ''
27
+
28
+ repository:
29
+ description: 'owner/repo for cross-repo download (optional)'
30
+ required: false
31
+ default: ''
32
+
33
+ run-id:
34
+ description: 'Workflow run ID for cross-run download (optional)'
35
+ required: false
36
+ default: ''
37
+
38
+ runs:
39
+ using: 'composite'
40
+ steps:
41
+ - name: Download artifact
42
+ uses: actions/download-artifact@v4
43
+ with:
44
+ name: ${{ inputs.name }}
45
+ path: ${{ inputs.path }}
46
+ pattern: ${{ inputs.pattern }}
47
+ merge-multiple: ${{ inputs.merge-multiple }}
48
+ github-token: ${{ inputs.github-token }}
49
+ repository: ${{ inputs.repository }}
50
+ run-id: ${{ inputs.run-id }}
@@ -0,0 +1,19 @@
1
+ name: 'GitHub Script'
2
+ description: 'Wrapper for actions/github-script'
3
+ inputs:
4
+ script:
5
+ description: 'JavaScript to run'
6
+ required: true
7
+
8
+ github-token:
9
+ description: 'GitHub token (defaults to github.token)'
10
+ required: false
11
+ default: ${{ github.token }}
12
+
13
+ runs:
14
+ using: 'composite'
15
+ steps:
16
+ - uses: actions/github-script@v8
17
+ with:
18
+ script: ${{ inputs.script }}
19
+ github-token: ${{ inputs.github-token }}
@@ -0,0 +1,40 @@
1
+ name: 'Setup EasyScience bot for pushing'
2
+ description: 'Create GitHub App token and configure git identity + origin remote'
3
+ inputs:
4
+ app-id:
5
+ description: 'GitHub App ID'
6
+ required: true
7
+ private-key:
8
+ description: 'GitHub App private key (PEM)'
9
+ required: true
10
+ repositories:
11
+ description: 'Additional repositories to grant access to (newline-separated)'
12
+ required: false
13
+ default: ''
14
+
15
+ outputs:
16
+ token:
17
+ description: 'Installation access token'
18
+ value: ${{ steps.app-token.outputs.token }}
19
+
20
+ runs:
21
+ using: 'composite'
22
+ steps:
23
+ - name: Create GitHub App installation token
24
+ id: app-token
25
+ uses: actions/create-github-app-token@v2
26
+ with:
27
+ app-id: ${{ inputs.app-id }}
28
+ private-key: ${{ inputs.private-key }}
29
+ repositories: ${{ inputs.repositories }}
30
+
31
+ - name: Configure git for pushing
32
+ shell: bash
33
+ run: |
34
+ git config user.name "easyscience[bot]"
35
+ git config user.email "${{ inputs.app-id }}+easyscience[bot]@users.noreply.github.com"
36
+
37
+ - name: Configure origin remote to use the bot token
38
+ shell: bash
39
+ run: |
40
+ git remote set-url origin https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}.git
@@ -0,0 +1,44 @@
1
+ name: 'Setup Pixi Environment'
2
+ description: 'Sets up pixi with common configuration'
3
+ inputs:
4
+ environments:
5
+ description: 'Pixi environments to setup'
6
+ required: false
7
+ default: 'default'
8
+ activate-environment:
9
+ description: 'Environment to activate'
10
+ required: false
11
+ default: 'default'
12
+ run-install:
13
+ description: 'Whether to run pixi install'
14
+ required: false
15
+ default: 'true'
16
+ locked:
17
+ description: 'Whether to run pixi install --locked'
18
+ required: false
19
+ default: 'false'
20
+ frozen:
21
+ description: 'Whether to run pixi install --frozen'
22
+ required: false
23
+ default: 'true'
24
+ cache:
25
+ description: 'Whether to use cache'
26
+ required: false
27
+ default: 'false'
28
+ post-cleanup:
29
+ description: 'Whether to run post cleanup'
30
+ required: false
31
+ default: 'false'
32
+
33
+ runs:
34
+ using: 'composite'
35
+ steps:
36
+ - uses: prefix-dev/setup-pixi@v0.9.4
37
+ with:
38
+ environments: ${{ inputs.environments }}
39
+ activate-environment: ${{ inputs.activate-environment }}
40
+ run-install: ${{ inputs.run-install }}
41
+ locked: ${{ inputs.locked }}
42
+ frozen: ${{ inputs.frozen }}
43
+ cache: ${{ inputs.cache }}
44
+ post-cleanup: ${{ inputs.post-cleanup }}
@@ -0,0 +1,49 @@
1
+ name: 'Upload artifact'
2
+ description: 'Generic wrapper for actions/upload-artifact'
3
+ inputs:
4
+ name:
5
+ description: 'Artifact name'
6
+ required: true
7
+
8
+ path:
9
+ description: 'File(s)/dir(s)/glob(s) to upload (newline-separated)'
10
+ required: true
11
+
12
+ include-hidden-files:
13
+ description: 'Include hidden files'
14
+ required: false
15
+ default: 'true'
16
+
17
+ if-no-files-found:
18
+ description: 'warn | error | ignore'
19
+ required: false
20
+ default: 'error'
21
+
22
+ compression-level:
23
+ description: '0-9 (0 = no compression)'
24
+ required: false
25
+ default: '0'
26
+
27
+ retention-days:
28
+ description: 'Retention in days (optional)'
29
+ required: false
30
+ default: ''
31
+
32
+ overwrite:
33
+ description: 'Overwrite an existing artifact with the same name'
34
+ required: false
35
+ default: 'false'
36
+
37
+ runs:
38
+ using: 'composite'
39
+ steps:
40
+ - name: Upload artifact
41
+ uses: actions/upload-artifact@v4
42
+ with:
43
+ name: ${{ inputs.name }}
44
+ path: ${{ inputs.path }}
45
+ include-hidden-files: ${{ inputs.include-hidden-files }}
46
+ if-no-files-found: ${{ inputs.if-no-files-found }}
47
+ compression-level: ${{ inputs.compression-level }}
48
+ retention-days: ${{ inputs.retention-days }}
49
+ overwrite: ${{ inputs.overwrite }}
@@ -0,0 +1,42 @@
1
+ name: 'Upload coverage to Codecov'
2
+ description: 'Generic wrapper for codecov/codecov-action@v5'
3
+
4
+ inputs:
5
+ name:
6
+ description: 'Codecov upload name'
7
+ required: true
8
+
9
+ flags:
10
+ description: 'Codecov flags'
11
+ required: false
12
+ default: ''
13
+
14
+ files:
15
+ description: 'Coverage report files'
16
+ required: true
17
+
18
+ fail_ci_if_error:
19
+ description: 'Fail CI if upload fails'
20
+ required: false
21
+ default: 'true'
22
+
23
+ verbose:
24
+ description: 'Enable verbose output'
25
+ required: false
26
+ default: 'true'
27
+
28
+ token:
29
+ description: 'Codecov token'
30
+ required: true
31
+
32
+ runs:
33
+ using: composite
34
+ steps:
35
+ - uses: codecov/codecov-action@v5
36
+ with:
37
+ name: ${{ inputs.name }}
38
+ flags: ${{ inputs.flags }}
39
+ files: ${{ inputs.files }}
40
+ fail_ci_if_error: ${{ inputs.fail_ci_if_error }}
41
+ verbose: ${{ inputs.verbose }}
42
+ token: ${{ inputs.token }}
@@ -0,0 +1,6 @@
1
+ {
2
+ "source": {
3
+ "branch": "gh-pages",
4
+ "path": "/"
5
+ }
6
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "develop branch",
3
+ "target": "branch",
4
+ "enforcement": "active",
5
+ "conditions": {
6
+ "ref_name": {
7
+ "include": ["refs/heads/develop"],
8
+ "exclude": []
9
+ }
10
+ },
11
+ "bypass_actors": [
12
+ {
13
+ "actor_id": 2476259,
14
+ "actor_type": "Integration",
15
+ "bypass_mode": "always"
16
+ }
17
+ ],
18
+ "rules": [
19
+ {
20
+ "type": "non_fast_forward"
21
+ },
22
+ {
23
+ "type": "deletion"
24
+ },
25
+ {
26
+ "type": "pull_request",
27
+ "parameters": {
28
+ "allowed_merge_methods": ["squash"],
29
+ "dismiss_stale_reviews_on_push": false,
30
+ "require_code_owner_review": false,
31
+ "require_last_push_approval": false,
32
+ "required_approving_review_count": 0,
33
+ "required_review_thread_resolution": false
34
+ }
35
+ }
36
+ ]
37
+ }
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "gh-pages branch",
3
+ "target": "branch",
4
+ "enforcement": "active",
5
+ "conditions": {
6
+ "ref_name": {
7
+ "include": ["refs/heads/gh-pages"],
8
+ "exclude": []
9
+ }
10
+ },
11
+ "rules": [
12
+ {
13
+ "type": "non_fast_forward"
14
+ },
15
+ {
16
+ "type": "deletion"
17
+ }
18
+ ]
19
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "master branch",
3
+ "target": "branch",
4
+ "enforcement": "active",
5
+ "conditions": {
6
+ "ref_name": {
7
+ "include": ["~DEFAULT_BRANCH"],
8
+ "exclude": []
9
+ }
10
+ },
11
+ "rules": [
12
+ {
13
+ "type": "non_fast_forward"
14
+ },
15
+ {
16
+ "type": "deletion"
17
+ },
18
+ {
19
+ "type": "pull_request",
20
+ "parameters": {
21
+ "allowed_merge_methods": ["merge"],
22
+ "dismiss_stale_reviews_on_push": false,
23
+ "require_code_owner_review": false,
24
+ "require_last_push_approval": false,
25
+ "required_approving_review_count": 0,
26
+ "required_review_thread_resolution": false
27
+ }
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,69 @@
1
+ module.exports = async ({ github, context, core }) => {
2
+ // Repo context
3
+ const owner = context.repo.owner
4
+ const repo = context.repo.repo
5
+
6
+ // Link to the exact workflow run that detected the conflict
7
+ const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`
8
+
9
+ // We use a *stable title* so we can find/reuse the same "conflict tracker" issue
10
+ // instead of creating a new issue on every failed run.
11
+ const title = 'Backmerge conflict: master → develop'
12
+
13
+ // Comment/issue body includes the run URL so maintainers can jump straight to logs.
14
+ const body = [
15
+ 'Automatic backmerge failed due to merge conflicts.',
16
+ '',
17
+ `Workflow run: ${runUrl}`,
18
+ '',
19
+ 'Manual resolution required.',
20
+ ].join('\n')
21
+
22
+ // Label applied to the tracker issue (assumed to already exist in the repo).
23
+ const label = '[bot] backmerge'
24
+
25
+ // Search issues by title across *open and closed* issues.
26
+ // Why: if the conflict was resolved previously and the issue was closed,
27
+ // we prefer to reopen it and append a new comment instead of creating duplicates.
28
+ const q = `repo:${owner}/${repo} is:issue in:title "${title}"`
29
+ const search = await github.rest.search.issuesAndPullRequests({
30
+ q,
31
+ per_page: 10,
32
+ })
33
+
34
+ // Pick the first exact-title match (search can return partial matches).
35
+ const existing = search.data.items.find((i) => i.title === title)
36
+
37
+ if (existing) {
38
+ // If a tracker issue exists, reuse it:
39
+ // - reopen it if needed
40
+ // - add a comment with the new run URL
41
+ if (existing.state === 'closed') {
42
+ await github.rest.issues.update({
43
+ owner,
44
+ repo,
45
+ issue_number: existing.number,
46
+ state: 'open',
47
+ })
48
+ }
49
+
50
+ await github.rest.issues.createComment({
51
+ owner,
52
+ repo,
53
+ issue_number: existing.number,
54
+ body,
55
+ })
56
+
57
+ core.notice(`Conflict issue updated: #${existing.number}`)
58
+ return
59
+ }
60
+
61
+ // No tracker issue exists yet -> create the first one.
62
+ await github.rest.issues.create({
63
+ owner,
64
+ repo,
65
+ title,
66
+ body,
67
+ labels: [label],
68
+ })
69
+ }
@@ -0,0 +1,109 @@
1
+ # This workflow automatically merges `master` into `develop` whenever a
2
+ # new version release with a tag is published. It can also be triggered
3
+ # manually via workflow_dispatch for cases where an automatic backmerge
4
+ # is needed outside of the standard release process.
5
+ # If a merge conflict occurs, the workflow creates an issue to notify
6
+ # maintainers for manual resolution.
7
+
8
+ name: Backmerge (master → develop)
9
+
10
+ on:
11
+ release:
12
+ types: [published, prereleased]
13
+ workflow_dispatch:
14
+
15
+ permissions:
16
+ contents: write
17
+ issues: write
18
+
19
+ concurrency:
20
+ group: backmerge-master-into-develop
21
+ cancel-in-progress: false
22
+
23
+ jobs:
24
+ backmerge:
25
+ runs-on: ubuntu-latest
26
+ timeout-minutes: 10
27
+
28
+ steps:
29
+ - name: Checkout repository (for local actions)
30
+ uses: actions/checkout@v5
31
+
32
+ - name: Setup easyscience[bot]
33
+ id: bot
34
+ uses: ./.github/actions/setup-easyscience-bot
35
+ with:
36
+ app-id: ${{ vars.EASYSCIENCE_APP_ID }}
37
+ private-key: ${{ secrets.EASYSCIENCE_APP_KEY }}
38
+ repositories: ${{ github.event.repository.name }}
39
+
40
+ - name: Checkout repository (with bot token)
41
+ uses: actions/checkout@v5
42
+ with:
43
+ fetch-depth: 0
44
+ token: ${{ steps.bot.outputs.token }}
45
+
46
+ - name: Configure git identity
47
+ run: |
48
+ git config user.name "easyscience[bot]"
49
+ git config user.email "${{ vars.EASYSCIENCE_APP_ID }}+easyscience[bot]@users.noreply.github.com"
50
+
51
+ - name: Set merge message
52
+ run: |
53
+ if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
54
+ MESSAGE="Backmerge: master into develop (manual) [skip ci]"
55
+ else
56
+ TAG="${{ github.event.release.tag_name }}"
57
+ MESSAGE="Backmerge: master (${TAG}) into develop [skip ci]"
58
+ fi
59
+
60
+ echo "MESSAGE=$MESSAGE" >> "$GITHUB_ENV"
61
+ echo "message=$MESSAGE" >> "$GITHUB_OUTPUT"
62
+ echo "📝 Merge message: $MESSAGE" | tee -a "$GITHUB_STEP_SUMMARY"
63
+
64
+ - name: Prepare branches
65
+ run: |
66
+ git fetch origin master develop
67
+ git checkout -B develop origin/develop
68
+
69
+ - name: Check if develop is already up-to-date
70
+ id: up_to_date
71
+ run: |
72
+ if git merge-base --is-ancestor origin/master develop; then
73
+ echo "value=true" >> "$GITHUB_OUTPUT"
74
+ echo "ℹ️ Develop is already up-to-date with master" | tee -a "$GITHUB_STEP_SUMMARY"
75
+ else
76
+ echo "value=false" >> "$GITHUB_OUTPUT"
77
+ fi
78
+
79
+ - name: Try merge master into develop
80
+ id: merge
81
+ if: steps.up_to_date.outputs.value == 'false'
82
+ continue-on-error: true
83
+ run: |
84
+ if ! git merge origin/master --no-ff -m "${MESSAGE}"; then
85
+ echo "conflict=true" >> "$GITHUB_OUTPUT"
86
+ echo "❌ Backmerge conflict detected." | tee -a "$GITHUB_STEP_SUMMARY"
87
+ git status --porcelain || true
88
+ exit 0
89
+ fi
90
+
91
+ echo "conflict=false" >> "$GITHUB_OUTPUT"
92
+ echo "✅ Merge commit created." | tee -a "$GITHUB_STEP_SUMMARY"
93
+
94
+ - name: Push to develop (if merge succeeded)
95
+ if:
96
+ steps.up_to_date.outputs.value == 'false' && steps.merge.outputs.conflict ==
97
+ 'false'
98
+ run: |
99
+ git push origin develop
100
+ echo "🚀 Backmerge successful: master → develop" | tee -a "$GITHUB_STEP_SUMMARY"
101
+
102
+ - name: Create issue (if merge failed with conflicts)
103
+ if: steps.merge.outputs.conflict == 'true'
104
+ uses: ./.github/actions/github-script
105
+ with:
106
+ github-token: ${{ steps.bot.outputs.token }}
107
+ script: |
108
+ const run = require('./.github/scripts/backmerge-conflict-issue.js')
109
+ await run({ github, context, core })