rhiza 0.9.0__tar.gz → 0.9.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 (116) hide show
  1. rhiza-0.9.1/.github/workflows/rhiza_benchmarks.yml +83 -0
  2. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_book.yml +10 -7
  3. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_ci.yml +31 -7
  4. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_codeql.yml +3 -3
  5. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_deptry.yml +3 -3
  6. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_marimo.yml +7 -4
  7. rhiza-0.9.1/.github/workflows/rhiza_mypy.yml +34 -0
  8. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_pre-commit.yml +2 -2
  9. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_release.yml +37 -38
  10. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_security.yml +10 -2
  11. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_sync.yml +15 -6
  12. {rhiza-0.9.0 → rhiza-0.9.1}/.github/workflows/rhiza_validate.yml +2 -2
  13. {rhiza-0.9.0 → rhiza-0.9.1}/.gitignore +1 -0
  14. {rhiza-0.9.0 → rhiza-0.9.1}/.pre-commit-config.yaml +11 -17
  15. rhiza-0.9.1/.rhiza/.rhiza-version +1 -0
  16. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/history +5 -3
  17. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/rhiza.mk +26 -7
  18. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/scripts/release.sh +61 -20
  19. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/utils/version_matrix.py +41 -6
  20. {rhiza-0.9.0 → rhiza-0.9.1}/PKG-INFO +1 -1
  21. {rhiza-0.9.0 → rhiza-0.9.1}/book/README.md +22 -0
  22. {rhiza-0.9.0 → rhiza-0.9.1}/book/book.mk +46 -1
  23. {rhiza-0.9.0 → rhiza-0.9.1}/book/marimo/marimo.mk +1 -1
  24. rhiza-0.9.1/pr-description.md +83 -0
  25. {rhiza-0.9.0 → rhiza-0.9.1}/pyproject.toml +28 -1
  26. {rhiza-0.9.0 → rhiza-0.9.1}/renovate.json +1 -0
  27. {rhiza-0.9.0 → rhiza-0.9.1}/ruff.toml +2 -1
  28. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/__main__.py +1 -1
  29. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/cli.py +10 -10
  30. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/__init__.py +5 -3
  31. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/init.py +2 -2
  32. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/materialize.py +39 -14
  33. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/summarise.py +1 -1
  34. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/validate.py +7 -6
  35. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/welcome.py +1 -1
  36. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/models.py +26 -4
  37. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_commands/test_materialize.py +33 -6
  38. rhiza-0.9.1/tests/test_commands/test_summarise.py +477 -0
  39. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_models.py +37 -0
  40. rhiza-0.9.1/tests/test_rhiza/__init__.py +5 -0
  41. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/conftest.py +54 -3
  42. rhiza-0.9.1/tests/test_rhiza/test_book.py +68 -0
  43. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_docstrings.py +21 -11
  44. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_makefile.py +118 -33
  45. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_makefile_api.py +1 -0
  46. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_marimushka_target.py +14 -13
  47. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_notebooks.py +3 -3
  48. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_release_script.py +100 -0
  49. rhiza-0.9.1/tests/test_rhiza/test_rhiza_workflows.py +227 -0
  50. rhiza-0.9.1/tests/test_rhiza/test_version_matrix.py +264 -0
  51. {rhiza-0.9.0 → rhiza-0.9.1}/tests/tests.mk +22 -4
  52. {rhiza-0.9.0 → rhiza-0.9.1}/uv.lock +185 -184
  53. rhiza-0.9.0/.github/workflows/rhiza_benchmarks.yml +0 -51
  54. rhiza-0.9.0/.rhiza/scripts/check_workflow_names.py +0 -73
  55. rhiza-0.9.0/book/pdoc-templates/module.html.jinja2 +0 -19
  56. rhiza-0.9.0/tests/test_commands/test_summarise.py +0 -101
  57. rhiza-0.9.0/tests/test_rhiza/test_check_workflow_names.py +0 -115
  58. rhiza-0.9.0/tests/test_rhiza/test_version_matrix.py +0 -137
  59. {rhiza-0.9.0 → rhiza-0.9.1}/.editorconfig +0 -0
  60. {rhiza-0.9.0 → rhiza-0.9.1}/.github/ISSUE_TEMPLATE/assign_ui_implementation.md +0 -0
  61. {rhiza-0.9.0 → rhiza-0.9.1}/.github/agents/agentic.mk +0 -0
  62. {rhiza-0.9.0 → rhiza-0.9.1}/.github/agents/analyser.md +0 -0
  63. {rhiza-0.9.0 → rhiza-0.9.1}/.github/agents/summarise.md +0 -0
  64. {rhiza-0.9.0 → rhiza-0.9.1}/.github/copilot-instructions.md +0 -0
  65. {rhiza-0.9.0 → rhiza-0.9.1}/.github/github.mk +0 -0
  66. {rhiza-0.9.0 → rhiza-0.9.1}/.python-version +0 -0
  67. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/.cfg.toml +0 -0
  68. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/.gitignore +0 -0
  69. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/docs/CONFIG.md +0 -0
  70. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/docs/TOKEN_SETUP.md +0 -0
  71. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/make.d/01-custom-env.mk +0 -0
  72. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/make.d/10-custom-task.mk +0 -0
  73. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/make.d/README.md +0 -0
  74. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/requirements/README.md +0 -0
  75. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/requirements/docs.txt +0 -0
  76. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/requirements/marimo.txt +0 -0
  77. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/requirements/tests.txt +0 -0
  78. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/requirements/tools.txt +0 -0
  79. {rhiza-0.9.0 → rhiza-0.9.1}/.rhiza/template.yml +0 -0
  80. {rhiza-0.9.0 → rhiza-0.9.1}/CLI.md +0 -0
  81. {rhiza-0.9.0 → rhiza-0.9.1}/CODE_OF_CONDUCT.md +0 -0
  82. {rhiza-0.9.0 → rhiza-0.9.1}/CONTRIBUTING.md +0 -0
  83. {rhiza-0.9.0 → rhiza-0.9.1}/GETTING_STARTED.md +0 -0
  84. {rhiza-0.9.0 → rhiza-0.9.1}/LICENSE +0 -0
  85. {rhiza-0.9.0 → rhiza-0.9.1}/Makefile +0 -0
  86. {rhiza-0.9.0 → rhiza-0.9.1}/README.md +0 -0
  87. {rhiza-0.9.0 → rhiza-0.9.1}/USAGE.md +0 -0
  88. {rhiza-0.9.0 → rhiza-0.9.1}/book/marimo/.gitkeep +0 -0
  89. {rhiza-0.9.0 → rhiza-0.9.1}/book/marimo/README.md +0 -0
  90. {rhiza-0.9.0 → rhiza-0.9.1}/book/marimo/notebooks/rhiza.py +0 -0
  91. {rhiza-0.9.0 → rhiza-0.9.1}/book/minibook-templates/custom.html.jinja2 +0 -0
  92. {rhiza-0.9.0 → rhiza-0.9.1}/presentation/README.md +0 -0
  93. {rhiza-0.9.0 → rhiza-0.9.1}/presentation/presentation.mk +0 -0
  94. {rhiza-0.9.0 → rhiza-0.9.1}/pytest.ini +0 -0
  95. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/__init__.py +0 -0
  96. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/_templates/basic/__init__.py.jinja2 +0 -0
  97. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/_templates/basic/main.py.jinja2 +0 -0
  98. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/_templates/basic/pyproject.toml.jinja2 +0 -0
  99. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/migrate.py +0 -0
  100. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/commands/uninstall.py +0 -0
  101. {rhiza-0.9.0 → rhiza-0.9.1}/src/rhiza/subprocess_utils.py +0 -0
  102. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_cli_commands.py +0 -0
  103. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_commands/test_init.py +0 -0
  104. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_commands/test_migrate.py +0 -0
  105. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_commands/test_uninstall.py +0 -0
  106. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_commands/test_validate.py +0 -0
  107. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_package.py +0 -0
  108. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/README.md +0 -0
  109. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/benchmarks/.gitignore +0 -0
  110. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/benchmarks/README.md +0 -0
  111. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/benchmarks/analyze_benchmarks.py +0 -0
  112. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_git_repo_fixture.py +0 -0
  113. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_makefile_gh.py +0 -0
  114. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_readme.py +0 -0
  115. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_requirements_folder.py +0 -0
  116. {rhiza-0.9.0 → rhiza-0.9.1}/tests/test_rhiza/test_structure.py +0 -0
