rivoli 0.1.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.
- rivoli-0.1.0/.copier-answers.yml +29 -0
- rivoli-0.1.0/.editorconfig +27 -0
- rivoli-0.1.0/.git-blame-ignore-revs +6 -0
- rivoli-0.1.0/.git_archival.txt +3 -0
- rivoli-0.1.0/.gitattributes +15 -0
- rivoli-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +20 -0
- rivoli-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- rivoli-0.1.0/.github/ISSUE_TEMPLATE/documentation.yml +17 -0
- rivoli-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +17 -0
- rivoli-0.1.0/.github/ISSUE_TEMPLATE/question.yml +17 -0
- rivoli-0.1.0/.github/codecov.yml +20 -0
- rivoli-0.1.0/.github/dependabot.yml +71 -0
- rivoli-0.1.0/.github/pull_request_template.md +16 -0
- rivoli-0.1.0/.github/rulesets/main.json +53 -0
- rivoli-0.1.0/.github/rulesets/version-tags.json +25 -0
- rivoli-0.1.0/.github/workflows/ci.yml +132 -0
- rivoli-0.1.0/.github/workflows/release.yml +129 -0
- rivoli-0.1.0/.gitignore +651 -0
- rivoli-0.1.0/.license-header.txt +2 -0
- rivoli-0.1.0/.pre-commit-config.yaml +77 -0
- rivoli-0.1.0/CHANGELOG.md +104 -0
- rivoli-0.1.0/CITATION.cff +22 -0
- rivoli-0.1.0/CODE_OF_CONDUCT.md +89 -0
- rivoli-0.1.0/CONTRIBUTING.md +108 -0
- rivoli-0.1.0/LICENSE.txt +661 -0
- rivoli-0.1.0/PKG-INFO +186 -0
- rivoli-0.1.0/README.md +157 -0
- rivoli-0.1.0/SECURITY.md +30 -0
- rivoli-0.1.0/docs/adr/0001-record-architecture-decisions.md +88 -0
- rivoli-0.1.0/docs/adr/README.md +12 -0
- rivoli-0.1.0/docs/adr/template.md +55 -0
- rivoli-0.1.0/docs/assets/header.png +0 -0
- rivoli-0.1.0/docs/assets/logo.png +0 -0
- rivoli-0.1.0/docs/assets/social_preview.png +0 -0
- rivoli-0.1.0/examples/README.md +44 -0
- rivoli-0.1.0/examples/hdf5_reconstruction.py +262 -0
- rivoli-0.1.0/examples/merl_reconstruction.py +220 -0
- rivoli-0.1.0/pyproject.toml +117 -0
- rivoli-0.1.0/ruff.toml +41 -0
- rivoli-0.1.0/scripts/configure-github.sh +127 -0
- rivoli-0.1.0/scripts/release.py +150 -0
- rivoli-0.1.0/setup.cfg +4 -0
- rivoli-0.1.0/src/rivoli/__init__.py +18 -0
- rivoli-0.1.0/src/rivoli/colour.py +282 -0
- rivoli-0.1.0/src/rivoli/data/CIE_std_illum_D65.csv +531 -0
- rivoli-0.1.0/src/rivoli/data/CIE_xyz_1931_2deg.csv +471 -0
- rivoli-0.1.0/src/rivoli/data/README.md +14 -0
- rivoli-0.1.0/src/rivoli/dirichlet.py +351 -0
- rivoli-0.1.0/src/rivoli/distances.py +319 -0
- rivoli-0.1.0/src/rivoli/geometry.py +133 -0
- rivoli-0.1.0/src/rivoli/hdf5.py +274 -0
- rivoli-0.1.0/src/rivoli/kernels.py +167 -0
- rivoli-0.1.0/src/rivoli/merl.py +258 -0
- rivoli-0.1.0/src/rivoli/model.py +356 -0
- rivoli-0.1.0/src/rivoli/parametrization.py +311 -0
- rivoli-0.1.0/src/rivoli/py.typed +0 -0
- rivoli-0.1.0/src/rivoli/sampling.py +334 -0
- rivoli-0.1.0/src/rivoli/tikhonov.py +167 -0
- rivoli-0.1.0/src/rivoli/warp/__init__.py +13 -0
- rivoli-0.1.0/src/rivoli/warp/dirichlet.py +277 -0
- rivoli-0.1.0/src/rivoli/warp/distances.py +188 -0
- rivoli-0.1.0/src/rivoli/warp/kernels.py +334 -0
- rivoli-0.1.0/src/rivoli.egg-info/PKG-INFO +186 -0
- rivoli-0.1.0/src/rivoli.egg-info/SOURCES.txt +85 -0
- rivoli-0.1.0/src/rivoli.egg-info/dependency_links.txt +1 -0
- rivoli-0.1.0/src/rivoli.egg-info/requires.txt +7 -0
- rivoli-0.1.0/src/rivoli.egg-info/scm_file_list.json +82 -0
- rivoli-0.1.0/src/rivoli.egg-info/scm_version.json +8 -0
- rivoli-0.1.0/src/rivoli.egg-info/top_level.txt +1 -0
- rivoli-0.1.0/tests/test_colour.py +116 -0
- rivoli-0.1.0/tests/test_dirichlet.py +339 -0
- rivoli-0.1.0/tests/test_distances.py +270 -0
- rivoli-0.1.0/tests/test_examples.py +122 -0
- rivoli-0.1.0/tests/test_geometry.py +133 -0
- rivoli-0.1.0/tests/test_hdf5.py +207 -0
- rivoli-0.1.0/tests/test_kernels.py +145 -0
- rivoli-0.1.0/tests/test_merl.py +226 -0
- rivoli-0.1.0/tests/test_model.py +226 -0
- rivoli-0.1.0/tests/test_package.py +10 -0
- rivoli-0.1.0/tests/test_parametrization.py +252 -0
- rivoli-0.1.0/tests/test_release.py +110 -0
- rivoli-0.1.0/tests/test_sampling.py +246 -0
- rivoli-0.1.0/tests/test_tikhonov.py +130 -0
- rivoli-0.1.0/tests/test_warp_dirichlet.py +80 -0
- rivoli-0.1.0/tests/test_warp_distances.py +122 -0
- rivoli-0.1.0/tests/test_warp_kernels.py +130 -0
- rivoli-0.1.0/uv.lock +932 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY
|
|
2
|
+
_commit: v0.1.2
|
|
3
|
+
_src_path: gh:fmargall/scientific-python-template
|
|
4
|
+
author_email: fr.margall@proton.me
|
|
5
|
+
author_family_names: Margall
|
|
6
|
+
author_given_names: François
|
|
7
|
+
author_orcid: https://orcid.org/0009-0004-0585-087X
|
|
8
|
+
conduct_email: fr.margall@proton.me
|
|
9
|
+
copyright_holder: François Margall
|
|
10
|
+
copyright_year: '2026'
|
|
11
|
+
creation_date: '2026-10-26'
|
|
12
|
+
distribution_name: rivoli
|
|
13
|
+
homepage_url: ''
|
|
14
|
+
keywords:
|
|
15
|
+
- interpolation
|
|
16
|
+
- brdf
|
|
17
|
+
- rbf
|
|
18
|
+
- ebf
|
|
19
|
+
- erbf
|
|
20
|
+
- pbr
|
|
21
|
+
- modeling
|
|
22
|
+
license: AGPL-3.0-or-later
|
|
23
|
+
package_name: rivoli
|
|
24
|
+
project_description: Physically-based interpolation code by radial basis function
|
|
25
|
+
dedicated to BRDF, spherical or bispherical modeling functions and data reconstruction.
|
|
26
|
+
project_name: RIVOLI
|
|
27
|
+
python_min_version: '3.13'
|
|
28
|
+
repository_url: https://github.com/fmargall/rivoli
|
|
29
|
+
use_codecov: true
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# https://editorconfig.org
|
|
2
|
+
root = true
|
|
3
|
+
|
|
4
|
+
[*]
|
|
5
|
+
charset = utf-8
|
|
6
|
+
end_of_line = lf
|
|
7
|
+
insert_final_newline = true
|
|
8
|
+
trim_trailing_whitespace = true
|
|
9
|
+
indent_style = space
|
|
10
|
+
indent_size = 4
|
|
11
|
+
|
|
12
|
+
[*.py]
|
|
13
|
+
max_line_length = 100
|
|
14
|
+
|
|
15
|
+
[*.{yaml,yml,json,cff}]
|
|
16
|
+
indent_size = 2
|
|
17
|
+
|
|
18
|
+
[*.md]
|
|
19
|
+
# Two trailing spaces are a hard line break in Markdown
|
|
20
|
+
trim_trailing_whitespace = false
|
|
21
|
+
indent_size = 2
|
|
22
|
+
|
|
23
|
+
[*.{bat,cmd,ps1}]
|
|
24
|
+
end_of_line = crlf
|
|
25
|
+
|
|
26
|
+
[Makefile]
|
|
27
|
+
indent_style = tab
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Normalize line endings in the repository regardless of the OS
|
|
2
|
+
* text=auto eol=lf
|
|
3
|
+
|
|
4
|
+
*.bat text eol=crlf
|
|
5
|
+
*.cmd text eol=crlf
|
|
6
|
+
*.ps1 text eol=crlf
|
|
7
|
+
|
|
8
|
+
*.png binary
|
|
9
|
+
*.jpg binary
|
|
10
|
+
*.npy binary
|
|
11
|
+
*.npz binary
|
|
12
|
+
*.exr binary
|
|
13
|
+
|
|
14
|
+
# Let setuptools-scm read the version from git archives (GitHub, Zenodo)
|
|
15
|
+
.git_archival.txt export-subst
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: "Report something in RIVOLI that does not work as expected."
|
|
3
|
+
labels: [bug]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: description
|
|
7
|
+
attributes:
|
|
8
|
+
label: Bug description
|
|
9
|
+
description: >-
|
|
10
|
+
What happens, and what you expected instead. A short example reproducing it and the
|
|
11
|
+
full error message help a lot, if you have them.
|
|
12
|
+
validations:
|
|
13
|
+
required: true
|
|
14
|
+
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: system
|
|
17
|
+
attributes:
|
|
18
|
+
label: System information
|
|
19
|
+
description: "Versions of RIVOLI and Python, and operating system."
|
|
20
|
+
placeholder: "RIVOLI 0.1.0, Python 3.13, Ubuntu 24.04"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Settings of the "New issue" chooser page
|
|
2
|
+
# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser
|
|
3
|
+
|
|
4
|
+
# The forms of this folder cover the usual cases (bugs, features, questions,
|
|
5
|
+
# documentation), but a blank issue stays available for anything they do not fit.
|
|
6
|
+
# The link to report a security vulnerability privately is added by GitHub itself,
|
|
7
|
+
# from SECURITY.md
|
|
8
|
+
blank_issues_enabled: true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Documentation
|
|
2
|
+
description: "Report missing, incorrect or unclear documentation of RIVOLI."
|
|
3
|
+
labels: [documentation]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: description
|
|
7
|
+
attributes:
|
|
8
|
+
label: Documentation issue
|
|
9
|
+
description: What is missing, incorrect or unclear, and where (a link to the page or section helps).
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: suggestion
|
|
15
|
+
attributes:
|
|
16
|
+
label: Suggested improvement
|
|
17
|
+
description: How the documentation could be improved, if you have an idea.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: "Suggest a new feature or an improvement of RIVOLI."
|
|
3
|
+
labels: [enhancement]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: description
|
|
7
|
+
attributes:
|
|
8
|
+
label: Feature description
|
|
9
|
+
description: What you would like, and the need behind it.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: context
|
|
15
|
+
attributes:
|
|
16
|
+
label: Additional context
|
|
17
|
+
description: Examples, alternatives you have considered, or references to papers or other tools.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Question
|
|
2
|
+
description: "Ask a question about the usage of RIVOLI."
|
|
3
|
+
labels: [question]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: question
|
|
7
|
+
attributes:
|
|
8
|
+
label: Question
|
|
9
|
+
description: What you would like to know.
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: context
|
|
15
|
+
attributes:
|
|
16
|
+
label: Context
|
|
17
|
+
description: What you are trying to achieve, what you have already tried, and the versions you use.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
coverage:
|
|
2
|
+
status:
|
|
3
|
+
project:
|
|
4
|
+
default:
|
|
5
|
+
target: auto
|
|
6
|
+
threshold: 1%
|
|
7
|
+
patch:
|
|
8
|
+
default:
|
|
9
|
+
# Same threshold as fail_under in [tool.coverage.report] of pyproject.toml
|
|
10
|
+
target: 90%
|
|
11
|
+
|
|
12
|
+
codecov:
|
|
13
|
+
notify:
|
|
14
|
+
# Wait for the uploads of all the runs of the tests job of ci.yml. Computed
|
|
15
|
+
# from the Python versions by the template: `copier update` keeps it in sync
|
|
16
|
+
after_n_builds: 4
|
|
17
|
+
|
|
18
|
+
comment:
|
|
19
|
+
# Same as codecov.notify.after_n_builds
|
|
20
|
+
after_n_builds: 4
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Version updates of the dependencies, opened as pull requests by Dependabot
|
|
2
|
+
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference
|
|
3
|
+
#
|
|
4
|
+
# Dependabot only opens PRs: nothing changes until one is merged.
|
|
5
|
+
# In each ecosystem, an update goes into the first group it matches, so order
|
|
6
|
+
# matters. Ungrouped updates (majors, unless stated otherwise) get one PR each,
|
|
7
|
+
# so their release notes can be reviewed on their own.
|
|
8
|
+
version: 2
|
|
9
|
+
updates:
|
|
10
|
+
# GitHub Actions used in .github/workflows (pinned by SHA, version in trailing comment)
|
|
11
|
+
- package-ecosystem: "github-actions"
|
|
12
|
+
directory: "/"
|
|
13
|
+
schedule:
|
|
14
|
+
interval: "weekly"
|
|
15
|
+
day: "monday"
|
|
16
|
+
# Wait a week before proposing a new release, so compromised versions get pulled first
|
|
17
|
+
cooldown:
|
|
18
|
+
default-days: 7
|
|
19
|
+
# Follow the gitmoji + Conventional Commits convention: "⬆️ ci: bump ..."
|
|
20
|
+
commit-message:
|
|
21
|
+
prefix: "⬆️ ci"
|
|
22
|
+
groups:
|
|
23
|
+
# upload-artifact and download-artifact must share the same major version,
|
|
24
|
+
# so they always move together, majors included. They only run in release.yml,
|
|
25
|
+
# which does not run on PRs: a green CI does not prove they work.
|
|
26
|
+
artifacts:
|
|
27
|
+
patterns:
|
|
28
|
+
- "actions/upload-artifact"
|
|
29
|
+
- "actions/download-artifact"
|
|
30
|
+
# Every other action: minor and patch updates are batched into a single PR
|
|
31
|
+
actions:
|
|
32
|
+
patterns: ["*"]
|
|
33
|
+
update-types: ["minor", "patch"]
|
|
34
|
+
|
|
35
|
+
# Python dependencies of pyproject.toml, and their locked versions in uv.lock
|
|
36
|
+
- package-ecosystem: "uv"
|
|
37
|
+
directory: "/"
|
|
38
|
+
schedule:
|
|
39
|
+
interval: "weekly"
|
|
40
|
+
day: "monday"
|
|
41
|
+
# Wait a week before proposing a new release, so compromised versions get pulled first
|
|
42
|
+
cooldown:
|
|
43
|
+
default-days: 7
|
|
44
|
+
# Follow the gitmoji + Conventional Commits convention: "⬆️ build: bump ..."
|
|
45
|
+
commit-message:
|
|
46
|
+
prefix: "⬆️ build"
|
|
47
|
+
groups:
|
|
48
|
+
# Every dependency: minor and patch updates are batched into a single PR.
|
|
49
|
+
# This includes pyright, pinned in pyproject.toml: its PR is where a new
|
|
50
|
+
# release, which can add new errors, is deliberately accepted.
|
|
51
|
+
python:
|
|
52
|
+
patterns: ["*"]
|
|
53
|
+
update-types: ["minor", "patch"]
|
|
54
|
+
|
|
55
|
+
# Hooks of .pre-commit-config.yaml (rev of each hook repository)
|
|
56
|
+
- package-ecosystem: "pre-commit"
|
|
57
|
+
directory: "/"
|
|
58
|
+
schedule:
|
|
59
|
+
interval: "weekly"
|
|
60
|
+
day: "monday"
|
|
61
|
+
# Wait a week before proposing a new release, so compromised versions get pulled first
|
|
62
|
+
cooldown:
|
|
63
|
+
default-days: 7
|
|
64
|
+
# Follow the gitmoji + Conventional Commits convention: "⬆️ chore: bump ..."
|
|
65
|
+
commit-message:
|
|
66
|
+
prefix: "⬆️ chore"
|
|
67
|
+
groups:
|
|
68
|
+
# Every hook: minor and patch updates are batched into a single PR
|
|
69
|
+
hooks:
|
|
70
|
+
patterns: ["*"]
|
|
71
|
+
update-types: ["minor", "patch"]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
The title of the pull request follows gitmoji and Conventional Commits, for
|
|
3
|
+
example "✨ feat(io): add the CSV export". It becomes the commit message of the
|
|
4
|
+
squash merge, and it feeds the release notes.
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
<!-- What does this change, and why? Link the issue or the ADR it implements. -->
|
|
10
|
+
|
|
11
|
+
## Checklist
|
|
12
|
+
|
|
13
|
+
- [ ] Tests cover the change.
|
|
14
|
+
- [ ] `CHANGELOG.md` is updated, or the change is not visible to users.
|
|
15
|
+
- [ ] A decision that deserves a record has one in `docs/adr/`.
|
|
16
|
+
- [ ] Every ADR changed or added here has its final status, in its file and in the index.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "main",
|
|
3
|
+
"target": "branch",
|
|
4
|
+
"enforcement": "active",
|
|
5
|
+
"conditions": {
|
|
6
|
+
"ref_name": {
|
|
7
|
+
"exclude": [],
|
|
8
|
+
"include": [
|
|
9
|
+
"~DEFAULT_BRANCH"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"rules": [
|
|
14
|
+
{
|
|
15
|
+
"type": "deletion"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "non_fast_forward"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "required_linear_history"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "pull_request",
|
|
25
|
+
"parameters": {
|
|
26
|
+
"required_approving_review_count": 0,
|
|
27
|
+
"dismiss_stale_reviews_on_push": false,
|
|
28
|
+
"required_reviewers": [],
|
|
29
|
+
"require_code_owner_review": false,
|
|
30
|
+
"require_last_push_approval": false,
|
|
31
|
+
"required_review_thread_resolution": false,
|
|
32
|
+
"require_extra_approval_for_unattributed_changes": true,
|
|
33
|
+
"allowed_merge_methods": [
|
|
34
|
+
"squash"
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"type": "required_status_checks",
|
|
40
|
+
"parameters": {
|
|
41
|
+
"strict_required_status_checks_policy": false,
|
|
42
|
+
"do_not_enforce_on_create": false,
|
|
43
|
+
"required_status_checks": [
|
|
44
|
+
{
|
|
45
|
+
"context": "ci-passed",
|
|
46
|
+
"integration_id": 15368
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"bypass_actors": []
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "version-tags",
|
|
3
|
+
"target": "tag",
|
|
4
|
+
"enforcement": "active",
|
|
5
|
+
"conditions": {
|
|
6
|
+
"ref_name": {
|
|
7
|
+
"exclude": [],
|
|
8
|
+
"include": [
|
|
9
|
+
"refs/tags/v*"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"rules": [
|
|
14
|
+
{
|
|
15
|
+
"type": "deletion"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "non_fast_forward"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "update"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"bypass_actors": []
|
|
25
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
# Called by release.yml before publishing anything
|
|
8
|
+
workflow_call:
|
|
9
|
+
# Run by hand from the Actions tab, for example to check a branch again after
|
|
10
|
+
# a dependency release, without pushing anything
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
lint:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
25
|
+
with:
|
|
26
|
+
persist-credentials: false
|
|
27
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
28
|
+
# pre-commit is run directly, not with pre-commit/action: that action calls
|
|
29
|
+
# actions/cache by tag, which the SHA pinning required by
|
|
30
|
+
# scripts/configure-github.sh rejects
|
|
31
|
+
- run: uvx pre-commit run --all-files --show-diff-on-failure
|
|
32
|
+
env:
|
|
33
|
+
# pyright needs the project installed: it runs in the typecheck job
|
|
34
|
+
SKIP: pyright
|
|
35
|
+
|
|
36
|
+
typecheck:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
40
|
+
with:
|
|
41
|
+
# setuptools-scm needs the tags to compute the version at install time
|
|
42
|
+
fetch-depth: 0
|
|
43
|
+
persist-credentials: false
|
|
44
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
45
|
+
with:
|
|
46
|
+
# Oldest supported version, matching pythonVersion in [tool.pyright],
|
|
47
|
+
# so that dependencies are resolved as on that version
|
|
48
|
+
python-version: "3.13"
|
|
49
|
+
# --locked fails if uv.lock is out of date with pyproject.toml
|
|
50
|
+
- run: uv sync --locked
|
|
51
|
+
# --no-sync: uv run would otherwise sync the environment again
|
|
52
|
+
- run: uv run --no-sync pyright
|
|
53
|
+
|
|
54
|
+
build:
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
steps:
|
|
57
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
58
|
+
with:
|
|
59
|
+
fetch-depth: 0
|
|
60
|
+
persist-credentials: false
|
|
61
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
62
|
+
- run: uv build
|
|
63
|
+
- run: uvx twine check --strict dist/*
|
|
64
|
+
|
|
65
|
+
tests:
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
# id-token lets the Codecov upload authenticate with a short-lived OIDC token
|
|
68
|
+
# instead of a stored secret. Job-level permissions replace the workflow-level
|
|
69
|
+
# ones, so contents: read must be granted again here.
|
|
70
|
+
permissions:
|
|
71
|
+
contents: read
|
|
72
|
+
id-token: write
|
|
73
|
+
strategy:
|
|
74
|
+
fail-fast: false
|
|
75
|
+
matrix:
|
|
76
|
+
# From python_min_version of .copier-answers.yml to the newest Python
|
|
77
|
+
# release: `copier update` adds each new release.
|
|
78
|
+
# Each run uploads a coverage report: after_n_builds of .github/codecov.yml is
|
|
79
|
+
# computed from this matrix by the template, and updated along with it.
|
|
80
|
+
python-version: ["3.13", "3.14", "3.15"]
|
|
81
|
+
deps: [locked]
|
|
82
|
+
include:
|
|
83
|
+
# The locked versions hide the breaking releases of the dependencies:
|
|
84
|
+
# one more run with their newest versions catches them before the users
|
|
85
|
+
- python-version: "3.15"
|
|
86
|
+
deps: latest
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
89
|
+
with:
|
|
90
|
+
fetch-depth: 0
|
|
91
|
+
persist-credentials: false
|
|
92
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
93
|
+
with:
|
|
94
|
+
python-version: ${{ matrix.python-version }}
|
|
95
|
+
# h5py publishes no wheels for Python 3.15 yet: it is built from source, which
|
|
96
|
+
# needs the HDF5 library of the system. Remove once h5py publishes them (#37)
|
|
97
|
+
- if: matrix.python-version == '3.15'
|
|
98
|
+
run: sudo apt-get update && sudo apt-get install --yes libhdf5-dev pkg-config
|
|
99
|
+
- if: matrix.deps == 'locked'
|
|
100
|
+
run: uv sync --locked --no-default-groups --group test
|
|
101
|
+
- if: matrix.deps == 'latest'
|
|
102
|
+
run: uv sync --upgrade --no-default-groups --group test
|
|
103
|
+
# Reminder of #37: warns in the checks once the installed h5py has wheels for
|
|
104
|
+
# Python 3.15, so that the installation of HDF5 above can be removed
|
|
105
|
+
- if: matrix.python-version == '3.15'
|
|
106
|
+
run: |
|
|
107
|
+
version=$(uv run --no-sync python -c "import importlib.metadata as m; print(m.version('h5py'))")
|
|
108
|
+
if curl --fail --silent --show-error "https://pypi.org/pypi/h5py/$version/json" | grep --quiet "cp315-"; then
|
|
109
|
+
echo "::warning::h5py $version has wheels for Python 3.15: remove the installation of HDF5 from the CI (#37)"
|
|
110
|
+
fi
|
|
111
|
+
- run: uv run --no-sync pytest --cov --cov-report=term --cov-report=xml
|
|
112
|
+
- uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
|
|
113
|
+
with:
|
|
114
|
+
use_oidc: true
|
|
115
|
+
files: coverage.xml
|
|
116
|
+
disable_search: true
|
|
117
|
+
fail_ci_if_error: true
|
|
118
|
+
|
|
119
|
+
# Single required status check for the main branch ruleset: it passes only
|
|
120
|
+
# if every job below succeeded, so the matrix can change without updating
|
|
121
|
+
# the ruleset. Any new job must be added to `needs`, or its failure will not
|
|
122
|
+
# block merging.
|
|
123
|
+
ci-passed:
|
|
124
|
+
# A job whose dependency failed is skipped, and a skipped required check
|
|
125
|
+
# counts as passing: always() makes it run and report the real outcome
|
|
126
|
+
if: always()
|
|
127
|
+
needs: [lint, typecheck, build, tests]
|
|
128
|
+
runs-on: ubuntu-latest
|
|
129
|
+
steps:
|
|
130
|
+
# A cancelled job proved nothing, so it fails the check too
|
|
131
|
+
- if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')
|
|
132
|
+
run: exit 1
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions: {}
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
ci:
|
|
11
|
+
# "$/": the self-repository syntax always loads the workflow of this repository
|
|
12
|
+
# at the same commit, never a file of the workspace (unlike "./")
|
|
13
|
+
uses: $/.github/workflows/ci.yml
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
# The tests job of the CI uploads the coverage with an OIDC token
|
|
17
|
+
id-token: write
|
|
18
|
+
|
|
19
|
+
# A forgotten `scripts/release.py prepare` fails the release here, before
|
|
20
|
+
# anything is published: the changelog must have a section for the tag, and
|
|
21
|
+
# CITATION.cff its version and date. Pre-releases (a, b, rc) are not checked.
|
|
22
|
+
changelog:
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
28
|
+
with:
|
|
29
|
+
persist-credentials: false
|
|
30
|
+
# The script only needs the standard library: the Python of the runner is enough
|
|
31
|
+
- run: |
|
|
32
|
+
if [[ "$GITHUB_REF_NAME" =~ (a|b|rc)[0-9]+$ ]]; then exit 0; fi
|
|
33
|
+
python3 scripts/release.py check "$GITHUB_REF_NAME"
|
|
34
|
+
|
|
35
|
+
build:
|
|
36
|
+
needs: [ci, changelog]
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
permissions:
|
|
39
|
+
contents: read
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
42
|
+
with:
|
|
43
|
+
fetch-depth: 0
|
|
44
|
+
persist-credentials: false
|
|
45
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
46
|
+
with:
|
|
47
|
+
# A cache restored in a release job could inject altered packages into
|
|
48
|
+
# the published distributions: build from a clean environment
|
|
49
|
+
enable-cache: false
|
|
50
|
+
- run: uv build
|
|
51
|
+
- run: uvx twine check --strict dist/*
|
|
52
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
53
|
+
with:
|
|
54
|
+
name: dist
|
|
55
|
+
path: dist/
|
|
56
|
+
|
|
57
|
+
publish-testpypi:
|
|
58
|
+
needs: build
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
environment:
|
|
61
|
+
name: testpypi
|
|
62
|
+
url: https://test.pypi.org/project/rivoli/
|
|
63
|
+
permissions:
|
|
64
|
+
id-token: write
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
67
|
+
with:
|
|
68
|
+
name: dist
|
|
69
|
+
path: dist/
|
|
70
|
+
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
71
|
+
with:
|
|
72
|
+
repository-url: https://test.pypi.org/legacy/
|
|
73
|
+
skip-existing: true
|
|
74
|
+
|
|
75
|
+
publish-pypi:
|
|
76
|
+
needs: publish-testpypi
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
environment:
|
|
79
|
+
name: pypi
|
|
80
|
+
url: https://pypi.org/project/rivoli/
|
|
81
|
+
permissions:
|
|
82
|
+
id-token: write
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
85
|
+
with:
|
|
86
|
+
name: dist
|
|
87
|
+
path: dist/
|
|
88
|
+
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
89
|
+
|
|
90
|
+
github-release:
|
|
91
|
+
needs: publish-pypi
|
|
92
|
+
runs-on: ubuntu-latest
|
|
93
|
+
permissions:
|
|
94
|
+
contents: write
|
|
95
|
+
id-token: write
|
|
96
|
+
steps:
|
|
97
|
+
# The notes of the release come from CHANGELOG.md. Checked out first: the
|
|
98
|
+
# checkout empties the working directory
|
|
99
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
100
|
+
with:
|
|
101
|
+
persist-credentials: false
|
|
102
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
103
|
+
with:
|
|
104
|
+
name: dist
|
|
105
|
+
path: dist/
|
|
106
|
+
- uses: sigstore/gh-action-sigstore-python@790bc6befb9d733738f18d8f895854b453640ec9 # v3.5.0
|
|
107
|
+
with:
|
|
108
|
+
inputs: >-
|
|
109
|
+
./dist/*.tar.gz
|
|
110
|
+
./dist/*.whl
|
|
111
|
+
- env:
|
|
112
|
+
GH_TOKEN: ${{ github.token }}
|
|
113
|
+
# Passed through the environment, never interpolated in the script
|
|
114
|
+
PROJECT_NAME: "RIVOLI"
|
|
115
|
+
# The changelog section of the version becomes the notes of the release,
|
|
116
|
+
# and the description of its Zenodo record. Pre-releases have no section:
|
|
117
|
+
# their notes are generated from the merged pull requests instead
|
|
118
|
+
run: |
|
|
119
|
+
if [[ "$GITHUB_REF_NAME" =~ (a|b|rc)[0-9]+$ ]]; then
|
|
120
|
+
flags=(--prerelease --generate-notes)
|
|
121
|
+
else
|
|
122
|
+
python3 scripts/release.py notes "$GITHUB_REF_NAME" > "$RUNNER_TEMP/notes.md"
|
|
123
|
+
flags=(--notes-file "$RUNNER_TEMP/notes.md")
|
|
124
|
+
fi
|
|
125
|
+
gh release create "$GITHUB_REF_NAME" dist/* \
|
|
126
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
127
|
+
--title "$PROJECT_NAME ${GITHUB_REF_NAME#v}" \
|
|
128
|
+
--verify-tag \
|
|
129
|
+
"${flags[@]}"
|