@@ -0,0 +1,83 @@
1
+ # This file is part of the jebel-quant/rhiza repository
2
+ # (https://github.com/jebel-quant/rhiza).
3
+ #
4
+ # Workflow: Performance Benchmarks
5
+ #
6
+ # Purpose: Run performance benchmarks and detect regressions.
7
+ #
8
+ # Trigger: On push to main/master branches, PRs, and manual trigger.
9
+ #
10
+ # Regression Detection:
11
+ # - Compares against previous benchmark results stored in gh-pages branch
12
+ # - Alerts if performance degrades by more than 150% (configurable)
13
+ # - PRs will show a warning comment but not fail
14
+ # - Main branch updates the baseline for future comparisons
15
+
16
+ name: "(RHIZA) BENCHMARKS"
17
+
18
+ permissions:
19
+ contents: write
20
+ pull-requests: write
21
+
22
+ on:
23
+ push:
24
+ branches: [ main, master ]
25
+ pull_request:
26
+ branches: [ main, master ]
27
+ workflow_dispatch:
28
+
29
+ jobs:
30
+ benchmark:
31
+ runs-on: ubuntu-latest
32
+
33
+ steps:
34
+ - name: Checkout repository
35
+ uses: actions/checkout@v6.0.2
36
+ with:
37
+ lfs: true
38
+
39
+ - name: Install uv
40
+ uses: astral-sh/setup-uv@v7.2.1
41
+ with:
42
+ version: "0.9.28"
43
+ python-version: "3.12"
44
+
45
+ - name: Run benchmarks
46
+ env:
47
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
48
+ run: |
49
+ make benchmark
50
+
51
+ - name: Upload benchmark results
52
+ uses: actions/upload-artifact@v6.0.0
53
+ if: always()
54
+ with:
55
+ name: benchmark-results
56
+ path: |
57
+ _benchmarks/benchmarks.json
58
+ _benchmarks/benchmarks.svg
59
+ _benchmarks/benchmarks.html
60
+
61
+ # Regression detection using github-action-benchmark
62
+ # Stores benchmark history in gh-pages branch under /benchmarks
63
+ # Alerts if performance degrades by more than 150% of baseline
64
+ - name: Store benchmark result and check for regression
65
+ uses: benchmark-action/github-action-benchmark@v1
66
+ # run this only if _benchmarks/benchmarks.json exists
67
+ if: hashFiles('_benchmarks/benchmarks.json') != ''
68
+ with:
69
+ tool: 'pytest'
70
+ output-file-path: _benchmarks/benchmarks.json
71
+ # Store benchmark data in gh-pages branch
72
+ gh-pages-branch: gh-pages
73
+ benchmark-data-dir-path: benchmarks
74
+ # Only update baseline on main branch push (not PRs)
75
+ auto-push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
76
+ # Alert if performance degrades by more than 150%
77
+ alert-threshold: '150%'
78
+ # Post comment on PR if regression detected
79
+ comment-on-alert: ${{ github.event_name == 'pull_request' }}
80
+ # Fail workflow if regression detected (disabled for PRs to allow investigation)
81
+ fail-on-alert: ${{ github.event_name == 'push' }}
82
+ # GitHub token for pushing to gh-pages and commenting
83
+ github-token: ${{ secrets.GITHUB_TOKEN }}
@@ -36,30 +36,33 @@ jobs:
36
36
 
37
37
  steps:
38
38
  # Check out the repository code
39
- - uses: actions/checkout@v6
39
+ - uses: actions/checkout@v6.0.2
40
40
  with:
41
41
  lfs: true
42
42
 
43
43
  - name: Install uv
44
- uses: astral-sh/setup-uv@v7
44
+ uses: astral-sh/setup-uv@v7.2.1
45
45
  with:
46
- version: "0.9.26"
46
+ version: "0.9.28"
47
47
 
48
48
  - name: "Sync the virtual environment for ${{ github.repository }}"
49
49
  shell: bash
50
+ env:
51
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
50
52
  run: |
51
- export UV_EXTRA_INDEX_URL="${{ secrets.uv-extra-index-url }}"
52
53
  # will just use .python-version?
53
54
  uv sync --all-extras --all-groups --frozen
54
55
 
55
56
  - name: "Make the book"
57
+ env:
58
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
56
59
  run: |
57
- make -f .rhiza/rhiza.mk book
60
+ make book
58
61
 
59
62
  # Step 5: Package all artifacts for GitHub Pages deployment
60
63
  # This prepares the combined outputs for deployment by creating a single artifact
61
64
  - name: Upload static files as artifact
62
- uses: actions/upload-pages-artifact@v4 # Official GitHub Pages artifact upload action
65
+ uses: actions/upload-pages-artifact@v4.0.0 # Official GitHub Pages artifact upload action
63
66
  with:
64
67
  path: _book/ # Path to the directory containing all artifacts to deploy
65
68
 
@@ -70,5 +73,5 @@ jobs:
70
73
  # If PUBLISH_COMPANION_BOOK is not set, it defaults to allowing deployment
71
74
  - name: Deploy to GitHub Pages
72
75
  if: ${{ !github.event.repository.fork && (vars.PUBLISH_COMPANION_BOOK == 'true' || vars.PUBLISH_COMPANION_BOOK == '') }}
73
- uses: actions/deploy-pages@v4 # Official GitHub Pages deployment action
76
+ uses: actions/deploy-pages@v4.0.5 # Official GitHub Pages deployment action
74
77
  continue-on-error: true
@@ -24,14 +24,18 @@ jobs:
24
24
  outputs:
25
25
  matrix: ${{ steps.versions.outputs.list }}
26
26
  steps:
27
- - uses: actions/checkout@v6
27
+ - uses: actions/checkout@v6.0.2
28
+ with:
29
+ lfs: true
28
30
 
29
31
  - name: Install uv
30
- uses: astral-sh/setup-uv@v7
32
+ uses: astral-sh/setup-uv@v7.2.1
31
33
  with:
32
- version: "0.9.26"
34
+ version: "0.9.28"
33
35
 
34
36
  - id: versions
37
+ env:
38
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
35
39
  run: |
36
40
  # Generate Python versions JSON from the script
37
41
  JSON=$(make -f .rhiza/rhiza.mk -s version-matrix)
@@ -51,16 +55,36 @@ jobs:
51
55
 
52
56
  steps:
53
57
  - name: Checkout repository
54
- uses: actions/checkout@v6
58
+ uses: actions/checkout@v6.0.2
55
59
  with:
56
60
  lfs: true
57
61
 
58
62
  - name: Install uv
59
- uses: astral-sh/setup-uv@v7
63
+ uses: astral-sh/setup-uv@v7.2.1
60
64
  with:
61
- version: "0.9.26"
65
+ version: "0.9.28"
62
66
  python-version: ${{ matrix.python-version }}
63
67
 
64
68
  - name: Run tests
69
+ env:
70
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
71
+ run: |
72
+ make test
73
+
74
+
75
+ docs-coverage:
76
+ runs-on: ubuntu-latest
77
+ steps:
78
+ - name: Checkout repository
79
+ uses: actions/checkout@v6.0.2
80
+
81
+ - name: Install uv
82
+ uses: astral-sh/setup-uv@v7.2.1
83
+ with:
84
+ version: "0.9.28"
85
+
86
+ - name: Check docs coverage
87
+ env:
88
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
65
89
  run: |
66
- make -f .rhiza/rhiza.mk test
90
+ make docs-coverage
@@ -81,7 +81,7 @@ jobs:
81
81
  # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
82
82
  steps:
83
83
  - name: Checkout repository
84
- uses: actions/checkout@v6
84
+ uses: actions/checkout@v6.0.2
85
85
 
86
86
  # Add any setup steps before running the `github/codeql-action/init` action.
87
87
  # This includes steps like installing compilers or runtimes (`actions/setup-node`
@@ -91,7 +91,7 @@ jobs:
91
91
 
92
92
  # Initializes the CodeQL tools for scanning.
93
93
  - name: Initialize CodeQL
94
- uses: github/codeql-action/init@v4
94
+ uses: github/codeql-action/init@v4.32.0
95
95
  with:
96
96
  languages: ${{ matrix.language }}
97
97
  build-mode: ${{ matrix.build-mode }}
@@ -120,6 +120,6 @@ jobs:
120
120
  exit 1
121
121
 
122
122
  - name: Perform CodeQL Analysis
123
- uses: github/codeql-action/analyze@v4
123
+ uses: github/codeql-action/analyze@v4.32.0
124
124
  with:
125
125
  category: "/language:${{matrix.language}}"
@@ -27,13 +27,13 @@ jobs:
27
27
  name: Check dependencies with deptry
28
28
  runs-on: ubuntu-latest
29
29
  container:
30
- image: ghcr.io/astral-sh/uv:0.9.26-python3.12-trixie
30
+ image: ghcr.io/astral-sh/uv:0.9.28-bookworm
31
31
 
32
32
  steps:
33
- - uses: actions/checkout@v6
33
+ - uses: actions/checkout@v6.0.2
34
34
 
35
35
  - name: Run deptry
36
- run: make -f .rhiza/rhiza.mk deptry
36
+ run: make deptry
37
37
  # NOTE: make deptry is good style because it encapsulates the folders to check
38
38
  # (e.g. src and book/marimo) and keeps CI in sync with local development.
39
39
  # Since we use a 'uv' container, the Makefile is optimised to use the
@@ -34,13 +34,14 @@ jobs:
34
34
  notebook-list: ${{ steps.notebooks.outputs.matrix }}
35
35
  steps:
36
36
  # Check out the repository code
37
- - uses: actions/checkout@v6
37
+ - uses: actions/checkout@v6.0.2
38
38
 
39
39
  # Find all Python files in the marimo folder and create a matrix for parallel execution
40
40
  - name: Find notebooks and build matrix
41
41
  id: notebooks
42
42
  run: |
43
43
  # Extract MARIMO_FOLDER from the project configuration (via Makefile)
44
+ # shellcheck disable=SC2016 # Single quotes intentional - Make syntax, not shell expansion
44
45
  NOTEBOOK_DIR=$(make -s -f Makefile -f - <<< 'print: ; @echo $(or $(MARIMO_FOLDER),marimo)' print)
45
46
 
46
47
  echo "Searching notebooks in: $NOTEBOOK_DIR"
@@ -74,18 +75,20 @@ jobs:
74
75
  name: Run notebook ${{ matrix.notebook }}
75
76
  steps:
76
77
  # Check out the repository code
77
- - uses: actions/checkout@v6
78
+ - uses: actions/checkout@v6.0.2
78
79
  with:
79
80
  lfs: true
80
81
 
81
82
  # Install uv/uvx
82
83
  - name: Install uv
83
- uses: astral-sh/setup-uv@v7
84
+ uses: astral-sh/setup-uv@v7.2.1
84
85
  with:
85
- version: "0.9.26"
86
+ version: "0.9.28"
86
87
 
87
88
  # Execute the notebook with the appropriate runner based on its content
88
89
  - name: Run notebook
90
+ env:
91
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
89
92
  run: |
90
93
  uvx uv run "${{ matrix.notebook }}"
91
94
  # uvx → creates a fresh ephemeral environment
@@ -0,0 +1,34 @@
1
+ # This file is part of the jebel-quant/rhiza repository
2
+ # (https://github.com/jebel-quant/rhiza).
3
+ #
4
+ # Workflow: Mypy
5
+ #
6
+ # Purpose: Run static type checking with mypy in strict mode to ensure
7
+ # type safety across the codebase.
8
+ #
9
+ # Trigger: On push and pull requests to main/master branches.
10
+
11
+ name: "(RHIZA) MYPY"
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ on:
17
+ push:
18
+ branches: [ main, master ]
19
+ pull_request:
20
+ branches: [ main, master ]
21
+
22
+ jobs:
23
+ mypy:
24
+ name: Static type checking with mypy
25
+ runs-on: ubuntu-latest
26
+ container:
27
+ image: ghcr.io/astral-sh/uv:0.9.28-bookworm
28
+
29
+ steps:
30
+ - uses: actions/checkout@v6
31
+
32
+ # to brutal for now
33
+ # - name: Run mypy
34
+ # run: make -f .rhiza/rhiza.mk mypy
@@ -29,9 +29,9 @@ jobs:
29
29
  runs-on: ubuntu-latest
30
30
 
31
31
  steps:
32
- - uses: actions/checkout@v6
32
+ - uses: actions/checkout@v6.0.2
33
33
 
34
34
  # Run pre-commit
35
35
  - name: Run pre-commit
36
36
  run: |
37
- make -f .rhiza/rhiza.mk fmt
37
+ make fmt
@@ -33,6 +33,7 @@
33
33
  # - No PyPI credentials stored; relies on Trusted Publishing via GitHub OIDC
34
34
  # - For custom feeds, PYPI_TOKEN secret is used with default username __token__
35
35
  # - Container registry uses GITHUB_TOKEN for authentication
36
+ # - SLSA provenance attestations generated for build artifacts (public repos only)
36
37
  #
37
38
  # 📄 Requirements:
38
39
  # - pyproject.toml with top-level version field (for Python packages)
@@ -61,9 +62,10 @@ on:
61
62
  - 'v*'
62
63
 
63
64
  permissions:
64
- contents: write # Needed to create releases
65
- id-token: write # Needed for OIDC authentication with PyPI
66
- packages: write # Needed to publish devcontainer image
65
+ contents: write # Needed to create releases
66
+ id-token: write # Needed for OIDC authentication with PyPI
67
+ packages: write # Needed to publish devcontainer image
68
+ attestations: write # Needed for SLSA provenance attestations (public repos only)
67
69
 
68
70
  jobs:
69
71
  tag:
@@ -73,7 +75,7 @@ jobs:
73
75
  tag: ${{ steps.set_tag.outputs.tag }}
74
76
  steps:
75
77
  - name: Checkout Code
76
- uses: actions/checkout@v6
78
+ uses: actions/checkout@v6.0.2
77
79
  with:
78
80
  fetch-depth: 0
79
81
 
@@ -81,7 +83,7 @@ jobs:
81
83
  id: set_tag
82
84
  run: |
83
85
  TAG="${GITHUB_REF#refs/tags/}"
84
- echo "tag=$TAG" >> $GITHUB_OUTPUT
86
+ echo "tag=$TAG" >> "$GITHUB_OUTPUT"
85
87
 
86
88
  - name: Validate Release
87
89
  env:
@@ -104,21 +106,14 @@ jobs:
104
106
  needs: tag
105
107
  steps:
106
108
  - name: Checkout Code
107
- uses: actions/checkout@v6
109
+ uses: actions/checkout@v6.0.2
108
110
  with:
109
111
  fetch-depth: 0
110
112
 
111
113
  - name: Install uv
112
- uses: astral-sh/setup-uv@v7
114
+ uses: astral-sh/setup-uv@v7.2.1
113
115
  with:
114
- version: "0.9.26"
115
-
116
- - name: "Sync the virtual environment for ${{ github.repository }}"
117
- shell: bash
118
- run: |
119
- export UV_EXTRA_INDEX_URL="${{ secrets.uv-extra-index-url }}"
120
- # will just use .python-version?
121
- uv sync --all-extras --all-groups --frozen
116
+ version: "0.9.28"
122
117
 
123
118
  - name: Verify version matches tag
124
119
  if: hashFiles('pyproject.toml') != ''
@@ -148,10 +143,15 @@ jobs:
148
143
  printf "[INFO] Building package...\n"
149
144
  uvx hatch build
150
145
 
146
+ - name: Generate SLSA provenance attestations
147
+ if: steps.buildable.outputs.buildable == 'true' && github.event.repository.private == false
148
+ uses: actions/attest-build-provenance@v3
149
+ with:
150
+ subject-path: dist/*
151
151
 
152
152
  - name: Upload dist artifact
153
153
  if: steps.buildable.outputs.buildable == 'true'
154
- uses: actions/upload-artifact@v6
154
+ uses: actions/upload-artifact@v6.0.0
155
155
  with:
156
156
  name: dist
157
157
  path: dist
@@ -182,12 +182,12 @@ jobs:
182
182
 
183
183
  steps:
184
184
  - name: Checkout Code
185
- uses: actions/checkout@v6
185
+ uses: actions/checkout@v6.0.2
186
186
  with:
187
187
  fetch-depth: 0
188
188
 
189
189
  - name: Download dist artifact
190
- uses: actions/download-artifact@v7
190
+ uses: actions/download-artifact@v7.0.0
191
191
  with:
192
192
  name: dist
193
193
  path: dist
@@ -199,15 +199,15 @@ jobs:
199
199
  run: |
200
200
  if [[ ! -d dist ]]; then
201
201
  echo "::warning::No folder dist/. Skipping PyPI publish."
202
- echo "should_publish=false" >> $GITHUB_OUTPUT
202
+ echo "should_publish=false" >> "$GITHUB_OUTPUT"
203
203
  else
204
204
  if grep -R "Private :: Do Not Upload" pyproject.toml; then
205
- echo "should_publish=false" >> $GITHUB_OUTPUT
205
+ echo "should_publish=false" >> "$GITHUB_OUTPUT"
206
206
  else
207
- echo "should_publish=true" >> $GITHUB_OUTPUT
207
+ echo "should_publish=true" >> "$GITHUB_OUTPUT"
208
208
  fi
209
209
  fi
210
- cat $GITHUB_OUTPUT
210
+ cat "$GITHUB_OUTPUT"
211
211
 
212
212
  # this should not take place, as "Private :: Do Not Upload" set in pyproject.toml
213
213
  # repository-url and password only used for custom feeds, not for PyPI with OIDC
@@ -230,7 +230,7 @@ jobs:
230
230
  image_name: ${{ steps.image_name.outputs.image_name }}
231
231
  steps:
232
232
  - name: Checkout Code
233
- uses: actions/checkout@v6
233
+ uses: actions/checkout@v6.0.2
234
234
  with:
235
235
  fetch-depth: 0
236
236
 
@@ -240,10 +240,10 @@ jobs:
240
240
  PUBLISH_DEVCONTAINER: ${{ vars.PUBLISH_DEVCONTAINER }}
241
241
  run: |
242
242
  if [[ "$PUBLISH_DEVCONTAINER" == "true" ]] && [[ -d ".devcontainer" ]]; then
243
- echo "should_publish=true" >> $GITHUB_OUTPUT
243
+ echo "should_publish=true" >> "$GITHUB_OUTPUT"
244
244
  echo "🚀 Will build and publish devcontainer image"
245
245
  else
246
- echo "should_publish=false" >> $GITHUB_OUTPUT
246
+ echo "should_publish=false" >> "$GITHUB_OUTPUT"
247
247
  echo "⏭️ Skipping devcontainer publish (PUBLISH_DEVCONTAINER not true or .devcontainer missing)"
248
248
  fi
249
249
 
@@ -255,11 +255,11 @@ jobs:
255
255
  if [ -z "$REGISTRY" ]; then
256
256
  REGISTRY="ghcr.io"
257
257
  fi
258
- echo "registry=$REGISTRY" >> $GITHUB_OUTPUT
258
+ echo "registry=$REGISTRY" >> "$GITHUB_OUTPUT"
259
259
 
260
260
  - name: Login to Container Registry
261
261
  if: steps.check_publish.outputs.should_publish == 'true'
262
- uses: docker/login-action@v3
262
+ uses: docker/login-action@v3.7.0
263
263
  with:
264
264
  registry: ${{ steps.registry.outputs.registry }}
265
265
  username: ${{ github.repository_owner }}
@@ -268,7 +268,7 @@ jobs:
268
268
  - name: Get lowercase repository owner
269
269
  if: steps.check_publish.outputs.should_publish == 'true'
270
270
  id: repo_owner
271
- run: echo "owner_lc=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
271
+ run: echo "owner_lc=$(echo '${{ github.repository_owner }}' | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT"
272
272
 
273
273
  - name: Get Image Name
274
274
  if: steps.check_publish.outputs.should_publish == 'true'
@@ -297,7 +297,7 @@ jobs:
297
297
 
298
298
  IMAGE_NAME="${{ steps.registry.outputs.registry }}/${{ steps.repo_owner.outputs.owner_lc }}/$IMAGE_NAME"
299
299
  echo "✅ Final image name: $IMAGE_NAME"
300
- echo "image_name=$IMAGE_NAME" >> $GITHUB_OUTPUT
300
+ echo "image_name=$IMAGE_NAME" >> "$GITHUB_OUTPUT"
301
301
 
302
302
  - name: Build and Publish Devcontainer Image
303
303
  if: steps.check_publish.outputs.should_publish == 'true'
@@ -315,30 +315,29 @@ jobs:
315
315
  if: needs.pypi.result == 'success' || needs.devcontainer.result == 'success'
316
316
  steps:
317
317
  - name: Checkout Code
318
- uses: actions/checkout@v6
318
+ uses: actions/checkout@v6.0.2
319
319
  with:
320
320
  fetch-depth: 0
321
321
 
322
322
  - name: Install uv
323
- uses: astral-sh/setup-uv@v7
323
+ uses: astral-sh/setup-uv@v7.2.1
324
324
  with:
325
- version: "0.9.26"
325
+ version: "0.9.28"
326
326
 
327
327
  - name: "Sync the virtual environment for ${{ github.repository }}"
328
328
  shell: bash
329
329
  run: |
330
- export UV_EXTRA_INDEX_URL="${{ secrets.uv-extra-index-url }}"
330
+ export UV_EXTRA_INDEX_URL="${{ secrets.uv_extra_index_url }}"
331
331
  # will just use .python-version?
332
332
  uv sync --all-extras --all-groups --frozen
333
333
 
334
334
  - name: Set up Python
335
- uses: actions/setup-python@v6
335
+ uses: actions/setup-python@v6.2.0
336
336
 
337
337
  - name: Generate Devcontainer Link
338
338
  id: devcontainer_link
339
339
  if: needs.devcontainer.outputs.should_publish == 'true' && needs.devcontainer.result == 'success'
340
340
  run: |
341
- OWNER_LC=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
342
341
  FULL_IMAGE="${{ needs.devcontainer.outputs.image_name }}:${{ needs.tag.outputs.tag }}"
343
342
  {
344
343
  echo "message<<EOF"
@@ -346,13 +345,13 @@ jobs:
346
345
  echo ""
347
346
  echo "\`$FULL_IMAGE\`"
348
347
  echo "EOF"
349
- } >> $GITHUB_OUTPUT
348
+ } >> "$GITHUB_OUTPUT"
350
349
 
351
350
  - name: Generate PyPI Link
352
351
  id: pypi_link
353
352
  if: needs.pypi.outputs.should_publish == 'true' && needs.pypi.result == 'success'
354
353
  run: |
355
- PACKAGE_NAME=$(python3 -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])")
354
+ PACKAGE_NAME=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['name'])")
356
355
  VERSION="${{ needs.tag.outputs.tag }}"
357
356
  VERSION=${VERSION#v}
358
357
 
@@ -371,7 +370,7 @@ jobs:
371
370
  echo ""
372
371
  echo "[$PACKAGE_NAME]($LINK)"
373
372
  echo "EOF"
374
- } >> $GITHUB_OUTPUT
373
+ } >> "$GITHUB_OUTPUT"
375
374
 
376
375
  - name: Publish Release
377
376
  uses: softprops/action-gh-release@v2.5.0
@@ -27,10 +27,18 @@ jobs:
27
27
  name: Security scanning
28
28
  runs-on: ubuntu-latest
29
29
  container:
30
- image: ghcr.io/astral-sh/uv:0.9.26-python3.12-trixie
30
+ image: ghcr.io/astral-sh/uv:0.9.28-bookworm
31
31
 
32
32
  steps:
33
- - uses: actions/checkout@v6
33
+ - uses: actions/checkout@v6.0.2
34
34
 
35
35
  - name: Run security scans
36
+ env:
37
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
36
38
  run: make security
39
+
40
+
41
+ - name: Run typecheck
42
+ env:
43
+ UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
44
+ run: make typecheck
@@ -26,7 +26,7 @@ jobs:
26
26
 
27
27
  steps:
28
28
  - name: Checkout repository
29
- uses: actions/checkout@v6
29
+ uses: actions/checkout@v6.0.2
30
30
  with:
31
31
  token: ${{ secrets.PAT_TOKEN || github.token }}
32
32
  fetch-depth: 0
@@ -50,7 +50,13 @@ jobs:
50
50
  fi
51
51
 
52
52
  - name: Install uv
53
- uses: astral-sh/setup-uv@v7
53
+ uses: astral-sh/setup-uv@v7.2.1
54
+
55
+ - name: Get Rhiza version
56
+ id: rhiza-version
57
+ run: |
58
+ VERSION=$(cat .rhiza/.rhiza-version 2>/dev/null || echo "0.9.0")
59
+ echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
54
60
 
55
61
  - name: Sync template
56
62
  id: sync
@@ -58,7 +64,9 @@ jobs:
58
64
  run: |
59
65
  set -euo pipefail
60
66
 
61
- uvx rhiza materialize --force .
67
+ RHIZA_VERSION="${{ steps.rhiza-version.outputs.version }}"
68
+
69
+ uvx "rhiza>=${RHIZA_VERSION}" materialize --force .
62
70
 
63
71
  git add -A
64
72
 
@@ -70,10 +78,11 @@ jobs:
70
78
  echo "changes_detected=true" >> "$GITHUB_OUTPUT"
71
79
 
72
80
  # Generate PR description based on staged changes
73
- uvx rhiza summarise --output pr-description.md
81
+ uvx "rhiza>=${RHIZA_VERSION}" summarise --output "${RUNNER_TEMP}/pr-description.md"
74
82
 
75
83
  git config user.name "github-actions[bot]"
76
84
  git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
85
+ git config --global url."https://x-access-token:${{ secrets.PAT_TOKEN }}@github.com/".insteadOf "https://github.com/"
77
86
 
78
87
  git commit -m "chore: Update via rhiza"
79
88
 
@@ -81,11 +90,11 @@ jobs:
81
90
  if: >
82
91
  (github.event_name == 'schedule' || inputs.create-pr == true)
83
92
  && steps.sync.outputs.changes_detected == 'true'
84
- uses: peter-evans/create-pull-request@v8
93
+ uses: peter-evans/create-pull-request@v8.1.0
85
94
  with:
86
95
  token: ${{ secrets.PAT_TOKEN || github.token }}
87
96
  base: ${{ github.event.repository.default_branch }}
88
97
  branch: ${{ steps.branch.outputs.name }}
89
98
  delete-branch: true
90
99
  title: "chore: Sync with rhiza"
91
- body-path: pr-description.md
100
+ body-path: ${{ runner.temp }}/pr-description.md
@@ -15,11 +15,11 @@ jobs:
15
15
  # don't run this in rhiza itself. Rhiza has no template.yml file.
16
16
  if: ${{ github.repository != 'jebel-quant/rhiza' }}
17
17
  container:
18
- image: ghcr.io/astral-sh/uv:0.9.26-python3.12-trixie
18
+ image: ghcr.io/astral-sh/uv:0.9.28-bookworm
19
19
 
20
20
  steps:
21
21
  - name: Checkout repository
22
- uses: actions/checkout@v6
22
+ uses: actions/checkout@v6.0.2
23
23
 
24
24
  - name: Validate Rhiza config
25
25
  shell: bash
@@ -13,6 +13,7 @@ _book
13
13
  _pdoc
14
14
  _marimushka
15
15
  _benchmarks
16
+ _jupyter
16
17
 
17
18
  # temp file used by Junie
18
19
  .output.txt